1 import Base 2 import mylsm-lsm-store@0.3.1.0/mylsm.bend as MyLsmStore 3 import mylsm-lsm-store@0.3.1.0/src/Db.bend as DbTypes 4 5 # Session effects for ber-core. Op is a newtype over MyLSM Sess and Handle 6 # over MyLSM Db: ber-core names THESE types, and this module is the ONLY one 7 # naming MyLSM. do-blocks desugar through Op.bind/Op.pure exactly like Sess. 8 # Bend has no value projection: inner sessions unwrap via Op.inner (match on 9 # the parameter), never `op.run`; computed pairs thread through helpers. 10 11 # One session step chain; the answer type rides along. 12 type Op is Kind(a <&> &1): 13 Op{run: MyLsmStore.Sess} 14 15 # An opened store handle; affine, threaded through run_op. 16 type Handle is Type: 17 Handle{db: DbTypes.Db} 18 19 # Unwraps the inner session for translators like bind and run_op. 20 def Op.inner(b, -B: Kind(b), op: Op) -> MyLsmStore.Sess: 21 match op: 22 case Op{inner_sess}: 23 inner_sess 24 25 # Lifts a pure value; what `return` desugars to inside do-blocks. 26 def Op.pure(a, -A: Kind(a), val: A) -> Op: 27 Op{MyLsmStore.Sess.pure(a, A, val)} 28 29 # Sequences two ops; what `<-` desugars to inside do-blocks. 30 def Op.bind(a, -A: Kind(a), -B: Kind(a), op: Op, fun: A -> Op) -> Op: 31 Op{MyLsmStore.Sess.bind(a, A, B, Op.inner(a, A, op), x => Op.inner(a, B, fun(x)))} 32 33 # Writes one key. 34 def oput(+key: String, +val: String) -> Op<&2, Unit>: 35 Op{MyLsmStore.sput(key, val)} 36 37 # Reads one key; missing reads as None. 38 def oget(+key: String) -> Op<&2, Maybe<&2, String>>: 39 Op{MyLsmStore.sget(key)} 40 41 # Deletes one key. 42 def odel(+key: String) -> Op<&2, Unit>: 43 Op{MyLsmStore.sdel(key)} 44 45 # Opens a store handle over a directory label. 46 def open_store(+dir: String) -> Handle: 47 Handle{MyLsmStore.open(dir)} 48 49 # Rewraps a computed runner pair into Handle form. 50 def rewrap_pair(a, -A: Kind(a), computed_pair: DbTypes.Db & A) -> Handle & A: 51 match computed_pair: 52 case (db_next, answer): 53 (Handle{db_next}, answer) 54 55 # Executes a whole op chain against a handle. 56 def run_op(a, -A: Kind(a), store: Handle, op: Op) -> Handle & A: 57 match store: 58 case Handle{db}: 59 rewrap_pair(a, A, MyLsmStore.run_sess(a, A, db, Op.inner(a, A, op)))