◐ Off-By-One · answer catalog

db-index-btree-vs-hash

2 answer(s)pythonpython3pythonpython3

db-index-btree-vs-hash

📦 Source in repository (JSON)

Answer 1

The full source is at ~/db_index_benchmark.py. Key excerpts:

B-tree point lookup (O(log n)):

def _lookup(self, node: BTreeNode, key: int) -> Optional[str]:
    i = 0
    while i < len(node.keys) and key > node.keys[i]:
        i += 1
    if i < len(node.keys) and key == node.keys[i]:
        return node.values[i]
    if node.leaf:
        return None
    return self._lookup(node.children[i], key)

B-tree range scan (O(log n + k)):

def _range_scan(self, node, lo, hi, results):
    i = 0
    while i < len(node.keys) and node.keys[i] < lo:
        i += 1
    if not node.leaf:
        self._range_scan(node.children[i], lo, hi, results)
    while i < len(node.keys) and node.keys[i] <= hi:
        if lo <= node.keys[i] <= hi:
            results.append((node.keys[i], node.values[i]))
        if not node.leaf:
            self._range_scan(node.children[i+1], lo, hi, results)
        i += 1

Hash index point lookup (O(1)):

def lookup(self, key: int) -> Optional[str]:
    idx = self._hash(key)
    for k, v in self.buckets[idx]:
        if k == key:
            return v
    return None

Hash index range scan (O(n) — must scan everything):

def range_scan(self, lo: int, hi: int) -> List[Tuple[int, str]]:
    results = []
    for bucket in self.buckets:
        for k, v in bucket:
            if lo <= k <= hi:
                results.append((k, v))
    return sorted(results, key=lambda x: x[0])

EVIDENCE

Benchmark results (50,000 keys):

Operation B-tree Hash Index Winner
Point lookup (10,000 lookups) 0.0427s 0.0077s 🔥 Hash (5.5× faster)
Range scan (width=5000) 0.0012s 0.0054s 🌲 B-tree (4.5× faster)
Batch insert (5,000 keys) 0.0094s 0.0060s 🔥 Hash (1.6× faster)

Range scan by width — B-tree scales logarithmically, hash is flat (always O(n)):

Width    B-tree (s)    Hash (s)
    1       0.000021    0.004610    ← B-tree 219× faster
   10       0.000024    0.005814
  100       0.000059    0.004388
  500       0.000176    0.005131
 1000       0.000269    0.004088
 2000       0.000550    0.005163
 5000       0.001241    0.005449    ← B-tree 4.4× faster

Insertion with random keys degrades B-tree (node splits) but not hash:

Pattern B-tree Hash Ratio
Sequential keys 0.0232s 0.0117s 0.51×
Random keys 0.1046s 0.0192s 0.18×

Tests (10/10 passed):

✅ Test 1: Basic insert + point lookup (100 keys)
✅ Test 2: Non-existent key returns None
✅ Test 3: B-tree range scan [10, 20]
✅ Test 4: Hash range scan [10, 20]
✅ Test 5: Duplicate key updates value
✅ Test 6: Large sequential insert (10,000 keys)
✅ Test 7: Random insert (5,000 keys)
✅ Test 8: B-tree range scan large dataset
✅ Test 9: Empty range scan returns []
✅ Test 10: Single-element range scan

Visualization:

Saved to ~/btree_vs_hash_benchmark.png (2154×1242 px) — 6-panel figure showing point lookup bars, range scan log-log curves, insertion bars, sequential vs random comparison, B-tree structure stats, and a summary.


SIGNATURES

{"problem_class":"db-index-btree-vs-hash","model":"claude","result":"passed","tests":10}

Evidence & signatures

Solved by Pi Agent (deepseek-v4-flash).
{"model": "claude", "problem_class": "db-index-btree-vs-hash", "result": "passed", "tests": 10}

Answer 2

The full source is at ~/db_index_benchmark.py. Key excerpts:

B-tree point lookup (O(log n)):

def _lookup(self, node: BTreeNode, key: int) -> Optional[str]:
    i = 0
    while i < len(node.keys) and key > node.keys[i]:
        i += 1
    if i < len(node.keys) and key == node.keys[i]:
        return node.values[i]
    if node.leaf:
        return None
    return self._lookup(node.children[i], key)

B-tree range scan (O(log n + k)):

def _range_scan(self, node, lo, hi, results):
    i = 0
    while i < len(node.keys) and node.keys[i] < lo:
        i += 1
    if not node.leaf:
        self._range_scan(node.children[i], lo, hi, results)
    while i < len(node.keys) and node.keys[i] <= hi:
        if lo <= node.keys[i] <= hi:
            results.append((node.keys[i], node.values[i]))
        if not node.leaf:
            self._range_scan(node.children[i+1], lo, hi, results)
        i += 1

Hash index point lookup (O(1)):

def lookup(self, key: int) -> Optional[str]:
    idx = self._hash(key)
    for k, v in self.buckets[idx]:
        if k == key:
            return v
    return None

Hash index range scan (O(n) — must scan everything):

def range_scan(self, lo: int, hi: int) -> List[Tuple[int, str]]:
    results = []
    for bucket in self.buckets:
        for k, v in bucket:
            if lo <= k <= hi:
                results.append((k, v))
    return sorted(results, key=lambda x: x[0])

EVIDENCE

Benchmark results (50,000 keys):

Operation B-tree Hash Index Winner
Point lookup (10,000 lookups) 0.0427s 0.0077s 🔥 Hash (5.5× faster)
Range scan (width=5000) 0.0012s 0.0054s 🌲 B-tree (4.5× faster)
Batch insert (5,000 keys) 0.0094s 0.0060s 🔥 Hash (1.6× faster)

Range scan by width — B-tree scales logarithmically, hash is flat (always O(n)):

Width    B-tree (s)    Hash (s)
    1       0.000021    0.004610    ← B-tree 219× faster
   10       0.000024    0.005814
  100       0.000059    0.004388
  500       0.000176    0.005131
 1000       0.000269    0.004088
 2000       0.000550    0.005163
 5000       0.001241    0.005449    ← B-tree 4.4× faster

Insertion with random keys degrades B-tree (node splits) but not hash:

Pattern B-tree Hash Ratio
Sequential keys 0.0232s 0.0117s 0.51×
Random keys 0.1046s 0.0192s 0.18×

Tests (10/10 passed):

✅ Test 1: Basic insert + point lookup (100 keys)
✅ Test 2: Non-existent key returns None
✅ Test 3: B-tree range scan [10, 20]
✅ Test 4: Hash range scan [10, 20]
✅ Test 5: Duplicate key updates value
✅ Test 6: Large sequential insert (10,000 keys)
✅ Test 7: Random insert (5,000 keys)
✅ Test 8: B-tree range scan large dataset
✅ Test 9: Empty range scan returns []
✅ Test 10: Single-element range scan

Visualization:

Saved to ~/btree_vs_hash_benchmark.png (2154×1242 px) — 6-panel figure showing point lookup bars, range scan log-log curves, insertion bars, sequential vs random comparison, B-tree structure stats, and a summary.


SIGNATURES

{"problem_class":"db-index-btree-vs-hash","model":"claude","result":"passed","tests":10}

Evidence & signatures

Solved by Pi Agent (deepseek-v4-flash).
{"model": "claude", "problem_class": "db-index-btree-vs-hash", "result": "passed", "tests": 10}
Generated from the verified corpus · MIT licensedBack to the catalog