예제 #1
0
        public DocumentConflict GetConflictForChangeVector(
            DocumentsOperationContext context,
            string id,
            LazyStringValue changeVector)
        {
            var conflictsTable = context.Transaction.InnerTransaction.OpenTable(ConflictsSchema, ConflictsSlice);

            using (DocumentIdWorker.GetSliceFromId(context, id, out Slice lowerId))
                using (GetConflictsIdPrefix(context, lowerId, out Slice prefixSlice))
                {
                    foreach (var tvr in conflictsTable.SeekForwardFrom(ConflictsSchema.Indexes[IdAndChangeVectorSlice], prefixSlice, 0, true))
                    {
                        var currentChangeVector = TableValueToChangeVector(context, (int)ConflictsTable.ChangeVector, ref tvr.Result.Reader);
                        if (changeVector.CompareTo(currentChangeVector) == 0)
                        {
                            var dataPtr = tvr.Result.Reader.Read((int)ConflictsTable.Data, out int size);
                            var doc     = size == 0 ? null : new BlittableJsonReaderObject(dataPtr, size, context);
                            DebugDisposeReaderAfterTransaction(context.Transaction, doc);
                            return(new DocumentConflict
                            {
                                ChangeVector = currentChangeVector,
                                Id = context.AllocateStringValue(id, tvr.Result.Reader.Read((int)ConflictsTable.Id, out size), size),
                                StorageId = tvr.Result.Reader.Id,
                                //size == 0 --> this is a tombstone conflict
                                Doc = doc
                            });
                        }
                    }
                }
            return(null);
        }
예제 #2
0
        private unsafe string ReadType()
        {
            if (UnmanagedJsonParserHelper.Read(_peepingTomStream, _parser, _state, _buffer) == false)
            {
                UnmanagedJsonParserHelper.ThrowInvalidJson("Unexpected end of object when reading type", _peepingTomStream, _parser);
            }

            if (_state.CurrentTokenType == JsonParserToken.EndObject)
            {
                return(null);
            }

            if (_state.CurrentTokenType != JsonParserToken.String)
            {
                UnmanagedJsonParserHelper.ThrowInvalidJson("Expected property type to be string, but was " + _state.CurrentTokenType, _peepingTomStream, _parser);
            }

            return(_context.AllocateStringValue(null, _state.StringBuffer, _state.StringSize).ToString());
        }
예제 #3
0
        protected unsafe void SetLazyStringValue(DocumentsOperationContext context, ref LazyStringValue prop)
        {
            var size = *(int *)Reader.ReadExactly(sizeof(int));

            if (size < 0)
            {
                return;
            }

            if (size == 0)
            {
                prop = context.Empty;
                return;
            }

            var mem = Reader.AllocateMemory(size);

            Memory.Copy(mem, Reader.ReadExactly(size), size);
            prop = context.AllocateStringValue(null, mem, size);
        }
예제 #4
0
        public unsafe void HandleConflictForDocument(
            DocumentsOperationContext documentsContext,
            string id,
            string collection,
            long lastModifiedTicks,
            BlittableJsonReaderObject doc,
            string changeVector,
            DocumentFlags flags)
        {
            if (id.StartsWith(HiLoHandler.RavenHiloIdPrefix, StringComparison.OrdinalIgnoreCase))
            {
                HandleHiloConflict(documentsContext, id, doc, changeVector);
                return;
            }

            if (TryResolveIdenticalDocument(
                    documentsContext,
                    id,
                    doc,
                    lastModifiedTicks,
                    changeVector))
            {
                return;
            }

            var lazyId = documentsContext.GetLazyString(id);

            using (DocumentIdWorker.GetLower(documentsContext.Allocator, lazyId, out var loweredKey))
            {
                var conflictedDoc = new DocumentConflict
                {
                    Doc        = doc,
                    Collection = documentsContext.GetLazyStringForFieldWithCaching(
                        collection ??
                        CollectionName.GetCollectionName(doc)
                        ),
                    LastModified = new DateTime(lastModifiedTicks),
                    LowerId      = documentsContext.AllocateStringValue(null, loweredKey.Content.Ptr, loweredKey.Content.Length),
                    Id           = lazyId,
                    ChangeVector = changeVector,
                    Flags        = flags
                };

                if (TryResolveConflictByScript(
                        documentsContext,
                        conflictedDoc))
                {
                    return;
                }

                if (_conflictResolver.ConflictSolver?.ResolveToLatest ?? true)
                {
                    var conflicts = new List <DocumentConflict>
                    {
                        conflictedDoc.Clone()
                    };
                    conflicts.AddRange(_database.DocumentsStorage.ConflictsStorage.GetConflictsFor(documentsContext, id));

                    var localDocumentTuple = _database.DocumentsStorage.GetDocumentOrTombstone(documentsContext, id, false);
                    var local = DocumentConflict.From(documentsContext, localDocumentTuple.Document) ?? DocumentConflict.From(localDocumentTuple.Tombstone);
                    if (local != null)
                    {
                        conflicts.Add(local);
                    }

                    var resolved = _conflictResolver.ResolveToLatest(conflicts);
                    _conflictResolver.PutResolvedDocument(documentsContext, resolved, resolvedToLatest: true, conflictedDoc);

                    return;
                }

                _database.DocumentsStorage.ConflictsStorage.AddConflict(documentsContext, id, lastModifiedTicks, doc, changeVector, collection, flags);
            }
        }