summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/tanya/container/entry.d32
-rw-r--r--source/tanya/container/hashtable.d24
-rw-r--r--source/tanya/container/set.d24
3 files changed, 61 insertions, 19 deletions
diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d
index ed508bd..ff09669 100644
--- a/source/tanya/container/entry.d
+++ b/source/tanya/container/entry.d
@@ -164,13 +164,22 @@ package struct HashArray(alias hasher, K, V = void)
.swap(this.length, data.length);
}
+ void opAssign(ref typeof(this) that)
+ {
+ this.array = that.array;
+ this.lengthIndex = that.lengthIndex;
+ this.length = that.length;
+ }
+
/*
* Returns bucket position for `hash`. `0` may mean the 0th position or an
* empty `buckets` array.
*/
size_t locateBucket(ref const Key key) const
{
- return this.array.length == 0 ? 0 : hasher(key) % this.array.length;
+ return this.array.length == 0
+ ? 0
+ : hasher(key) % primes[this.lengthIndex];
}
/*
@@ -179,11 +188,9 @@ package struct HashArray(alias hasher, K, V = void)
*/
ref Bucket insert(ref Key key)
{
- while (true)
+ while ((this.lengthIndex + 1) != primes.length)
{
- auto bucketPosition = locateBucket(key);
-
- foreach (ref e; this.array[bucketPosition .. $])
+ foreach (ref e; this.array[locateBucket(key) .. $])
{
if (e == key)
{
@@ -196,16 +203,13 @@ package struct HashArray(alias hasher, K, V = void)
}
}
- if (primes.length == (this.lengthIndex + 1))
- {
- this.array.insertBack(Bucket(key));
- return this.array[$ - 1];
- }
if (this.rehashToSize(this.lengthIndex + 1))
{
++this.lengthIndex;
}
}
+ this.array.insertBack(Bucket(key));
+ return this.array[$ - 1];
}
// Takes an index in the primes array.
@@ -221,7 +225,7 @@ package struct HashArray(alias hasher, K, V = void)
{
if (e1.status == BucketStatus.used)
{
- auto bucketPosition = hasher(e1.key) % storage.length;
+ auto bucketPosition = hasher(e1.key) % primes[n];
foreach (ref e2; storage[bucketPosition .. $])
{
@@ -267,8 +271,7 @@ package struct HashArray(alias hasher, K, V = void)
size_t remove(ref Key key)
{
- auto bucketPosition = locateBucket(key);
- foreach (ref e; this.array[bucketPosition .. $])
+ foreach (ref e; this.array[locateBucket(key) .. $])
{
if (e == key) // Found.
{
@@ -286,8 +289,7 @@ package struct HashArray(alias hasher, K, V = void)
bool opBinaryRight(string op : "in")(ref inout(Key) key) inout
{
- auto bucketPosition = locateBucket(key);
- foreach (ref e; this.array[bucketPosition .. $])
+ foreach (ref e; this.array[locateBucket(key) .. $])
{
if (e == key) // Found.
{
diff --git a/source/tanya/container/hashtable.d b/source/tanya/container/hashtable.d
index b7224fa..b1a347d 100644
--- a/source/tanya/container/hashtable.d
+++ b/source/tanya/container/hashtable.d
@@ -194,7 +194,7 @@ if (is(typeof(hasher(Key.init)) == size_t))
do
{
this(allocator);
- rehash(n);
+ this.data.rehash(n);
}
///
@@ -265,7 +265,6 @@ if (is(typeof(hasher(Key.init)) == size_t))
if (is(Unqual!S == HashTable))
{
this.data = that.data;
- this.data.lengthIndex = that.data.lengthIndex;
return this;
}
@@ -604,6 +603,16 @@ if (is(typeof(hasher(Key.init)) == size_t))
assert(hashTable.capacity == 7);
}
+// Assigns by reference
+@nogc nothrow pure @safe unittest
+{
+ auto hashTable1 = HashTable!(string, int)(7);
+ HashTable!(string, int) hashTable2;
+ hashTable1 = hashTable2;
+ assert(hashTable1.length == hashTable2.length);
+ assert(hashTable1.capacity == hashTable2.capacity);
+}
+
// Assigns by value
@nogc nothrow pure @safe unittest
{
@@ -611,3 +620,14 @@ if (is(typeof(hasher(Key.init)) == size_t))
hashTable = HashTable!(string, int)(7);
assert(hashTable.capacity == 7);
}
+
+// Postblit copies
+@nogc nothrow pure @safe unittest
+{
+ auto hashTable = HashTable!(string, int)(7);
+ void testFunc(HashTable!(string, int) hashTable)
+ {
+ assert(hashTable.capacity == 7);
+ }
+ testFunc(hashTable);
+}
diff --git a/source/tanya/container/set.d b/source/tanya/container/set.d
index 2ac3e2e..b8fd0e6 100644
--- a/source/tanya/container/set.d
+++ b/source/tanya/container/set.d
@@ -191,7 +191,7 @@ if (is(typeof(hasher(T.init)) == size_t))
do
{
this(allocator);
- rehash(n);
+ this.data.rehash(n);
}
///
@@ -262,7 +262,6 @@ if (is(typeof(hasher(T.init)) == size_t))
if (is(Unqual!S == Set))
{
this.data = that.data;
- this.data.lengthIndex = that.data.lengthIndex;
return this;
}
@@ -619,6 +618,16 @@ if (is(typeof(hasher(T.init)) == size_t))
assert(set.capacity == 7);
}
+// Assigns by reference
+@nogc nothrow pure @safe unittest
+{
+ auto set1 = Set!int(7);
+ Set!int set2;
+ set1 = set2;
+ assert(set1.length == set2.length);
+ assert(set1.capacity == set2.capacity);
+}
+
// Assigns by value
@nogc nothrow pure @safe unittest
{
@@ -626,3 +635,14 @@ if (is(typeof(hasher(T.init)) == size_t))
set = Set!int(7);
assert(set.capacity == 7);
}
+
+// Postblit copies
+@nogc nothrow pure @safe unittest
+{
+ auto set = Set!int(7);
+ void testFunc(Set!int set)
+ {
+ assert(set.capacity == 7);
+ }
+ testFunc(set);
+}