Skip to content

Instantly share code, notes, and snippets.

@jweinst1
Created June 21, 2024 03:39
Show Gist options
  • Save jweinst1/9df1e5002dc4a01d45416991b82fef82 to your computer and use it in GitHub Desktop.
Save jweinst1/9df1e5002dc4a01d45416991b82fef82 to your computer and use it in GitHub Desktop.
in place rehash of hash table in Python
import sys
import random
import string
def rand_str(n):
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(n))
def rand_str_set(n, amount):
return {rand_str(n) for i in range(amount)}
class DeleteMarker:
def __repr__(self):
return "X"
class EmptyMarker:
def __repr__(self):
return "O"
class HashMarker:
def __init__(self, key, hsize, hashv):
self.key = key
self.hsize = hsize
self.hashv = hashv
def __repr__(self):
return str((self.key, self.hsize, self.hashv))
def isKey(self, other):
return self.key == other
def empty_arr(n):
return [EmptyMarker() for i in range(n)]
class HashTable:
def __init__(self, size):
self.size = size
self.table = empty_arr(self.size)
def __repr__(self):
return str(self.table)
def checkSlot(self, i, keystr):
if isinstance(self.table[i], EmptyMarker) or isinstance(self.table[i], DeleteMarker):
return True
elif self.table[i].isKey(keystr):
return True
else:
return False
def insert(self, keystr, use_size=0, verbose=False):
hashed = abs(hash(keystr))
if use_size == 0:
use_size = self.size
table_hash = hashed % use_size
if verbose:
print("will hash {} into slot {}".format(keystr, table_hash))
if self.checkSlot(table_hash, keystr):
self.table[table_hash] = HashMarker(keystr, use_size, hashed)
return True
for i in range(table_hash, use_size):
if self.checkSlot(i, keystr):
self.table[i] = HashMarker(keystr, use_size, hashed)
return True
for j in range(table_hash):
if self.checkSlot(j, keystr):
self.table[j] = HashMarker(keystr, use_size, hashed)
return True
return False
def rehash_inplace(self, new_size):
self.table += empty_arr(new_size - self.size)
for i in range(self.size):
if isinstance(self.table[i], HashMarker):
self.insert(self.table[i].key, new_size, True)
# this step needs a global lock
old_size = self.size
self.size = new_size
# print("---------------")
# print(self.table)
# print("---------------")
for i in range(self.size):
if isinstance(self.table[i], HashMarker):
if self.table[i].hsize == old_size:
self.table[i] = DeleteMarker()
if __name__ == '__main__':
h = HashTable(50)
h.insert("foo", verbose = True)
h.insert("foo", verbose = True)
h.insert("doo", verbose = True)
h.insert("blue", verbose = True)
h.insert("blee", verbose = True)
h.insert("green", verbose = True)
print(h)
h.rehash_inplace(100)
print("-------------------")
print(h)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment