Exemple #1
0
        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);
        }