summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Wissner <belka@caraus.de>2018-04-30 12:42:25 +0200
committerEugene Wissner <belka@caraus.de>2018-04-30 12:51:35 +0200
commitc4424e7e01e5eba8b593fd9a14da41e12d12452e (patch)
tree1c64617583f06f76b1fbd67ebf51dec3625dccc8
parent18d54b4b186c5a05b054a015c966950dfba68c19 (diff)
downloadtanya-c4424e7e01e5eba8b593fd9a14da41e12d12452e.tar.gz
Track hash Set length
Can be used later to rehash the hash table if it is full up to some percentage.
-rw-r--r--source/tanya/container/entry.d50
-rw-r--r--source/tanya/container/set.d57
2 files changed, 70 insertions, 37 deletions
diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d
index 8822924..a3cc9ee 100644
--- a/source/tanya/container/entry.d
+++ b/source/tanya/container/entry.d
@@ -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;
+ }
}
diff --git a/source/tanya/container/set.d b/source/tanya/container/set.d
index 7d7449c..6f1b809 100644
--- a/source/tanya/container/set.d
+++ b/source/tanya/container/set.d
@@ -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);
}
///