diff --git a/src/.prototype/main.py b/src/.prototype/main.py new file mode 100644 index 0000000..259fd11 --- /dev/null +++ b/src/.prototype/main.py @@ -0,0 +1,133 @@ +import random +import time +import threading +import queue +from sys import argv + +def main(): + def __input__(): + return input() + if argv[1:]: + f = open(argv[1]) + def __input__(): + return f.readline() + input_buffer = InputBuffer() + input_buffer.start() + print("accepting input") + while True: + try: + got = __input__() + input_buffer.enqueue(got.strip()) + except KeyboardInterrupt: + print("stopping") + input_buffer.stop() + break + input_buffer.join() + print("stopped") + +class InputBuffer(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + self.pages = {} + self.q = queue.Queue() + self.done = False + + def now(): + return time.time() + + def interval(): + return .1 + + def stop(self): + self.done = True + self.q.put(None) + + def bucket(self, t): + t *= 1000 + i = InputBuffer.interval() * 1000 + tp = int(t // i) * int(i) + return tp / 1000 + + def run(self): + state = InputBuffer.State(0, None) + previous = None + while not self.done: + try: + state = InputBuffer.State.choose(state, self._run()) + latest = state.v + if latest != previous: + print(InputBuffer.now(), latest) + previous = latest + except Exception as e: + print(e) + time.sleep(InputBuffer.interval()) + + def _run(self): + now = InputBuffer.now() + deadline = now + InputBuffer.interval() + while InputBuffer.now() < deadline: + if self.dequeue(deadline - InputBuffer.now()) == None: + self.done = True + return + return InputBuffer.State(now, self.pick(now)) + + def enqueue(self, k): + self.q.put([ InputBuffer.now(), k.lower() ]) + + def dequeue(self, timeout): + try: + if timeout <= 0: + return False + got = self.q.get(timeout=timeout) + except queue.Empty: + return False + if got: + t = self.bucket(got[0]) + k = got[1] + if not t in self.pages: + self.pages[t] = InputBuffer.Page() + self.pages[t].push(k) + return got + + def pick(self, t): + return self.pages.get(self.bucket(t), InputBuffer.Page()).pick() + + class Page: + def __init__(self): + self.inputs = {} + + def push(self, k): + self.inputs[k] = self.inputs.get(k, 0) + 1 + + def pick(self): + if not self.inputs: + return None + options = [] + for k,v in self.inputs.items(): + for i in range(0, v): + options.append(k) + return options[random.randint(0, len(options)-1)] + + class State: + def __init__(self, t, v): + self.t = t + self.v = v + + def choose(a, b): + if not a: + return b + if not b: + return a + latest = a + oldest = b + if b.t > a.t: + latest = b + oldest = a + if latest.v == None: + t_a_few_intervals_ago = InputBuffer.now() - InputBuffer.interval() * 10 + if oldest.t > t_a_few_intervals_ago: + return oldest + return latest + +if __name__ == "__main__": + main() diff --git a/src/.prototype/run.sh b/src/.prototype/run.sh new file mode 100644 index 0000000..d1ab6b6 --- /dev/null +++ b/src/.prototype/run.sh @@ -0,0 +1,20 @@ +#! /bin/bash + +main() { + cleanup() { + jobs="$(jobs -p)" + test -n "$jobs" && kill -9 $jobs + } + trap cleanup EXIT + + local pipe=/tmp/breel.pipe + test -e "$pipe" || mkfifo $pipe + while true; do + read -s v + echo "$v" + done | python3 ./main.py +} + +if [ "$0" == "$BASH_SOURCE" ]; then + main "$@" +fi