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