Skip to content

Commit dcd9b31

Browse files
committedMay 8, 2023
wokring on btree
1 parent 4a56b3a commit dcd9b31

File tree

4 files changed

+239
-51
lines changed

4 files changed

+239
-51
lines changed
 

‎notebooks/B-Tree.ipynb

+235
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 35,
6+
"id": "destroyed-ground",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from abc import ABC, abstractmethod\n",
11+
"import bisect"
12+
]
13+
},
14+
{
15+
"cell_type": "code",
16+
"execution_count": 5,
17+
"id": "matched-tract",
18+
"metadata": {},
19+
"outputs": [],
20+
"source": [
21+
"class BPlusTreeNode(ABC):\n",
22+
" def __init__(self, kvstore = None, is_leaf = False):\n",
23+
" self._kvstore = kvstore if kvstore else []\n",
24+
" self._is_leaf = is_leaf\n",
25+
" \n",
26+
" \n",
27+
" def delete(self, key):\n",
28+
" idx = -1\n",
29+
" for i, tup in enumerate(self._kvstore):\n",
30+
" k, _ = tup\n",
31+
" if k == key:\n",
32+
" idx = i\n",
33+
" if idx != -1:\n",
34+
" del self._kvstore[idx]\n",
35+
" \n",
36+
" \n",
37+
" def find(self, key):\n",
38+
" # TODO: Use binary search here instead;\n",
39+
" # look into using bisect.bisect_left\n",
40+
" for k,v in self._kvstore:\n",
41+
" if k == key:\n",
42+
" return (k,v)\n",
43+
" return None\n",
44+
"\n",
45+
" \n",
46+
" def order(self):\n",
47+
" return len(self._kvstore) \n",
48+
"\n",
49+
" def insert(self, key_or_tuple, value=None):\n",
50+
" \"\"\"\n",
51+
" TODO: Maybe we should implement this in the child classes\n",
52+
" since \n",
53+
" \"\"\"\n",
54+
" if isinstance(key_or_tuple, tuple) and value is None:\n",
55+
" key, value = key_or_tuple\n",
56+
" elif not isinstance(key_or_tuple, tuple) and value is not None:\n",
57+
" key = key_or_tuple\n",
58+
" else:\n",
59+
" raise TypeError(\"Invalid arguments: insert() takes either a tuple or a key-value pair\")\n",
60+
" self._kvstore.append((key, value))\n",
61+
" self._kvstore.sort()\n",
62+
" \n",
63+
" \n",
64+
" @abstractmethod\n",
65+
" def is_leaf(self):\n",
66+
" pass"
67+
]
68+
},
69+
{
70+
"cell_type": "code",
71+
"execution_count": 10,
72+
"id": "cardiac-techno",
73+
"metadata": {},
74+
"outputs": [],
75+
"source": [
76+
"class BPlusTreeInternalNode(BPlusTreeNode):\n",
77+
" def __init__(self):\n",
78+
" super().__init__()\n",
79+
" \n",
80+
" def is_leaf(self):\n",
81+
" return False\n",
82+
"\n",
83+
"#############\n",
84+
"### Tests ###\n",
85+
"#############\n",
86+
"node = BPlusTreeInternalNode()\n",
87+
"node1 = BPlusTreeInternalNode()\n",
88+
"node2 = BPlusTreeInternalNode()\n",
89+
"node3 = BPlusTreeInternalNode()\n",
90+
"node4 = BPlusTreeInternalNode()\n",
91+
"\n",
92+
"node.insert(20, node1)\n",
93+
"node.insert(10, node2)\n",
94+
"node.insert((30, node3))\n",
95+
"node.insert(2, node4)\n",
96+
"assert node._kvstore == [(2, node4), (10, node2), (20, node1), (30, node3)]\n",
97+
"assert node.order() == 4\n",
98+
"assert node.find(10) == (10, node2)\n",
99+
"assert not node.is_leaf()\n",
100+
"node.delete(2)\n",
101+
"assert node._kvstore == [(10, node2), (20, node1), (30, node3)]"
102+
]
103+
},
104+
{
105+
"cell_type": "code",
106+
"execution_count": 13,
107+
"id": "instructional-final",
108+
"metadata": {},
109+
"outputs": [],
110+
"source": [
111+
"class BPlusTreeLeafNode(BPlusTreeNode):\n",
112+
" def __init__(self, next_leaf = None, prev_leaf = None):\n",
113+
" super().__init__()\n",
114+
" self._next_leaf = next_leaf\n",
115+
" self._prev_leaf = prev_leaf\n",
116+
"\n",
117+
" def insert(self, key_or_tuple, value=None):\n",
118+
" if isinstance(key_or_tuple, tuple) and value is None:\n",
119+
" key, value = key_or_tuple\n",
120+
" elif not isinstance(key_or_tuple, tuple) and value is not None:\n",
121+
" key = key_or_tuple\n",
122+
" else:\n",
123+
" raise TypeError(\"Invalid arguments: insert() takes either a tuple or a key-value pair\")\n",
124+
" self._kvstore.append((key, value))\n",
125+
" self._kvstore.sort()\n",
126+
" \n",
127+
" def is_leaf(self):\n",
128+
" return True\n",
129+
" \n",
130+
" def set_next_leaf(self, next_leaf):\n",
131+
" self._next_leaf = next_leaf\n",
132+
" \n",
133+
" def get_next_leaf(self):\n",
134+
" return self._next_leaf\n",
135+
"\n",
136+
" def set_prev_leaf(self, prev_leaf):\n",
137+
" self._prev_leaf = prev_leaf\n",
138+
" \n",
139+
" def get_prev_leaf(self):\n",
140+
" return self._prev_leaf\n",
141+
"\n",
142+
"\n",
143+
"#############\n",
144+
"### Tests ###\n",
145+
"#############\n",
146+
"node = BPlusTreeLeafNode()\n",
147+
"node.insert(20, \"bob\")\n",
148+
"node.insert(10, \"alice\")\n",
149+
"node.insert((30, \"cathy\"))\n",
150+
"node.insert(2, \"doug\")\n",
151+
"assert node._kvstore == [(2, 'doug'), (10, 'alice'), (20, 'bob'), (30, 'cathy')]\n",
152+
"assert node.order() == 4\n",
153+
"assert node.find(10) == (10, 'alice')\n",
154+
"assert node.is_leaf()\n",
155+
"node.delete(2)\n",
156+
"assert node._kvstore == [(10, 'alice'), (20, 'bob'), (30, 'cathy')]\n",
157+
"\n",
158+
"node0 = BPlusTreeLeafNode()\n",
159+
"for i in range(10):\n",
160+
" node0.insert((i, f\"boomer{i}\"))\n",
161+
"node2 = BPlusTreeLeafNode()\n",
162+
"for i in range(10):\n",
163+
" node2.insert((i, f\"coomer{i}\"))\n",
164+
"\n",
165+
"node.set_prev_leaf(node0)\n",
166+
"assert node.get_prev_leaf() == node0\n",
167+
"node.set_next_leaf(node2)\n",
168+
"assert node.get_next_leaf() == node2\n"
169+
]
170+
},
171+
{
172+
"cell_type": "code",
173+
"execution_count": 46,
174+
"id": "rotary-storage",
175+
"metadata": {},
176+
"outputs": [],
177+
"source": [
178+
"class BPlusTree:\n",
179+
" \"\"\"\n",
180+
" B-tree, but with some constraints:\n",
181+
" - Keys can only be stored in leaf nodes\n",
182+
" - All nodes but root must be half-full to maintain balance\n",
183+
" - Leaf nodes connected via pointers (for traverse())\n",
184+
" - All records stored in leaf nodes\n",
185+
" \"\"\"\n",
186+
" def __init__(self, order, root = None):\n",
187+
" self._root = BTreeNode() if root == None else root\n",
188+
" self._order = order\n",
189+
" \n",
190+
" def insert(self, key):\n",
191+
" pass\n",
192+
" \n",
193+
" def delete(self, key):\n",
194+
" pass\n",
195+
" \n",
196+
" def find(self, key):\n",
197+
" pass\n",
198+
" \n",
199+
" def traverse(self):\n",
200+
" pass\n",
201+
" \n",
202+
" def range_query(self, start_key, end_key):\n",
203+
" pass\n",
204+
" \n",
205+
" def load(self):\n",
206+
" pass\n",
207+
"\n",
208+
"#############\n",
209+
"### Tests ###\n",
210+
"#############\n"
211+
]
212+
}
213+
],
214+
"metadata": {
215+
"kernelspec": {
216+
"display_name": "Python 3",
217+
"language": "python",
218+
"name": "python3"
219+
},
220+
"language_info": {
221+
"codemirror_mode": {
222+
"name": "ipython",
223+
"version": 3
224+
},
225+
"file_extension": ".py",
226+
"mimetype": "text/x-python",
227+
"name": "python",
228+
"nbconvert_exporter": "python",
229+
"pygments_lexer": "ipython3",
230+
"version": "3.9.16"
231+
}
232+
},
233+
"nbformat": 4,
234+
"nbformat_minor": 5
235+
}

