summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2022-04-01 10:37:45 +0200
committerIvan Solovev <ivan.solovev@qt.io>2022-04-06 16:46:59 +0200
commit7c9afa8d00cc2bbc1b102eef6e76c23e07c7833f (patch)
treeb881550074308a9df8d9bb24ae5144a6eb2fbd70 /src/corelib/tools
parentd11941db41f00525f907417bbcd6ac5ee30d8485 (diff)
Q[Multi]Hash: fix squeeze()
When calling QHash::reserve(), or when creating the internal QHashPrivate::Data structure, the value 0 for the size parameter is reserved for performing the squeeze operation. However commit 8a984ab772dd194e39094e728b869e65912912a7 broke it, by using the 0 value in QHashPrivate::Data constructors as a mark that no resizing needs to be done. This patch reverts the problematic commit (also applying some later fixes to the code), and adds the missing tests for Q[Multi]Hash::squeeze(). Pick-to: 6.3 6.2 Change-Id: Id644df7b2beb008e6a37b2c89b709adfbd893e25 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qhash.h44
1 files changed, 29 insertions, 15 deletions
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 6a545988d4..07e2f2d355 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -565,7 +565,6 @@ struct Data
}
};
-
Data(size_t reserve = 0)
{
numBuckets = GrowthPolicy::bucketsForCapacity(reserve);
@@ -573,25 +572,16 @@ struct Data
spans = new Span[nSpans];
seed = QHashSeed::globalSeed();
}
- Data(const Data &other, size_t reserved = 0)
- : size(other.size),
- numBuckets(other.numBuckets),
- seed(other.seed)
- {
- if (reserved)
- numBuckets = GrowthPolicy::bucketsForCapacity(qMax(size, reserved));
- bool resized = numBuckets != other.numBuckets;
- size_t nSpans = numBuckets >> SpanConstants::SpanShift;
- spans = new Span[nSpans];
- size_t otherNSpans = other.numBuckets >> SpanConstants::SpanShift;
- for (size_t s = 0; s < otherNSpans; ++s) {
+ void reallocationHelper(const Data &other, size_t nSpans, bool resized)
+ {
+ for (size_t s = 0; s < nSpans; ++s) {
const Span &span = other.spans[s];
for (size_t index = 0; index < SpanConstants::NEntries; ++index) {
if (!span.hasNode(index))
continue;
const Node &n = span.at(index);
- auto it = resized ? findBucket(n.key) : Bucket{ spans + s, index };
+ auto it = resized ? findBucket(n.key) : Bucket { spans + s, index };
Q_ASSERT(it.isUnused());
Node *newNode = it.insert();
new (newNode) Node(n);
@@ -599,7 +589,31 @@ struct Data
}
}
- static Data *detached(Data *d, size_t size = 0)
+ Data(const Data &other) : size(other.size), numBuckets(other.numBuckets), seed(other.seed)
+ {
+ size_t nSpans = numBuckets >> SpanConstants::SpanShift;
+ spans = new Span[nSpans];
+ reallocationHelper(other, nSpans, false);
+ }
+ Data(const Data &other, size_t reserved) : size(other.size), seed(other.seed)
+ {
+ numBuckets = GrowthPolicy::bucketsForCapacity(qMax(size, reserved));
+ size_t nSpans = numBuckets >> SpanConstants::SpanShift;
+ spans = new Span[nSpans];
+ size_t otherNSpans = other.numBuckets >> SpanConstants::SpanShift;
+ reallocationHelper(other, otherNSpans, true);
+ }
+
+ static Data *detached(Data *d)
+ {
+ if (!d)
+ return new Data;
+ Data *dd = new Data(*d);
+ if (!d->ref.deref())
+ delete d;
+ return dd;
+ }
+ static Data *detached(Data *d, size_t size)
{
if (!d)
return new Data(size);