Flip Internal Design

Commit Cycle

This chapter describes how the whole commit cycle is managed.

Data Tree

The data tree, starting from the root class, has a double reprensentation in flip. Each type keeps track of its current value as well as its old value.

Instead of having two different trees, old and current value are maintained in-place in the tree structure. This means for example that a value type will hold its old and current value. Container types will do approximatively the same, by keeping track what was added and what was removed.

When a type is changed, a message is sent up to the root to maintain a modification count for each node. This allows to know how many changes are in each node (and children nodes if any), so that the tree can be traversed faster while observing or building the transaction.

If a type is changed twice so that it gets back to its original value (for example setting a value type from 0 to 2 and then back to 0, or inserting an element in a container and erase it), flip will detect it and will change the modification count accordingly, so that this double change is equivalent to no operation.

If a type is changed twice so that it gets to another value (for example setting a value type from 0 to 2 and then from 2 to 3), flip will dectect it and will not change the modification count the second time.

The modification count value can be fetched for every type using impl_get_total_modification_cnt.

Commit

Note: For clarity, the figure above does not take into account multi-document handling through a Hub

When a user calls commit on the document, Flip will first run the validation code to make sure that the client is not corrupting the state of the document.

If the document is not valid, Flip will revert it to put it back in the same state before commit was called and throw an exception. In particular, the document is valid again.

If the document is still valid, Flip will then call the document observer.

Then the transaction is built. To do that, the document will ask the root of the document to fill in a transaction, and each object will recursively ask its children to fill in the transaction. For this process to be faster, only nodes with a positive modification count are considered.

This transaction is then put on the push stack, as well as on the transaction stack. The push stack contains all transaction stacks ready to be sent to an upstream if any. The transaction stack keeps track of latent/pending transactions. The transaction stack mechanisms are described in the chapter The Transaction Stack.

Finally the document is synchronized, meaning that the old representation of the data tree is set to match its new representation, and modification counts are reset to 0.