‎notebooks/Math.ipynb

-47
Original file line numberDiff line numberDiff line change
@@ -140,53 +140,6 @@
140140
"## References / Credits\n",
141141
"- [CS 97 maths](https://web.stanford.edu/class/cs97si/02-mathematics.pdf)"
142142
]
143-
},
144-
{
145-
"cell_type": "code",
146-
"execution_count": 9,
147-
"id": "5b16487f",
148-
"metadata": {},
149-
"outputs": [
150-
{
151-
"data": {
152-
"text/plain": [
153-
"True"
154-
]
155-
},
156-
"execution_count": 9,
157-
"metadata": {},
158-
"output_type": "execute_result"
159-
}
160-
],
161-
"source": [
162-
"(2**8) == ((2**4)**2)"
163-
]
164-
},
165-
{
166-
"cell_type": "code",
167-
"execution_count": 47,
168-
"id": "ff7e211d",
169-
"metadata": {},
170-
"outputs": [
171-
{
172-
"name": "stdout",
173-
"output_type": "stream",
174-
"text": [
175-
"0.3333333333333333\n"
176-
]
177-
}
178-
],
179-
"source": [
180-
"print(1/3)"
181-
]
182-
},
183-
{
184-
"cell_type": "code",
185-
"execution_count": null,
186-
"id": "c73abfa1",
187-
"metadata": {},
188-
"outputs": [],
189-
"source": []
190143
}
191144
],
192145
"metadata": {

‎notebooks/WIP/Binary Search Tree.ipynb

+2-2
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@
283283
],
284284
"metadata": {
285285
"kernelspec": {
286-
"display_name": "Python 3 (ipykernel)",
286+
"display_name": "Python 3",
287287
"language": "python",
288288
"name": "python3"
289289
},
@@ -297,7 +297,7 @@
297297
"name": "python",
298298
"nbconvert_exporter": "python",
299299
"pygments_lexer": "ipython3",
300-
"version": "3.8.10"
300+
"version": "3.9.16"
301301
}
302302
},
303303
"nbformat": 4,

‎notebooks/WIP/Contents.ipynb

+2-2
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@
287287
],
288288
"metadata": {
289289
"kernelspec": {
290-
"display_name": "Python 3 (ipykernel)",
290+
"display_name": "Python 3",
291291
"language": "python",
292292
"name": "python3"
293293
},
@@ -301,7 +301,7 @@
301301
"name": "python",
302302
"nbconvert_exporter": "python",
303303
"pygments_lexer": "ipython3",
304-
"version": "3.10.4"
304+
"version": "3.9.16"
305305
}
306306
},
307307
"nbformat": 4,

0 commit comments

Comments
 (0)
Failed to load comments.