Skip to content

Fix binsearch #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 59 additions & 6 deletions include/cppcore/Common/Sort.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,54 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

namespace cppcore {

/// @brief The comparison function type
typedef int32_t (*ComparisonFn)(const void* _lhs, const void* _rhs);

/// @brief Compare two values in ascending order
/// @tparam T The type of the value
/// @param lhs The left hand side value
/// @param rhs The right hand side value
/// @return -1 if lhs < rhs, 0 if lhs == rhs, 1 if lhs > rhs
template<class T>
inline int32_t compAscending(const void *lhs, const void *rhs) {
const T _lhs = *static_cast<const T *>(lhs);
const T _rhs = *static_cast<const T *>(rhs);
return (_lhs > _rhs) - (_lhs < _rhs);
}

/// @brief Compare two values in descending order
/// @tparam T The type of the value
/// @param lhs The left hand side value
/// @param rhs The right hand side value
/// @return -1 if lhs > rhs, 0 if lhs == rhs, 1 if lhs < rhs
template <typename Ty>
inline int32_t compDescending(const void *_lhs, const void *_rhs) {
return compAscending<Ty>(_rhs, _lhs);
}

/// @brief Swaps two POD values.
/// @tparam T The type of the value.
/// @param v1 The first value
/// @param v2 The second value
template<class T>
inline void swap(T& v1, T& v2) {
T tmp = v1;
v1 = v2;
v2 = tmp;
}

/// @brief Swaps two uint8 values.
/// @param v1 The first value
/// @param v2 The second value
inline void swap(uint8_t &lhs, uint8_t &rhs) {
uint8_t tmp = lhs;
lhs = rhs;
rhs = tmp;
}

/// @brief Swaps two POD values bitwise.
/// @param lhs The first value
/// @param rhs The second value
inline void swap(void *v1, void *v2, size_t stride) {
uint8_t *lhs = (uint8_t*) v1;
uint8_t *rhs = (uint8_t*) v2;
Expand All @@ -62,6 +83,12 @@ namespace cppcore {
}
}

/// @brief Implements the quicksort algorithm.
/// @param pivot The pivot value to start
/// @param _data The data to sort
/// @param num The number of elements to sort
/// @param stride The stride of the data, i.e. the size of each element
/// @param func The comparison function
inline void quicksortImpl(void *pivot, void *_data, size_t num, size_t stride, ComparisonFn func) {
if (num < 2) {
return;
Expand Down Expand Up @@ -94,11 +121,22 @@ namespace cppcore {
quicksortImpl(pivot, &data[g*stride], num - g, stride, func);
}

/// @brief Implements the quicksort algorithm.
/// @param _data The data to sort
/// @param num The number of elements to sort
/// @param stride The stride of the data, i.e. the size of each element
/// @param func The comparison function
inline void quicksort(void *_data, size_t num, size_t stride, ComparisonFn func) {
uint8_t *pivot = (uint8_t*) CPPCORE_STACK_ALLOC(stride);
quicksortImpl(pivot, _data, num, stride, func);
}

/// @brief Checks if the data is sorted.
/// @param data The data to check
/// @param num The number of elements to check
/// @param stride The stride of the data, i.e. the size of each element
/// @param func The comparison function
/// @return true if the data is sorted, false otherwise
bool isSorted(const void *data, size_t num, size_t stride, ComparisonFn func) {
if (num < 2) {
return true;
Expand All @@ -114,12 +152,19 @@ namespace cppcore {
return true;
}

inline int32_t binSearchImpl(void *key, void *data, size_t num, size_t stride, ComparisonFn func) {
/// @brief Implements a binary search algorithm.
/// @param key The key to search for
/// @param data The data to search in
/// @param num The number of elements to search
/// @param stride The stride of the data, i.e. the size of each element
/// @param func The comparison function
/// @return The index of the key if found, otherwise ~index
inline int32_t binSearchImpl(const void *key, const void *data, size_t num, size_t stride, ComparisonFn func) {
size_t offset = 0;
uint8_t *_data = (uint8_t *)data;
const uint8_t *_data = (uint8_t *)data;
for (size_t i = num; offset < i;) {
size_t idx = (offset + i) / 2;
int32_t result = func(key, &_data[i * stride]);
int32_t result = func(key, &_data[idx * stride]);
if (result < 0) {
i = idx;
} else if (result > 0) {
Expand All @@ -130,8 +175,16 @@ namespace cppcore {
}
return ~offset;
}

int32_t binSearch(int32_t key, int32_t* array, size_t num, ComparisonFn func) {
return binSearchImpl(&key, &array[0], num, sizeof(int32_t), func);

/// @brief Implements a binary search algorithm.
/// @tparam T The type of the value
/// @param key The key to search for
/// @param array The data to search in
/// @param num The number of elements to search
/// @param func The comparison function
/// @return The index of the key if found, otherwise ~index
template<class T>
inline int32_t binSearch(const T &key, const void *array, size_t num, ComparisonFn func) {
return binSearchImpl(&key, array, num, sizeof(T), func);
}
} // namespace cppcore
3 changes: 2 additions & 1 deletion include/cppcore/Memory/TPoolAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ class TPoolAllocator {
/// @brief The class destructor.
~TPoolAllocator();

/// @brief
/// @brief WIll alloc one item from the pool.
/// @return The pointer to the allocated item.
T *alloc();

/// @brief Will release all allocated items.
Expand Down