Platform Manual
Data Types
Register
to start building your mental model, think of a crdt as a container holding two essential components the actual data to store and some metadata that helps in resolving conflicts representing the actual data the register type holds the actual data to be stored; each set of fields in a document or key‑value pair embedded in a map function as a single register object for example, the following snippet consists of three separate registers field property value crdt name 'frank' register ( string ) age 31 register ( number ) ownedcars 0 counter ( number ) let docid = try ditto store\["people"] upsert(\[ "name" "frank", "age" 31, "ownedcars" dittocounter()val docid = ditto store\["people"] upsert(mapof( "name" to "frank", "ownedcars" to dittocounter() )) ditto store collection("people") findbyid(docid) update { mutabledoc > mutabledoc!!\["ownedcars"] counter!! increment(amount = 1 0) }const docid = await ditto store collection('people') upsert({ name 'frank', age 31, ownedcars 0, })map\<string, object> content = new hashmap<>(); content put("name", "frank"); content put("ownedcars", new dittocounter()); dittodocumentid docid = ditto store collection("people") upsert(content); ditto store collection("people") findbyid(docid) update(mutdoc > { assertthat(mutdoc) isnotnull(); dittomutablecounter counter = mutdoc get("ownedcars") getcounter(); assertthat(counter) isnotnull(); counter increment(1); });var content = new dictionary\<string, object> { { "name", "frank" }, { "age", 31 }, { "ownedcars", new dittocounter() } };json person = json({{"name", "frank"}, {"age", 31}, {"ownedcars", 0}); documentid doc id = ditto get store() collection("people") upsert(person);let doc id = ditto store collection("people") upsert( hashmap! { "name" => "frank", "age" => 31, "ownedcars" => 0, }, ); since each set of fields in a document and, if embedded within a map , each key value pair acts as a single register , you can structure, organize, and manage your data more efficiently you can encode simple data as well as highly complex datasets in a register to encode simple data in a registers , use primitive json compatible types, such as string , boolean , number , and so on to encode more complex datasets in a register , use a combination of primitive types and register and maps the following table provides an overview of the types you can use to store a single value in a register data type corresponding values array an ordered list of values, where each value represents any primitive type, as well as nested collection types such as other arrays or maps boolean true or false float 64 bit floating point map embedded document object null represents an absence of a value int signed 64 bit integer string utf 8 encodable unsigned int unsigned 64 bit integer merging with last writer wins semantics each register adheres to the last writer wins principle at merge, ensuring conflict free replication and data consistency throughout the distributed system with last writer wins merge semantics, when conflicting updates occur, the update made by the last writer always takes precedence and propagates across peers as the single source of truth — the definitive value for example, one flight attendant updates a customer's seat number to 6 and another to seat 9 when two conflicting versions merge, the edit with the highest timestamp wins array an extension to the register type, an array is an ordered collection of items represented using any primitive json‑compatible data type enclosed within square brackets (\[ ]) avoid using arrays in ditto due to potential merge conflicts when offline peers reconnect to the mesh and attempt to sync their updates, especially when multiple peers make concurrent updates to the same item within the array limitations to arrays crdt based arrays , when compared to typical arrays , have certain strengths and limitations while crdts excel at managing unordered operations, maintaining a strict order is less efficient, which could potentially lead to data inconsistencies at merge the reason for this is because, unlike traditional arrays , the multiple elements within a crdt based array function collectively as a single register , and, as previously explained in docid\ rb3wd2jhenojpw8xuirfy , a register is effectively a container that holds multiple elements — the actual data and various metadata — just like regular arrays in simple terms, imagine an array like a string much like a string , each element in a crdt based array plays a unique role in determining the final value that ultimately forms; just like the string characters that eventually form a word similar to how you access elements in a typical array , you reference each individual element in a crdt based array (a register ) by their index if those indexes change while disconnected from the network, once network conditions improve, they may fail to merge due to concurrency conflicts, resulting in data inconsistencies considering this, avoid using arrays in ditto and opt for a map instead, which effectively functions as a set, more commonly known as an associative array using a map instead of an array when managing data that requires unique identifiers and relationships, instead of using an array to encode your data, use a map with unique string keys and object values instead for example, instead of representing an array of cars, where each element represents a car { "cars" \[ {"make" "toyota", "model" "camry", "year" 2022}, {"make" "honda", "model" "civic", "year" 2021}, {"make" "ford", "model" "mustang", "year" 2023} ] } implement a map instead { "cars" { "car1" {"make" "toyota", "model" "camry", "year" 2022}, "car2" {"make" "honda", "model" "civic", "year" 2021}, "car3" {"make" "ford", "model" "mustang", "year" 2023} } }