Add week 7 materials
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
"""A deterministic Chord routing exercise, not a network implementation."""
|
||||
import argparse
|
||||
from bisect import bisect_left
|
||||
|
||||
SIZE = 32
|
||||
NODES = [2, 7, 13, 20, 27]
|
||||
|
||||
|
||||
def successor(nodes, key):
|
||||
return nodes[bisect_left(nodes, key) % len(nodes)]
|
||||
|
||||
|
||||
def fingers(nodes, node):
|
||||
return [(point, successor(nodes, point))
|
||||
for point in ((node + (1 << i)) % SIZE for i in range(5))]
|
||||
|
||||
|
||||
def lookup(nodes, start, key, fast=True):
|
||||
current, route = start, [start]
|
||||
for _ in range(len(nodes) + 1):
|
||||
if key == current or len(nodes) == 1:
|
||||
return current, route
|
||||
next_node = nodes[(nodes.index(current) + 1) % len(nodes)]
|
||||
if (key - current) % SIZE <= (next_node - current) % SIZE:
|
||||
return next_node, route
|
||||
candidates = [n for _, n in fingers(nodes, current)
|
||||
if 0 < (n - current) % SIZE < (key - current) % SIZE]
|
||||
current = max(candidates, key=lambda n: (n - current) % SIZE) if fast and candidates else next_node
|
||||
route.append(current)
|
||||
raise RuntimeError("Routing loop")
|
||||
|
||||
|
||||
def check():
|
||||
for nodes in (NODES, sorted(NODES + [24]), [2, 7, 13, 27], [2], [0, 31]):
|
||||
for start in nodes:
|
||||
for key in range(SIZE):
|
||||
for fast in (False, True):
|
||||
owner, _ = lookup(nodes, start, key, fast)
|
||||
assert owner == successor(nodes, key), (nodes, start, key, fast)
|
||||
print("PASS: all keys and start nodes, before/after join/failure, singleton and wraparound")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--check", action="store_true")
|
||||
args = parser.parse_args()
|
||||
if args.check:
|
||||
check()
|
||||
return
|
||||
print("Ring 0..31; nodes:", NODES)
|
||||
for key in (0, 18, 26):
|
||||
print(f"key {key:2} -> owner {successor(NODES, key)}")
|
||||
print("\nFinger table of node 2 (start -> successor):")
|
||||
for point, node in fingers(NODES, 2):
|
||||
print(f"{point:2} -> {node:2}")
|
||||
for fast in (False, True):
|
||||
owner, route = lookup(NODES, 2, 26, fast)
|
||||
print(f"{'fingers' if fast else 'neighbors'}: route {route}; result {owner}; "
|
||||
f"forwarded requests {len(route) - 1}")
|
||||
joined = sorted(NODES + [24])
|
||||
changed = [key for key in range(SIZE) if successor(NODES, key) != successor(joined, key)]
|
||||
print("\nJoin node 24; transferred keys:", changed)
|
||||
print("Fail node 24; after repairing the ring the owner is 27.")
|
||||
print("Routing references do not recreate lost values; replicas are a separate concern.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user