Untitled

mail@pastecode.io avatar
unknown
plain_text
4 months ago
4.3 kB
6
Indexable
import sys

class SerializableHashMap:

    def __init__(self):
        self.byte_array = None
        self.page_size = 0
        self.num_pages = 0
        self.special_keys = {0: None, -1: None}

    def init(self, page_size, num_pages):
        self.page_size = page_size
        self.num_pages = num_pages
        self.byte_array = bytearray(8 + 9 + page_size * num_pages)

    def put(self, key, value):
        if key in self.special_keys:
            self._put_special_key(key, value)
        else:
            self._put_normal_key(key, value)

    def get(self, key):
        if key in self.special_keys:
            return self._get_special_key(key)
        return self._get_normal_key(key)

    def delete(self, key):
        if key in self.special_keys:
            self._delete_special_key(key)
        else:
            self._delete_normal_key(key)

    def dump(self):
        result = ''.join(f'{byte:02x}' for byte in self.byte_array)
        page_part = ''
        for i in range(self.num_pages):
            page = self.byte_array[8 + 9 + i * self.page_size:8 + 9 + (i + 1) * self.page_size]
            entries = [f'{int.from_bytes(page[j:j+4], "big"):08x}:{int.from_bytes(page[j+4:j+8], "big"):08x}' for j in range(0, len(page), 8)]
            page_part += f'[{" ,".join(entries)}]'
        print(f'{result[:8]} {result[8:16]} {result[16:18]} {result[18:26]} {result[26:28]} {result[28:36]} {page_part}')

    def _put_special_key(self, key, value):
        index = 8 if key == -1 else 13
        self.byte_array[index - 1] = 1
        self.byte_array[index:index + 4] = value.to_bytes(4, 'big')

    def _get_special_key(self, key):
        index = 8 if key == -1 else 13
        if self.byte_array[index - 1] == 1:
            return int.from_bytes(self.byte_array[index:index + 4], 'big')
        return 0

    def _delete_special_key(self, key):
        index = 8 if key == -1 else 13
        self.byte_array[index - 1] = 0
        self.byte_array[index:index + 4] = (0).to_bytes(4, 'big')

    def _put_normal_key(self, key, value):
        page_index = key % self.num_pages
        page_start = 8 + 9 + page_index * self.page_size
        for i in range(0, self.page_size, 8):
            record_start = page_start + i
            stored_key = int.from_bytes(self.byte_array[record_start:record_start + 4], 'big')
            if stored_key in (0, -1):
                self.byte_array[record_start:record_start + 4] = key.to_bytes(4, 'big')
                self.byte_array[record_start + 4:record_start + 8] = value.to_bytes(4, 'big')
                return
        raise Exception("Page is full")

    def _get_normal_key(self, key):
        page_index = key % self.num_pages
        page_start = 8 + 9 + page_index * self.page_size
        for i in range(0, self.page_size, 8):
            record_start = page_start + i
            stored_key = int.from_bytes(self.byte_array[record_start:record_start + 4], 'big')
            if stored_key == key:
                return int.from_bytes(self.byte_array[record_start + 4:record_start + 8], 'big')
            if stored_key == 0:
                break
        return 0

    def _delete_normal_key(self, key):
        page_index = key % self.num_pages
        page_start = 8 + 9 + page_index * self.page_size
        for i in range(0, self.page_size, 8):
            record_start = page_start + i
            stored_key = int.from_bytes(self.byte_array[record_start:record_start + 4], 'big')
            if stored_key == key:
                self.byte_array[record_start:record_start + 4] = (-1).to_bytes(4, 'big')
                self.byte_array[record_start + 4:record_start + 8] = (0).to_bytes(4, 'big')
                return

hash_map = SerializableHashMap()

for line in sys.stdin:
    parts = line.split()
    command = parts[0]
    if command == 'init':
        page_size, num_pages = int(parts[1]), int(parts[2])
        hash_map.init(page_size, num_pages)
    elif command == 'put':
        key, value = int(parts[1]), int(parts[2])
        hash_map.put(key, value)
    elif command == 'get':
        key = int(parts[1])
        print(hash_map.get(key))
    elif command == 'delete':
        key = int(parts[1])
        hash_map.delete(key)
    elif command == 'dump':
        hash_map.dump()
Leave a Comment