src/coordinator/OwnerGeneration.bend

mylsm-lsm-store@0.6.0.0 · 63 lines · 0 definitions

1import Base
2import bend-kit-bytes@0.3.2.0/bytes.bend as Bytes
3
4# Determines the next owner generation without allowing identifier wraparound.
5type Decision is Data:
6  GenerationReady{generation: U32}
7  GenerationExhausted{}
8
9# Separates the increment result from the wrap test.
10def next.result(generation: U32, wraps: Bool) -> Decision:
11  match wraps:
12    case True{}: GenerationExhausted{}
13    case False{}: GenerationReady{generation}
14
15# Encodes an unsigned field in big-endian byte order.
16def u32.bytes(value: U32) -> Bytes.Bytes:
17  Bytes.set.u32be(Bytes.new(4), 0, value)
18
19# Extracts a decoded word while consuming the buffer returned by the reader.
20def u32.read.value(pair: Bytes.Bytes & Maybe<&2, U32>) -> U32:
21  match pair:
22    case (_, Some{value}): value
23    case _: 0
24
25def u32.read(input: Bytes.Bytes) -> U32:
26  u32.read.value(Bytes.get.u32be(input, 0))
27
28def u32.clone.pair.copies(copies: Bytes.Bytes & Bytes.Bytes) -> U32 & U32:
29  match copies:
30    case (left, right): (u32.read(left), u32.read(right))
31
32def u32.clone.pair.buffers(
33  +len: U32,
34  copies: Array<U32> & Array<U32>
35) -> Bytes.Bytes & Bytes.Bytes:
36  match copies:
37    case (left, right): (Bytes.Bytes{len, left}, Bytes.Bytes{len, right})
38
39def u32.clone.pair.input(input: Bytes.Bytes) -> U32 & U32:
40  match input:
41    case Bytes.Bytes{+len, buf}:
42      u32.clone.pair.copies(u32.clone.pair.buffers(len,
43        Bytes.copy.bytes(len, buf, Bytes.alloc(len), 0, 0)))
44
45# Duplicates one fixed-width owner identifier without natural-number recursion.
46def u32.clone.pair(value: U32) -> U32 & U32:
47  u32.clone.pair.input(u32.bytes(value))
48
49# Advances a stored generation or reports terminal exhaustion.
50def next.copies(copies: U32 & U32) -> Decision:
51  match copies:
52    case (for_increment, for_wrap):
53      next.result(U32.add(for_increment, 1), U32.is_zero(U32.add(for_wrap, 1)))
54
55# Chooses generation one for a new owner state and advances a persisted value.
56def next(current: Maybe<&2, U32>) -> Decision:
57  match current:
58    case None{}: GenerationReady{1}
59    case Some{generation}:
60      next.copies(u32.clone.pair(generation))
61
62def response.generation(active: U32) -> U32:
63  active