This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def random_choice(rng, options, weights=None): | |
"""Pick something randomly from a list""" | |
if weights is None: | |
# Simple case: everything has equal chance | |
index = rng.extract_number() % len(options) | |
return options[index] | |
# Complex case: some things are more likely than others | |
# Generate random value in [0, sum(weights)) | |
r = random_float(rng) * sum(weights) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def random_float(mt): | |
"""Generate a random float in [0.0, 1.0)""" | |
return mt.extract_number() / 0xffffffff # Divide by 2^32 - 1 | |
def uniform(mt, a, b): | |
"""Generate a random float in [a, b)""" | |
return a + (b - a) * random_float(mt) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MersenneTwister: | |
def __init__(self, seed): | |
self.MT = [0] * 624 # State array | |
self.index = 624 | |
self.MT[0] = seed | |
# Initialize the rest of the state array | |
for i in range(1, 624): | |
self.MT[i] = (0xffffffff & | |
(1812433253 * (self.MT[i-1] ^ (self.MT[i-1] >> 30)) + i)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SimpleRandomGenerator: | |
def __init__(self, seed): | |
self.state = seed | |
def next(self): | |
# Magic numbers that make our randomness look good | |
a = 1664525 | |
c = 1013904223 | |
m = 2**32 | |
# Mix everything together |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def delete(self, key: str): | |
"""Delete a key""" | |
with self.lock: | |
self.wal.delete(key) | |
self.set(key, None) # Use None as tombstone | |
def close(self): | |
"""Ensure all data is persisted to disk""" | |
with self.lock: | |
if self.memtable.entries: # If there's data in memtable |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def test_basic_operations(db_path): | |
db = LSMTree(db_path) | |
# Test single key-value | |
db.set("test_key", "test_value") | |
assert db.get("test_key") == "test_value" | |
# Test overwrite | |
db.set("test_key", "new_value") | |
assert db.get("test_key") == "new_value" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def _compact(self): | |
"""Merge multiple SSTables into one""" | |
try: | |
# Create merged memtable | |
merged = MemTable(max_size=float("inf")) | |
# Merge all SSTables | |
for sstable in self.sstables: | |
for key, value in sstable.range_scan("", "~"): # Full range | |
merged.add(key, value) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def get(self, key: str) -> Optional[Any]: | |
"""Get value for key""" | |
with self.lock: | |
if not isinstance(key, str): | |
raise ValueError("Key must be a string") | |
# 1. Check memtable first (newest data) | |
value = self.memtable.get(key) | |
if value is not None: | |
return value |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def set(self, key: str, value: Any): | |
"""Set a key-value pair""" | |
with self.lock: | |
if not isinstance(key, str): | |
raise ValueError("Key must be a string") | |
# 1. Safety first: Write to WAL | |
self.wal.set(key, value) | |
# 2. Write to memory table (fast!) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LSMTree: | |
def __init__(self, base_path: str): | |
self.base_path = Path(base_path) | |
try: | |
# Check if path exists and is a file | |
if self.base_path.exists() and self.base_path.is_file(): | |
raise DatabaseError(f"Cannot create database: '{base_path}' is a file") | |
self.base_path.mkdir(parents=True, exist_ok=True) |