void VectorImpl::_shrink(size_t where, size_t amount) { if (!mStorage) return; // ALOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d", // this, (int)where, (int)amount, (int)mCount, (int)capacity()); ALOG_ASSERT(where + amount <= mCount, "[%p] _shrink: where=%d, amount=%d, count=%d", this, (int)where, (int)amount, (int)mCount); // caller already checked const size_t new_size = mCount - amount; if (new_size*3 < capacity()) { const size_t new_capacity = max(kMinVectorCapacity, new_size*2); // ALOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity); if ((where == new_size) && (mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); if (sb) { mStorage = sb->data(); } else { return; } } else { SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); if (sb) { void* array = sb->data(); if (where != 0) { _do_copy(array, mStorage, where); } if (where != new_size) { const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize; void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_copy(dest, from, new_size - where); } release_storage(); mStorage = const_cast<void*>(array); } else{ return; } } } else { void* array = editArrayImpl(); void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_destroy(to, amount); if (where != new_size) { const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_move_backward(to, from, new_size - where); } } mCount = new_size; }
void VectorImpl::_shrink(size_t where, size_t amount) { if (!mStorage) return; // LOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d", // this, (int)where, (int)amount, (int)mCount, (int)capacity()); if (where >= mCount) where = mCount - amount; const size_t new_size = mCount - amount; if (new_size*3 < capacity()) { const size_t new_capacity = max(kMinVectorCapacity, new_size*2); // LOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity); if ((where == mCount-amount) && (mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); mStorage = sb->data(); } else { SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); if (sb) { void* array = sb->data(); if (where>0) { _do_copy(array, mStorage, where); } if (mCount > where+amount) { const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize; void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_copy(dest, from, mCount-(where+amount)); } release_storage(); mStorage = const_cast<void*>(array); } } } else { void* array = editArrayImpl(); void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_destroy(to, amount); ssize_t s = mCount-(where+amount); if (s>0) { const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_move_backward(to, from, s); } } // adjust the number of items... mCount -= amount; }
void VectorImpl::_shrink(size_t where, size_t amount) { if (!mStorage) return; // ALOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d", // this, (int)where, (int)amount, (int)mCount, (int)capacity()); ALOG_ASSERT(where + amount <= mCount, "[%p] _shrink: where=%d, amount=%d, count=%d", this, (int)where, (int)amount, (int)mCount); // caller already checked size_t new_size; LOG_ALWAYS_FATAL_IF(!safe_sub(&new_size, mCount, amount)); if (new_size < (capacity() / 2)) { // NOTE: (new_size * 2) is safe because capacity didn't overflow and // new_size < (capacity / 2)). const size_t new_capacity = max(kMinVectorCapacity, new_size * 2); // NOTE: (new_capacity * mItemSize), (where * mItemSize) and // ((where + amount) * mItemSize) beyond this point are safe because // we are always reducing the capacity of the underlying SharedBuffer. // In other words, (old_capacity * mItemSize) did not overflow, and // where < (where + amount) < new_capacity < old_capacity. if ((where == new_size) && (mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); if (sb) { mStorage = sb->data(); } else { return; } } else { SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); if (sb) { void* array = sb->data(); if (where != 0) { _do_copy(array, mStorage, where); } if (where != new_size) { const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize; void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_copy(dest, from, new_size - where); } release_storage(); mStorage = const_cast<void*>(array); } else{ return; } } } else { void* array = editArrayImpl(); void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize; _do_destroy(to, amount); if (where != new_size) { const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; _do_move_backward(to, from, new_size - where); } } mCount = new_size; }