ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const { // binary search ssize_t err = NAME_NOT_FOUND; ssize_t l = 0; ssize_t h = size()-1; ssize_t mid; const void* a = arrayImpl(); const size_t s = itemSize(); while (l <= h) { mid = l + (h - l)/2; const void* const curr = reinterpret_cast<const char *>(a) + (mid*s); const int c = do_compare(curr, item); if (c == 0) { err = l = mid; break; } else if (c < 0) { l = mid + 1; } else { h = mid - 1; } } if (order) *order = l; return err; }
status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state) { // the sort must be stable. we're using insertion sort which // is well suited for small and already sorted arrays // for big arrays, it could be better to use mergesort const ssize_t count = size(); if (count > 1) { void* array = const_cast<void*>(arrayImpl()); void* temp = 0; ssize_t i = 1; while (i < count) { void* item = reinterpret_cast<char*>(array) + mItemSize*(i); void* curr = reinterpret_cast<char*>(array) + mItemSize*(i-1); if (cmp(curr, item, state) > 0) { if (!temp) { // we're going to have to modify the array... array = editArrayImpl(); if (!array) return NO_MEMORY; temp = malloc(mItemSize); if (!temp) return NO_MEMORY; item = reinterpret_cast<char*>(array) + mItemSize*(i); curr = reinterpret_cast<char*>(array) + mItemSize*(i-1); } else { _do_destroy(temp, 1); } _do_copy(temp, item, 1); ssize_t j = i-1; void* next = reinterpret_cast<char*>(array) + mItemSize*(i); do { _do_destroy(next, 1); _do_copy(next, curr, 1); next = curr; --j; curr = NULL; if (j >= 0) { curr = reinterpret_cast<char*>(array) + mItemSize*(j); } } while (j>=0 && (cmp(curr, temp, state) > 0)); _do_destroy(next, 1); _do_copy(next, temp, 1); } i++; } if (temp) { _do_destroy(temp, 1); free(temp); } } return NO_ERROR; }
const void* VectorImpl::itemLocation(size_t index) const { ALOG_ASSERT(index<capacity(), "[%p] itemLocation: index=%d, capacity=%d, count=%d", this, (int)index, (int)capacity(), (int)mCount); const void* buffer = arrayImpl(); if (buffer) return reinterpret_cast<const char*>(buffer) + index*mItemSize; return 0; }
ssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector) { // we've merging a sorted vector... nice! ssize_t err = NO_ERROR; if (!vector.isEmpty()) { // first take care of the case where the vectors are sorted together if (do_compare(vector.itemLocation(vector.size()-1), arrayImpl()) <= 0) { err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&>(vector), 0); } else if (do_compare(vector.arrayImpl(), itemLocation(size()-1)) >= 0) { err = VectorImpl::appendVector(static_cast<const VectorImpl&>(vector)); } else { // this could be made a little better err = merge(static_cast<const VectorImpl&>(vector)); } } return err; }