-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhashset.d
More file actions
93 lines (83 loc) · 1.87 KB
/
hashset.d
File metadata and controls
93 lines (83 loc) · 1.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
module stdex.hashset;
struct Node(T)
{
public:
this(T value, Node!T* next, size_t hash)
{
m_value = value;
m_next = next;
m_hash = hash;
}
T m_value;
Node* m_next;
size_t m_hash;
}
struct HashSet(T,
alias hash = defaultHash!T,
alias pred = defaultPred!T)
{
public:
this(size_t numBuckets)
{
m_buckets.length = numBuckets;
m_buckets[] = null;
m_pool = new Node!T[poolSize];
}
const(Node!T)* opIndex(T key)
{
assert(m_buckets.length != 0, "No buckets");
size_t k = hash(key) & (m_buckets.length-1);
Node!T* node = m_buckets[k];
for ( ; node && (node.m_hash & (m_buckets.length-1)) == k; node = node.m_next)
if (pred(node.m_value, key))
return node;
return null;
}
void insert(T key)
{
assert(m_buckets.length != 0, "No buckets");
size_t maxK = m_buckets.length;
size_t keyHash = hash(key);
size_t k = hash(key) & (maxK-1);
Node!T* node = &m_pool[0];
m_pool = m_pool[1..$];
if (m_pool.length == 0)
m_pool = new Node!T[poolSize];
*node = Node!T(key, m_buckets[k], keyHash);
m_buckets[k] = node;
}
private:
enum poolSize = 1<<10;
Node!T*[] m_buckets;
Node!T[] m_pool;
}
size_t defaultHash(T)(T value)
{
return typeid(T).getHash(cast(void*)&value);
}
bool defaultPred(T)(T x, T y)
{
return x == y;
}
unittest
{
import std.stdio;
writeln("testing stdex.hashset");
HashSet!int h = HashSet!int(2);
assert(!h[0]);
assert(!h[1]);
assert(!h[2]);
assert(!h[3]);
h.insert(0);
h.insert(1);
h.insert(2);
h.insert(3);
assert(h[0]);
assert(h[1]);
assert(h[2]);
assert(h[3]);
assert(!h[4]);
assert(!h[5]);
assert(!h[6]);
assert(!h[7]);
}