Skip to content

Commit 85d022d

Browse files
committed
Add bandwidth simulations
1 parent 4580d16 commit 85d022d

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

simulation/simulate.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import random
2+
3+
class Tree:
4+
def __init__(self, tree_path_count):
5+
self.tree_path_count = tree_path_count
6+
7+
def get_random_paths(self, batch_size):
8+
if batch_size > self.tree_path_count:
9+
raise ValueError("Batch size cannot be greater than the number of paths in the tree")
10+
return [random.randint(1, self.tree_path_count) for _ in range(batch_size)]
11+
12+
def get_unique_buckets_for_random_paths(self, random_paths):
13+
unique_buckets = set()
14+
for path_id in random_paths:
15+
leaf_id = self.tree_path_count + path_id - 1
16+
bucket_id = leaf_id
17+
while bucket_id > 0:
18+
unique_buckets.add(bucket_id)
19+
bucket_id = bucket_id >> 1
20+
return unique_buckets
21+
22+
EXPERIMETNS = 1000
23+
24+
class Simulator:
25+
def __init__(self, num_requests, batch_size, tree_path_count):
26+
self.num_requests = num_requests
27+
self.tree = Tree(tree_path_count)
28+
self.batch_size = batch_size
29+
30+
def run_once(self):
31+
retrieved_buckets_count = 0
32+
for i in range(0, self.num_requests, self.batch_size):
33+
random_paths = self.tree.get_random_paths(self.batch_size)
34+
unique_buckets = self.tree.get_unique_buckets_for_random_paths(random_paths)
35+
retrieved_buckets_count += len(unique_buckets)
36+
return retrieved_buckets_count
37+
38+
def run(self):
39+
total_buckets_count = 0
40+
for _ in range(EXPERIMETNS):
41+
total_buckets_count += self.run_once()
42+
print("Average number of buckets retrieved per request:", total_buckets_count / (self.num_requests * EXPERIMETNS))
43+
44+
45+
if __name__ == '__main__':
46+
batch_size = 2
47+
num_requests = 1000
48+
tree_path_count = 2**20
49+
sim = Simulator(num_requests, batch_size, tree_path_count)
50+
sim.run()

simulation/simulate_test.py

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import unittest
2+
from simulate import Tree
3+
4+
5+
class TestTree(unittest.TestCase):
6+
def test_get_random_paths_is_in_range(self):
7+
tree = Tree(tree_path_count=10)
8+
batch_size = 5
9+
paths = tree.get_random_paths(batch_size)
10+
for path in paths:
11+
self.assertTrue(1 <= path <= 10)
12+
13+
def test_get_random_paths_returns_correct_number_of_paths(self):
14+
tree = Tree(tree_path_count=10)
15+
batch_size = 5
16+
paths = tree.get_random_paths(batch_size)
17+
self.assertEqual(len(paths), batch_size)
18+
19+
def test_get_unique_buckets_for_random_paths_without_duplicates(self):
20+
tree = Tree(tree_path_count=2)
21+
# 1
22+
# / \
23+
# 2 3
24+
# path number: 1 2
25+
buckets = tree.get_unique_buckets_for_random_paths(random_paths=[1])
26+
expected_buckets = {1, 2}
27+
self.assertSetEqual(buckets, expected_buckets)
28+
29+
def test_get_unique_buckets_for_random_paths_with_duplicates(self):
30+
tree = Tree(tree_path_count=2)
31+
# 1
32+
# / \
33+
# 2 3
34+
# path number: 1 2
35+
buckets = tree.get_unique_buckets_for_random_paths(random_paths=[1, 2])
36+
expected_buckets = {1, 2, 3}
37+
self.assertSetEqual(buckets, expected_buckets)
38+
39+
def test_get_unique_buckets_for_random_paths_with_multiple_paths(self):
40+
tree = Tree(tree_path_count=4)
41+
# 1
42+
# / \
43+
# 2 3
44+
# / \ / \
45+
# 4 5 6 7
46+
# path number: 1 2 3 4
47+
buckets = tree.get_unique_buckets_for_random_paths(random_paths=[1, 2, 3])
48+
expected_buckets = {1, 2, 4, 5, 3, 6}
49+
self.assertSetEqual(buckets, expected_buckets)
50+
51+
if __name__ == '__main__':
52+
unittest.main()

0 commit comments

Comments
 (0)