Track hash Set length

Can be used later to rehash the hash table if it is full up to some
percentage.
This commit is contained in:
Eugen Wissner 2018-04-30 12:42:25 +02:00
parent 18d54b4b18
commit c4424e7e01
2 changed files with 70 additions and 37 deletions

View File

@ -120,6 +120,7 @@ package struct HashArray(alias hasher, K, V = void)
Array!Bucket array;
size_t lengthIndex;
size_t length;
/*
* Returns bucket position for `hash`. `0` may mean the 0th position or an
@ -144,10 +145,15 @@ package struct HashArray(alias hasher, K, V = void)
foreach (ref e; this.array[bucketPosition .. $])
{
if (e == key || e.status != BucketStatus.used)
if (e == key)
{
return e;
}
else if (e.status != BucketStatus.used)
{
++this.length;
return e;
}
}
if (primes.length == (this.lengthIndex + 1))
@ -207,4 +213,46 @@ package struct HashArray(alias hasher, K, V = void)
{
return this.array.length;
}
void clear()
{
this.array.clear();
this.length = 0;
}
size_t remove(ref K value)
{
auto bucketPosition = locateBucket(value);
foreach (ref e; this.array[bucketPosition .. $])
{
if (e == value) // Found.
{
e.remove();
--this.length;
return 1;
}
else if (e.status == BucketStatus.empty)
{
break;
}
}
return 0;
}
bool find(ref const K value) const
{
auto bucketPosition = locateBucket(value);
foreach (ref e; this.array[bucketPosition .. $])
{
if (e == value) // Found.
{
return true;
}
else if (e.status == BucketStatus.empty)
{
break;
}
}
return false;
}
}

View File

@ -314,15 +314,7 @@ if (is(typeof(hasher(T.init)) == size_t))
*/
@property size_t length() const
{
size_t count;
foreach (ref e; this.data.array[])
{
if (e.status == BucketStatus.used)
{
++count;
}
}
return count;
return this.data.length;
}
///
@ -335,6 +327,24 @@ if (is(typeof(hasher(T.init)) == size_t))
assert(set.length == 1);
}
/**
* Tells whether the container contains any elements.
*
* Returns: Whether the container is empty.
*/
@property bool empty() const
{
return length == 0;
}
/**
* Removes all elements.
*/
void clear()
{
this.data.clear();
}
/// The maximum number of buckets the container can have.
enum size_t maxBucketCount = primes[$ - 1];
@ -386,20 +396,7 @@ if (is(typeof(hasher(T.init)) == size_t))
*/
size_t remove(T value)
{
auto bucketPosition = this.data.locateBucket(value);
foreach (ref e; this.data.array[bucketPosition .. $])
{
if (e == value) // Found.
{
e.remove();
return 1;
}
else if (e.status == BucketStatus.empty)
{
break;
}
}
return 0;
return this.data.remove(value);
}
///
@ -427,19 +424,7 @@ if (is(typeof(hasher(T.init)) == size_t))
*/
bool opBinaryRight(string op : "in")(auto ref const T value) const
{
auto bucketPosition = this.data.locateBucket(value);
foreach (ref e; this.data.array[bucketPosition .. $])
{
if (e == value) // Found.
{
return true;
}
else if (e.status == BucketStatus.empty)
{
break;
}
}
return false;
return this.data.find(value);
}
///