Feature dcDb - Gadreel/divconq GitHub Wiki
Intro to dcDB
TODO add intro
Data Types & Codes
1 byte codes
-
0x00 = Alpha, marks boundaries between keys
-
0xff = Omega, marks end of database and database version
-
These have a sortable order, the rest not in any meaningful way
- 0x01 = Null/Empty
- 0x02 = Boolean
- 0x02 0x00 False
- 0x02 0x01 True
- 0x06 = Number (DB_TYPE_NUMBER)
- 1 byte is pos/neg flag
- 0x06 0x00 0xNN 0xNN etc neg number
- 0x06 0x01 0xNN 0xNN etc pos number
- 16 value bytes - 12 bytes before decimal and 4 bytes after
- official MAX/MIN before is 10,000,000,000,000,000,000,000,000,000 aka 10,000Y (where Y = yotta = septillion)
- official MAX/MIN after is 0.000,000,001 aka 1n (where n = nano = billionth)
- positive numbers are Little-endian
- negative numbers are Little-endian and XORed with all 0xFFs
- see examples below
- 1 byte is pos/neg flag
- 0x09 = DateTime (YYYYMMDDTHHMMSSsssZ)
- 0x09 0xNN 0xNN etc UTF 8 codes
- 0x0C = BigDateTime (tYYYYYYYYYYYMMDDhhmmss)
- 0x0C 0xNN 0xNN etc UTF 8 codes
- 0x0F = Time (HHMMSSsss)
- 0x0F 0xNN 0xNN etc UTF 8 codes
- 0x12 = Date (YYYYMMDD)
- 0x12 0xNN 0xNN etc UTF 8 codes
- 0x15 = Binary, indexes as Number (size in bytes)
- 0x15 0xNN 0xNN etc binary codes
- 0x18 = String encoded as UTF8 (codes not allowed 0x00 - 0x08, 0x0E - 0x1F, 0x7F), indexes as first 1024 bytes
- 0x18 0xNN 0xNN etc UTF 8 codes
- full text index option also
-
Value only, not sortable per say
- 0x1B = Special Number, indexes as Number (conversion)
- 0x1B 0xNN 0xNN etc bytes in BigDecimal
- 0x1E = Composite (JSON) - (special case of String), indexes as Number (size in bytes)
- 0x1E 0xNN 0xNN etc compact version of JSON, which can be directly output as response
- 0x1F = XML - (special case of String), indexes as Number (size in bytes)
- 0x1F 0xNN 0xNN etc bytes UTF 8 codes
- 0x1B = Special Number, indexes as Number (conversion)
DB_TYPE_NUMBER Examples
Note how the resulting numbers will sort correctly...
ByteUtil.longToDBNumber output
Long.MIN_VALUE: 00 ffffffff7fffffffffffffff ffffffff
-9999999999: 00 fffffffffffffffdabf41c00 ffffffff
-1000: 00 fffffffffffffffffffffc17 ffffffff
-1: 00 fffffffffffffffffffffffe ffffffff
1: 01 000000000000000000000001 00000000
1000: 01 0000000000000000000003e8 00000000
9999999999: 01 0000000000000002540be3ff 00000000
Long.MIN_VALUE: 01 000000007fffffffffffffff 00000000
ByteUtil.decimalToDBNumber output
DB_NUMBER_MIN: 00 dfb031a1c1dafd9eefffffff ffffffff
Long.MIN_VALUE: 00 ffffffff7fffffffffffffff ffffffff
-9999999999.999999999: 00 fffffffffffffffdabf41c00 c4653600
-9999999999: 00 fffffffffffffffdabf41c00 ffffffff
-1000.0001: 00 fffffffffffffffffffffc17 fffe795f
-1000: 00 fffffffffffffffffffffc17 ffffffff
-1.000000001: 00 fffffffffffffffffffffffe fffffffe
-1: 00 fffffffffffffffffffffffe ffffffff
-0.1: 00 ffffffffffffffffffffffff fa0a1eff
-0.0000000017: 00 ffffffffffffffffffffffff fffffffd
0.0000000017: 01 000000000000000000000000 00000002
0.1: 01 000000000000000000000000 05f5e100
1: 01 000000000000000000000001 00000000
1.000000001: 01 000000000000000000000001 00000001
1000: 01 0000000000000000000003e8 00000000
1000.0001: 01 0000000000000000000003e8 000186a0
9999999999: 01 0000000000000002540be3ff 00000000
9999999999.999999999: 01 0000000000000002540be3ff 3b9ac9ff
Long.MAX_VALUE: 01 000000007fffffffffffffff 00000000
DB_NUMBER_MAX: 01 204fce5e3e25026110000000 00000000
ByteUtil.dbNumberToNumber tests
DB_NUMBER_MIN: -10000000000000000000000000000
near MIN: -9999999999999999999999999999.999999999
-9999999999.999999999: -9999999999.999999999
-999999.9999: -999999.9999
-1000.01: -1000.01
-1.1: -1.1
1.1: 1.1
1000.01: 1000.01
999999.9999: 999999.9999
9999999999.999999999: 9999999999.999999999
near MAX: 9999999999999999999999999999.999999999
DB_NUMBER_MAX: 10000000000000000000000000000
Also
Long.MAX_VALUE: -9223372036854775808
-9999999999: -9999999999
-1000: -1000
-1: -1
1: 1
1000: 1000
9999999999: 9999999999
Long.MAX_VALUE: 9223372036854775807
Common Record Meta
DB_GLOBAL_RECORD_META, table, "Id" = last id seq
Domain Record Meta
DB_GLOBAL_RECORD_META, domain, table, "Count" = count
StaticScalar
DB_GLOBAL_RECORD, domain, table, id, field, stamp, "Data" = value - any db scalar type
DB_GLOBAL_RECORD, domain, table, id, field, stamp, "Tags" = | delim string w/ leading/trailing |
DB_GLOBAL_RECORD, domain, table, id, field, stamp, "Retired" = t/f
DB_GLOBAL_INDEX_1, domain, table, field, value = index count (approx number)
DB_GLOBAL_INDEX_1, domain, table, field, value, id, stamp = to stamp, null means always will be
StaticList
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "Data" = value - any db scalar type
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "Tags" = | delim string w/ leading/trailing |
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "Retired" = t/f
DB_GLOBAL_INDEX_2, domain, table, field, value = index count (approx number)
DB_GLOBAL_INDEX_2, domain, table, field, value, id, sid, stamp = to stamp, null means always will be
DynamicScalar
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "Data" = value - any db scalar type
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "From" = date time, null means always was
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "Tags" = | delim string w/ leading/trailing |
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "Retired" = t/f
DB_GLOBAL_INDEX_2, domain, table, field, value = index count (approx number)
DB_GLOBAL_INDEX_2, domain, table, field, value, id, sid, stamp = to stamp, null means always will be
DynamicList
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "Data" = value - any db scalar type
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "From" = date time, null means always was
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "To" = date time, null means always will be
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "Tags" = | delim string w/ leading/trailing |
DB_GLOBAL_RECORD, domain, table, id, field, sid, stamp, "Retired" = t/f
DB_GLOBAL_INDEX_2, domain, table, field, value = index count (approx number)
DB_GLOBAL_INDEX_2, domain, table, field, value, id, sid, stamp = to stamp, null means always will be
Index Example
keep in mind that stamp92 is newer (later date) than stamp98 or stamp107
Example Data
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 9, "Name", stamp46, "Data" = "Brian"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 9, "Name", stamp212, "Data" = "Ned"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Brian", 9, stamp46 = null (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = null (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92 DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 9, stamp212 = stamp46 DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
Example Search I
If searching for "Ned" on stamp96 we find the Neds:
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92 DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 9, stamp212 = stamp46
For each we must verify that the entry is current for the stamp:
Person 5 has a stamp98 and stamp92 and so stamp98 >= stamp96 > stamp92 - TRUE: therefore, for stamp96, "Ned" is correct Person 9 has a stamp212 and stamp46 and so stamp212 >= stamp96 > stamp46 - TRUE: therefore, for stamp96, "Ned" is correct
Example Search II
However, if searching for "Ned" on stamp86 we find the Neds:
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92 DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 9, stamp212 = stamp46
For each we must verify that the entry is current for the stamp:
Person 5 has a stamp98 and stamp92 and so stamp98 >= stamp86 > stamp92 - FALSE: therefore, for stamp86, "Ned" NOT is correct Person 9 has a stamp212 and stamp46 and so stamp212 >= stamp86 > stamp46 - TRUE: therefore, for stamp86, "Ned" is correct
Retired Field
The same results happen with retired fields. What if we retired instead of changed the name of Person 5 at stamp92? Here is what the record would look like for 5:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Retired" = true
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
And here is what the index would look like for 5:
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92 DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
Again we can see that searching the index for stamp96 and "Ned" still provides Person 5 as a result and searching with stamp86 does not.
Indexing Operation
Typical Future Set
Here is what we have for Person 5:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
And we are setting name to "Jed" for stamp92 (future, after stamp98 in time but before in collation).
- SET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
- find the next, older, stamp after current
- NEXT PEER on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92 results in stamp98
- take stamp98 and check for old value
- IS SET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" results in TRUE [NODE]
- take stamp98 and look up the old value
- GET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" results in "Ned"
- now read the stamp from the old index
- GET on DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 results in NULL
- now set the new index with the value returned above
- SET on DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = NULL (future)
- finally update the old index with current stamp
- SET on DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92
And now we have:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92 DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
Typical Future Retire
Here is what we have for Person 5:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
And we are retiring name for stamp92 (future, after stamp98 in time but before in collation).
- SET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Retired" = TRUE
- find the next, older, stamp after current
- NEXT PEER on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92 results in stamp98
- take stamp98 and check for old value
- IS SET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" results in TRUE [NODE]
- take stamp98 and look up the old value
- GET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" results in "Ned"
- now read the stamp from the old index
- GET on DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 results in NULL
- finally update the old index with current stamp
- SET on DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92
And now we have:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Retired" = true
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92 DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
Replicate Between Set
Here is what we have for Person 5 - on Hub A:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp92
And replicating (slowly) - is a stamp between stamp92 and stamp107 - this is from Hub B:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
We are setting name to "Ned" for stamp98.
- SET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
- find the next, older, stamp after current
- NEXT PEER on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98 results in stamp107
- take stamp107 and check for old value
- IS SET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" results in TRUE [NODE]
- take stamp107 and look up the old value
- GET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" results in "Ted"
- now read the stamp from the old index
- GET on DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 results in stamp92
- now set the new index with the value returned above
- SET on DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92
- finally update the old index with current stamp
- SET on DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
And now we have:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92 DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
Replicate End Set
Here is what we have for Person 5 - on Hub A:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92
And replicating (slowly) - is a stamp before stamp92 and stamp98 - this is from Hub B:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
We are setting name to "Ted" for stamp107.
- SET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
- find the next, older, stamp after current
- NEXT PEER on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107 results in NULL
- the NULL is not conclusive, look forward in time
- PREV PEER on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107 results in stamp98
- now set the new index with the value returned above
- SET on DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
And now we have:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92 DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
Replicate Between Retire
Here is what we have for Person 5 - on Hub A:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp92
And replicating (slowly) - is a stamp between stamp92 and stamp107 - this is from Hub B:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Retired" = TRUE
We are setting name to retired for stamp98.
- SET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Retired" = true
- find the next, older, stamp after current
- NEXT PEER on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98 results in stamp107
- take stamp107 and check for old value
- IS SET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" results in TRUE [NODE]
- take stamp107 and look up the old value
- GET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" results in "Ted"
- finally update the old index with current stamp
- SET on DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
And now we have:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Retired" = TRUE
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Data" = "Ted"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ted", 5, stamp107 = stamp98
Replicate End Retire
Here is what we have for Person 5 - on Hub A:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92
And replicating (slowly) - is a stamp before (in time, not collation) stamp92 and stamp98 - this is from Hub B:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Retired" = TRUE
We are setting name to retired for stamp107.
- SET on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Retired" = TRUE
- find the next, older, stamp after current
- NEXT PEER on DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107 results in NULL
- the NULL is enough, nothing more to do
And now we have:
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp92, "Data" = "Jed"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp98, "Data" = "Ned"
DB_GLOBAL_RECORD, ROOT_DOMAIN, "Person", 5, "Name", stamp107, "Retired" = TRUE
DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Jed", 5, stamp92 = NULL (future) DB_GLOBAL_INDEX_1, ROOT_DOMAIN, "Person", "Name", "Ned", 5, stamp98 = stamp92