class HashTableEntry:
    def __init__(self, key: str, value: str):
        self.key = key
        self.value = value
        self.deleted = False


class HashTable:
    def __init__(self, capacity: int = 100):
        self.capacity = capacity
        self.size = 0
        self.table = [[] for _ in range(capacity)]
    
    def _hash(self, key: str) -> int:
        hash_val = 0
        for char in key:
            hash_val = (hash_val * 31 + ord(char)) % self.capacity
        return hash_val
    
    def insert(self, key: str, value: str) -> None:
        if self.size / self.capacity > 0.75:
            self._resize()
        
        index = self._hash(key)
        bucket = self.table[index]
        
        for entry in bucket:
            if entry.key == key and not entry.deleted:
                entry.value = value
                return
        
        bucket.append(HashTableEntry(key, value))
        self.size += 1
    
    def _resize(self) -> None:
        old_table = self.table
        self.capacity *= 2
        self.table = [[] for _ in range(self.capacity)]
        self.size = 0
        
        for bucket in old_table:
            for entry in bucket:
                if not entry.deleted:
                    self.insert(entry.key, entry.value)
    
    def search(self, key: str):
        index = self._hash(key)
        bucket = self.table[index]
        
        for entry in bucket:
            if entry.key == key and not entry.deleted:
                return entry.value
        
        return None
    
    def delete(self, key: str) -> bool:
        index = self._hash(key)
        bucket = self.table[index]
        
        for entry in bucket:
            if entry.key == key and not entry.deleted:
                entry.deleted = True
                self.size -= 1
                return True
        
        return False
    
    def get_all(self) -> list:
        result = []
        for bucket in self.table:
            for entry in bucket:
                if not entry.deleted:
                    result.append({'name': entry.key, 'phone': entry.value})
        return result
    
    def clear(self) -> None:
        self.table = [[] for _ in range(self.capacity)]
        self.size = 0
    
    def get_size(self) -> int:
        return self.size
    
    def is_empty(self) -> bool:
        return self.size == 0