internal ContentDoc(YDoc doc) { if (doc._item != null) { throw new Exception("This document was already integrated as a sub-document. You should create a second instance instead with the same guid."); } Doc = doc; Opts = new YDocOptions(); if (!doc.Gc) { Opts.Gc = false; } if (doc.AutoLoad) { Opts.AutoLoad = true; } if (doc.Meta != null) { Opts.Meta = doc.Meta; } }
internal static ContentDoc Read(IUpdateDecoder decoder) { var guidStr = decoder.ReadString(); var opts = YDocOptions.Read(decoder); opts.Guid = guidStr; return(new ContentDoc(new YDoc(opts))); }
public YDoc RestoreDocument(YDoc originDoc, YDocOptions opts = null) { if (originDoc.Gc) { // We should try to restore a GC-ed document, because some of the restored items might have their content deleted. throw new Exception("originDoc must not be garbage collected"); } using var encoder = new UpdateEncoderV2(); originDoc.Transact(tr => { int size = StateVector.Count(kvp => kvp.Value /* clock */ > 0); encoder.RestWriter.WriteVarUint((uint)size); // Splitting the structs before writing them to the encoder. foreach (var kvp in StateVector) { int client = kvp.Key; int clock = kvp.Value; if (clock == 0) { continue; } if (clock < originDoc.Store.GetState(client)) { tr.Doc.Store.GetItemCleanStart(tr, new ID(client, clock)); } var structs = originDoc.Store.Clients[client]; var lastStructIndex = StructStore.FindIndexSS(structs, clock - 1); // Write # encoded structs. encoder.RestWriter.WriteVarUint((uint)(lastStructIndex + 1)); encoder.WriteClient(client); // First clock written is 0. encoder.RestWriter.WriteVarUint(0); for (int i = 0; i <= lastStructIndex; i++) { structs[i].Write(encoder, 0); } } DeleteSet.Write(encoder); }); var newDoc = new YDoc(opts ?? originDoc.CloneOptionsWithNewGuid()); newDoc.ApplyUpdateV2(encoder.ToArray(), transactionOrigin: "snapshot"); return(newDoc); }
/// <param name="gc">Disable garbage collection.</param> /// <param name="gcFilter">WIll be called before an Item is garbage collected. Return false to keep the item.</param> public YDoc(YDocOptions opts = null) { _opts = opts ?? new YDocOptions(); _transactionCleanups = new List <Transaction>(); ClientId = GenerateNewClientId(); _share = new Dictionary <string, AbstractType>(); Store = new StructStore(); Subdocs = new HashSet <YDoc>(); ShouldLoad = _opts.AutoLoad; }
internal static YDocOptions Read(IUpdateDecoder decoder) { var dict = (IDictionary <string, object>)decoder.ReadAny(); var result = new YDocOptions(); result.Gc = dict.ContainsKey("gc") ? (bool)dict["gc"] : true; result.Guid = dict.ContainsKey("guid") ? dict["guid"].ToString() : System.Guid.NewGuid().ToString("D"); result.Meta = dict.ContainsKey("meta") ? dict["meta"] as Dictionary <string, string> : null; result.AutoLoad = dict.ContainsKey("autoLoad") ? (bool)dict["autoLoad"] : false; return(result); }
protected void Init(int users = 5, YDocOptions options = null) { Users = new List <TestYInstance>(); Arrays = new Dictionary <TestYInstance, YArray>(); Maps = new Dictionary <TestYInstance, YMap>(); Texts = new Dictionary <TestYInstance, YText>(); Connector = new TestConnector(); for (int i = 0; i < users; i++) { var y = Connector.CreateY(i, options); Users.Add(y); Arrays[y] = y.GetArray("array"); Maps[y] = y.GetMap("map"); Texts[y] = y.GetText("text"); } Connector.SyncAll(); }
public TestYInstance(TestConnector connector, int clientId, YDocOptions options) : base(options) { ClientId = clientId; _tc = connector; _tc._allConns.Add(this); // Setup observe on local model. UpdateV2 += (s, e) => { if (e.origin != _tc) { using var stream = new MemoryStream(); SyncProtocol.WriteUpdate(stream, e.data); BroadcastMessage(this, stream.ToArray()); } }; Connect(); }
public TestYInstance CreateY(int clientId, YDocOptions options) { return(new TestYInstance(this, clientId, options)); }