void HashCollection::shrink(uint32_t oldCap /* = 0 */) { assert(isCapacityTooHigh() && (oldCap == 0 || oldCap < cap())); assert(m_size <= posLimit() && posLimit() <= cap()); dropImmCopy(); uint32_t newCap; if (oldCap != 0) { // If an old capacity was specified, use that newCap = oldCap; // .. unless the old capacity is too small, in which case we use the // smallest capacity that is large enough to hold the current number // of elements. for (; newCap < m_size; newCap <<= 1) {} assert(newCap == computeMaxElms(folly::nextPowTwo<uint64_t>(newCap) - 1)); } else { if (m_size == 0 && nextKI() == 0) { decRefArr(m_arr); m_arr = staticEmptyDictArrayAsMixed(); return; } // If no old capacity was provided, we compute the largest capacity // where m_size/cap() is less than or equal to 0.5 for good hysteresis size_t doubleSz = size_t(m_size) * 2; uint32_t capThreshold = (doubleSz < size_t(MaxSize)) ? doubleSz : MaxSize; for (newCap = SmallSize * 2; newCap < capThreshold; newCap <<= 1) {} } assert(SmallSize <= newCap && newCap <= MaxSize); assert(m_size <= newCap); auto* oldAd = arrayData(); if (!oldAd->cowCheck()) { // If the buffer's refcount is 1, we can teleport the elements // to a new buffer auto oldBuf = data(); auto oldUsed = posLimit(); auto oldNextKI = nextKI(); auto arr = MixedArray::asMixed(MixedArray::MakeReserveDict(newCap)); auto data = mixedData(arr); m_arr = arr; auto table = (int32_t*)(data + size_t(newCap)); auto table_mask = tableMask(); arr->m_size = m_size; setPosLimit(m_size); setNextKI(oldNextKI); for (uint32_t frPos = 0, toPos = 0; toPos < m_size; ++toPos, ++frPos) { frPos = skipTombstonesNoBoundsCheck(frPos, oldUsed, oldBuf); copyElm(oldBuf[frPos], data[toPos]); *findForNewInsert(table, table_mask, data[toPos].probe()) = toPos; } oldAd->setZombie(); decRefArr(oldAd); } else { // For cases where the buffer's refcount is greater than 1, call // resizeHelper() resizeHelper(newCap); } assert(canMutateBuffer()); assert(m_immCopy.isNull()); assert(!isCapacityTooHigh() || newCap == oldCap); }
void HashCollection::compact() { assert(isDensityTooLow()); dropImmCopy(); if (!arrayData()->cowCheck()) { // MixedArray::compact can only handle cases where the buffer's // refcount is 1. arrayData()->compact(false); } else { // For cases where the buffer's refcount is greater than 1, call // resizeHelper(). resizeHelper(cap()); } assert(canMutateBuffer()); assert(m_immCopy.isNull()); assert(!isDensityTooLow()); }
void HashCollection::grow(uint32_t newScale) { auto newCap = MixedArray::Capacity(newScale); assert(m_size <= posLimit() && posLimit() <= cap() && cap() <= newCap); assert(SmallSize <= newCap && newCap <= MaxSize); assert(m_size <= newCap); auto oldAd = arrayData(); dropImmCopy(); if (m_size > 0 && !oldAd->cowCheck()) { // MixedArray::Grow can only handle non-empty cases where the // buffer's refcount is 1. m_arr = MixedArray::Grow(oldAd, newScale); decRefArr(oldAd); } else { // For cases where m_size is zero or the buffer's refcount is // greater than 1, call resizeHelper(). resizeHelper(newCap); } assert(canMutateBuffer()); assert(m_immCopy.isNull()); }
bool PlaceableWindowProxy::handleMouseMove(QMouseEvent *event) { if (!visible_) { return false; } if (state_ == INACTIVE) { if (!rect_.contains(event->localPos())) { if (has_cursor_) { QApplication::restoreOverrideCursor(); has_cursor_ = false; } return false; } // The mouse cursor is over the rect, so we're going to change the // cursor to indicate the state the user would enter by clicking. Qt::CursorShape shape; switch(getNextState(event->localPos())) { case MOVE_TOP_LEFT: case MOVE_BOTTOM_RIGHT: shape = Qt::SizeFDiagCursor; break; case MOVE_TOP_RIGHT: case MOVE_BOTTOM_LEFT: shape = Qt::SizeBDiagCursor; break; default: shape = Qt::SizeAllCursor; } if (has_cursor_) { QApplication::changeOverrideCursor(QCursor(shape)); } else { QApplication::setOverrideCursor(QCursor(shape)); has_cursor_ = true; } return true; } QPointF dp = event->localPos() - start_point_; // todo: enforce minimum size & constrain aspect ratio for resizes. if (state_ == MOVE_ALL) { rect_ = start_rect_.translated(dp); } else if (state_ == MOVE_TOP_LEFT) { rect_= resizeHelper(start_rect_, start_rect_.bottomRight(), start_rect_.topLeft(), event->localPos()); rect_.moveBottomRight(start_rect_.bottomRight()); } else if (state_ == MOVE_BOTTOM_LEFT) { rect_= resizeHelper(start_rect_, start_rect_.topRight(), start_rect_.bottomLeft(), event->localPos()); rect_.moveTopRight(start_rect_.topRight()); } else if (state_ == MOVE_BOTTOM_RIGHT) { rect_= resizeHelper(start_rect_, start_rect_.topLeft(), start_rect_.bottomRight(), event->localPos()); rect_.moveTopLeft(start_rect_.topLeft()); } else if (state_ == MOVE_TOP_RIGHT) { rect_= resizeHelper(start_rect_, start_rect_.bottomLeft(), start_rect_.topRight(), event->localPos()); rect_.moveBottomLeft(start_rect_.bottomLeft()); } else { qWarning("Unhandled state in PlaceableWindowProxy: %d", state_); } return true; }