Skip to content

Commit

Permalink
Enveloping commentary
Browse files Browse the repository at this point in the history
  • Loading branch information
gritzko committed May 6, 2024
1 parent 154a97e commit 706f891
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
1 change: 1 addition & 0 deletions orm.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ func (orm *ORM) Close() error {
return ErrClosed
}
orm.objects.Clear()
orm.ids.Clear()
orm.Host = nil
_ = orm.Snap.Close()
orm.Snap = nil
Expand Down
16 changes: 16 additions & 0 deletions rdx/ELM_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ import (
"github.com/stretchr/testify/assert"
)

func TestMap(t *testing.T) {
var correct = []byte{
0x6D, 0x15,
0x36, 0x03, 0x00, 0xaf, 0x00, 0x0b, 0x0b,
0x73, 0x04, 0x30, 0x4b, 0x65, 0x79,
0x73, 0x06, 0x30, 0x56, 0x61, 0x6c, 0x75, 0x65,
}
id := IDFromString("b0b-af0-3")
env2 := protocol.Record('M',
protocol.TinyRecord('I', id.ZipBytes()),
protocol.Record('S', protocol.TinyRecord('T', ZipIntUint64Pair(0, 0)), []byte("Key")),
protocol.Record('S', protocol.TinyRecord('T', ZipIntUint64Pair(0, 0)), []byte("Value")),
)
assert.Equal(t, correct, env2)
}

func TestEmerge(t *testing.T) {
tlv1 := Eparse("{1, 2, \"four\"}")
assert.Equal(t, "{1,2,\"four\"}", Estring(tlv1))
Expand Down
31 changes: 30 additions & 1 deletion rdx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ to produce `I{1,3}1 T{-4,4} I{2,3}2 I{3,3}3` or `[2,3]`.

The string value for an array is like `[1,2,3]`

### `V`
### `V` Version vector

[Version vector][v] is a way to track dataset versions in a
causally ordered system. It is a vector of `seq` numbers, where
Expand Down Expand Up @@ -245,6 +245,35 @@ which has a separate bit-level [LEB128][b] coding for ints).
id64 and logical timestamps get packed as pairs of uint64s. All
zip codings are little-endian.

## Enveloping

RDX values can be bare, enveloped or double-enveloped. We use
bare values when we already know what field of what object we
are dealing with and what RDT it belongs to. That might be the
case when we read a value from a key-value storage where the key
contains object id, field and RDT. In such a case, a bare
Integer is like `{3,2}1` or `32 03 02 02`.
Within a network packet, that integer may need to be
single-enveloped: `I({3,2}1)` or `69 04 32 03 02 02` assuming
the other metadata is known from the context.
A bare `ELM` or `NZ` value would only contain a sequence of
single-enveloped `FIRST` values. To make that single-enveloped
we only prepend a TLV header.
In case we also have to convey the rest of the metadata, namely
the object id and the field, we have to use the double-enveloped
form. For a simple `map[string]string{"Key":"Value"}` that
looks like: `M({b0b-af0-3} S({0,0}"Key") S({0,0}"Value"))` or
`6D 15 36 03 00 af 00 0b 0b 73 04 30 4b 65 79 73 06 30 56 61 6c 75 65`
For FIRST values, there is no need to use two nested TLV
records, so a double-enveloped Integer looks like:
`I({b0b-af0-7}{3,2}1)`
Both pieces of metadata (id and timestamp) are Lamport
timestamps serialized as tiny `ZipIntUint64Pair`.
[x]: https://en.wikipedia.org/wiki/Causal_consistency
[v]: https://en.wikipedia.org/wiki/Version_vector
[r]: https://www.educative.io/answers/how-are-vector-clocks-used-in-dynamo
Expand Down

0 comments on commit 706f891

Please sign in to comment.