nall: fix various hashset issues
- Fix copy assignment operator - Prevent reserve() from reallocating/rehashing unless capacity is increasing - Prevent insert() from inserting duplicate entries - Disable remove() as needs some work and is currently unused
このコミットが含まれているのは:
コミット
ed43ab72b2
|
@ -24,8 +24,8 @@ struct hashset {
|
||||||
if(this == &source) return *this;
|
if(this == &source) return *this;
|
||||||
reset();
|
reset();
|
||||||
if(source.pool) {
|
if(source.pool) {
|
||||||
for(u32 n : range(source.count)) {
|
for(u32 n : range(source.length)) {
|
||||||
insert(*source.pool[n]);
|
if(source.pool[n]) insert(*source.pool[n]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -63,6 +63,8 @@ struct hashset {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto reserve(u32 size) -> void {
|
auto reserve(u32 size) -> void {
|
||||||
|
if(length >= size) return;
|
||||||
|
|
||||||
//ensure all items will fit into pool (with <= 50% load) and amortize growth
|
//ensure all items will fit into pool (with <= 50% load) and amortize growth
|
||||||
size = bit::round(max(size, count << 1));
|
size = bit::round(max(size, count << 1));
|
||||||
T** copy = new T*[size]();
|
T** copy = new T*[size]();
|
||||||
|
@ -100,15 +102,20 @@ struct hashset {
|
||||||
|
|
||||||
//double pool size when load is >= 50%
|
//double pool size when load is >= 50%
|
||||||
if(count >= (length >> 1)) reserve(length << 1);
|
if(count >= (length >> 1)) reserve(length << 1);
|
||||||
count++;
|
|
||||||
|
|
||||||
u32 hash = value.hash() & (length - 1);
|
u32 hash = value.hash() & (length - 1);
|
||||||
while(pool[hash]) if(++hash >= length) hash = 0;
|
while(pool[hash]) {
|
||||||
|
if(value == *pool[hash]) return nothing;
|
||||||
|
if(++hash >= length) hash = 0;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
pool[hash] = new T(value);
|
pool[hash] = new T(value);
|
||||||
|
|
||||||
return *pool[hash];
|
return *pool[hash];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
//does not work! todo: implement tombstones or rehashing to fill gaps.
|
||||||
auto remove(const T& value) -> bool {
|
auto remove(const T& value) -> bool {
|
||||||
if(!pool) return false;
|
if(!pool) return false;
|
||||||
|
|
||||||
|
@ -125,6 +132,7 @@ struct hashset {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
T** pool = nullptr;
|
T** pool = nullptr;
|
||||||
|
|
読み込み中…
新しいイシューから参照