def _locate_key(self, key, start): """ Locate position of the key, it will iterate using `next` field in record until required key will be find. :param key: the key to locate :param start: position to start from """ location = start while True: self.buckets.seek(location) data = self.buckets.read(self.entry_line_size) # todo, maybe partial read there... try: l_key, rev, start, size, status, _next = self.entry_struct.unpack( data) except struct.error: raise ElemNotFound("Location '%s' not found" % key) if l_key == key: break else: if not _next: # not found raise ElemNotFound("Location '%s' not found" % key) else: location = _next # go to next record return self.buckets.tell( ) - self.entry_line_size, l_key, rev, start, size, status, _next
def update(self, key, rev, u_start=0, u_size=0, u_status='o'): start_position = self._calculate_position(key) self.buckets.seek(start_position) curr_data = self.buckets.read(self.bucket_line_size) # test if it's unique or not really unique hash if curr_data: location = self.bucket_struct.unpack(curr_data)[0] else: raise ElemNotFound("Location '%s' not found" % key) found_at, _key, _rev, start, size, status, _next = self._locate_key( key, location) if u_start == 0: u_start = start if u_size == 0: u_size = size self.buckets.seek(found_at) self.buckets.write(self.entry_struct.pack(key, rev, u_start, u_size, u_status, _next)) self.flush() self._find_key.delete(key) return True