Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """ HashMap implementation. """
- from typing import Any
- import abc
- class Error(Exception):
- """ Base class for custom exceptions raised by this module """
- class NoSuchKeyError(Error):
- """ No such key exception. """
- class EmptyCapacityError(Error):
- """ Empty capacity for the hash map exception. """
- class HashMapBase(abc.ABC):
- """ Base class for hash map implementations. It defines API. """
- @abc.abstractmethod
- def __init__(self, **opts):
- if 'capacity' in opts:
- self.capacity = opts['capacity']
- @abc.abstractmethod
- def get(self, key: Any) -> Any:
- """ Gets value for the specified key. """
- @abc.abstractmethod
- def set(self, key: Any, value: Any) -> None:
- """ Sets value for the specified key. """
- @abc.abstractmethod
- def exists(self, key: Any) -> bool:
- """ Checks if the given key exists in the hash map. """
- @abc.abstractmethod
- def remove(self, key: Any) -> None:
- """ Removes the specified key from hash map. """
- def hash(self, key: Any):
- """ Calculates the hash number for the given key based on the current capacity. """
- if self.capacity == 0:
- return EmptyCapacityError()
- return hash(key) % self.capacity
- class HashMap(HashMapBase):
- """
- One of possible hash map implementations based on closed addressing and list for every cell.
- """
- default_capacity = 1024
- def __init__(self, **opts):
- if 'capacity' not in opts:
- opts['capacity'] = self.default_capacity
- super().__init__(**opts)
- self.data = [[] for _ in range(self.capacity)]
- def resize(self):
- """
- Resizes object whenever it takes too much or too few space compared to the capacity.
- This allows to keep number of collision and capacity appropriate to the current usage.
- TODO: not implemented yet.
- Most probably, we also need min and max fill factors in constructor for this.
- """
- def get(self, key: Any) -> Any:
- hash_value = self.hash(key)
- for cur_key, value in self.data[hash_value]:
- if cur_key == key:
- return value
- raise NoSuchKeyError()
- def exists(self, key: Any) -> bool:
- hash_value = hash(key)
- for cur_key, _ in self.data[hash_value]:
- if cur_key == key:
- return True
- return False
- def set(self, key: Any, value: Any) -> None:
- # call it before set in order to prevent zero capacity problems
- self.resize()
- hash_value = self.hash(key)
- for i, (cur_key, _) in enumerate(self.data[hash_value]):
- if cur_key == key:
- self.data[hash_value][i] = (key, value)
- return
- self.data[hash_value].append((key, value))
- def remove(self, key: Any) -> None:
- hash_value = self.hash(key)
- for i, (cur_key, _) in enumerate(self.data[hash_value]):
- if cur_key == key:
- del self.data[hash_value][i]
- self.resize()
- return
- raise NoSuchKeyError()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement