Skip to content

Instantly share code, notes, and snippets.

@agfor
Created December 22, 2017 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agfor/96df405bbd3f7ebfc3de9f2d24a36dce to your computer and use it in GitHub Desktop.
Save agfor/96df405bbd3f7ebfc3de9f2d24a36dce to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import random
from collections import Counter, OrderedDict
class OrderedCounter(Counter, OrderedDict):
pass
class FakeEtcd:
def __init__(self, count):
self.locks = [0 for _ in range(count)]
def set(self):
self.locks = [lock + 1 for lock in self.locks]
return self.locks
def rem(self, lock):
self.locks[lock] = 0
def __str__(self):
return str(self.locks)
class MultiLock:
def __init__(self, count):
self.etcd = FakeEtcd(count)
self.count = count
def get(self):
locks = self.etcd.set()
print(locks)
high = sum(1 for lock in locks if lock > self.count)
if high == self.count:
print("too high")
return None
elif len(set(locks)) > 1:
print("don't all match")
value = Counter(locks).most_common(1)[0][0]
lock = len(locks) - list(reversed(locks)).index(value) - 1
if locks[lock] == max(locks) and Counter(locks)[locks[lock]] == 1:
return None
else:
if locks[lock] >= self.count:
return lock - 1
else:
return lock
for i, lock in enumerate(locks):
if lock == 1:
print("lock == 1")
return i
else:
print("all match")
return len(locks) - locks[0]
print("fallthrough")
return None
def release(self, lock):
self.etcd.rem(lock)
def __str__(self):
return str(self.etcd)
class Tracker:
def __init__(self, count):
self.multilock = MultiLock(count)
self.count = count
self.locks = set()
def get(self):
lock = self.multilock.get()
print(lock)
if lock is None:
print(self.locks, "\n")
if len(self.locks) != self.count:
raise RuntimeError("Lock failed when expected to succeed")
elif not (0 <= lock < self.count):
print(self.locks, "\n")
raise RuntimeError("Invalid lock number")
elif lock in self.locks:
print(self.locks, "\n")
raise RuntimeError("Duplicate lock")
else:
self.locks.add(lock)
print(self.locks, "\n")
def rem(self):
if self.locks:
lock = self.locks.pop()
self.multilock.release(lock)
print("rem")
print(self.locks, "\n")
def main():
locks = Tracker(3)
commands = []
while True:
commands.append(random.choice([locks.get, locks.get, locks.rem]))
commands[-1]()
if __name__ == "__main__":
main()
"""
+ - max min % * % ()
count value index offset 0 1 2
3 1,2, 0,1, 0,1 of ones with same value
"""
"""
Two locks
get -> [1, 1] -> lock 0
get -> [2, 2] -> lock 1
get -> [3, 3] -> fail
del 0 -> [0, 3]
get -> [1, 4] -> lock 0
"""
"""
Three locks
get -> [1, 1, 1] -> lock 0
get -> [2, 2, 2] -> lock 1
get -> [3, 3, 3] -> lock 2
del 0 -> [0, 3, 3]
del 1 -> [0, 0, 3]
get -> [1, 1, 4] -> lock 0
get -> [2, 2, 4] -> lock 1
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment