-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathHashTable.py
More file actions
95 lines (70 loc) · 2.33 KB
/
HashTable.py
File metadata and controls
95 lines (70 loc) · 2.33 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
94
95
import os
from Dictionary import Dictionary
from BitMap import BitMap
from Entry import Entry
class HashTable(Dictionary):
def __init__(self, c=5):
self.M = self.__get_prime_number(c)
self.N = 0
self.entries = [None] * self.M
self.lazy_removal = BitMap(self.M)
def __str__(self):
values = []
for entry in self.entries:
if entry is not None:
values.append(str(entry.value))
return ','.join(values)
def size(self):
return self.N
def lazily_removed(self, k):
return self.lazy_removal.test(k)
def mark_as_removed(self, k):
return self.lazy_removal.set(k)
def put(self, key, value):
x = self.__probe_for_free(key)
self.entries[x] = Entry(key, value)
self.N += 1
if 2 * self.N > self.M:
self.__rehash()
def get(self, key):
x = self.__probe_for_hit(key)
entry = self.entries[x]
return None if entry is None else entry.value
def remove(self, key):
x = self.__probe_for_hit(key)
entry = self.entries[x]
if entry is not None:
self.entries[x] = None
self.mark_as_removed(x)
self.N -= 1
def hash_code(self, key):
if type(key) == int:
return key
else:
return ''.join(str(ord(c)) for c in key)
def __probe_for_hit(self, key):
x = key % self.M
i = 0
while (self.entries[x] is not None and self.entries[x].key != key) or \
(self.entries[x] is None and self.lazily_removed(x)):
x = (x + i**2) % self.M
i += 1
return x
def __probe_for_free(self, key):
x = key % self.M
i = 1
while self.entries[x] is not None:
x = (x + i**2) % self.M
i += 1
return x
def __rehash(self):
old_entries = self.entries
self.M = self.__get_prime_number(self.M * 2)
self.entries = [None] * self.M
self.lazy_removal = BitMap(self.M)
self.N = 0
for entry in old_entries:
if entry is not None:
self.put(entry.key, entry.value)
def __get_prime_number(self, m):
return int(open(os.path.dirname(os.path.abspath(__file__)) + '/prime_number.txt').read().split(',')[m])