prototyped

master
Bel LaPointe 2022-09-18 11:35:57 -06:00
parent 0b0d001a2f
commit 52e9df34d3
2 changed files with 153 additions and 0 deletions

133
src/.prototype/main.py Normal file
View File

@ -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()

20
src/.prototype/run.sh Normal file
View File

@ -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