private void Delete(DocumentsOperationContext context, Slice lowerId, Slice idSlice, string id, CollectionName collectionName, BlittableJsonReaderObject deleteRevisionDocument, string changeVector, long lastModifiedTicks, NonPersistentDocumentFlags nonPersistentFlags, DocumentFlags flags) { Debug.Assert(changeVector != null, "Change vector must be set"); if (flags.Contain(DocumentFlags.HasAttachments)) { flags &= ~DocumentFlags.HasAttachments; } var configuration = GetRevisionsConfiguration(collectionName.Name, flags); if (configuration.Disabled) { return; } var table = EnsureRevisionTableCreated(context.Transaction.InnerTransaction, collectionName); if (configuration.PurgeOnDelete) { using (GetKeyPrefix(context, lowerId, out Slice prefixSlice)) { DeleteRevisions(context, table, prefixSlice, collectionName, long.MaxValue, null, changeVector, lastModifiedTicks); DeleteCountOfRevisions(context, prefixSlice); } return; } var fromReplication = (nonPersistentFlags & NonPersistentDocumentFlags.FromReplication) == NonPersistentDocumentFlags.FromReplication; if (fromReplication) { void DeleteFromRevisionIfChangeVectorIsGreater() { TableValueReader tvr; try { var hasDoc = _documentsStorage.GetTableValueReaderForDocument(context, lowerId, throwOnConflict: true, tvr: out tvr); if (hasDoc == false) { return; } } catch (DocumentConflictException) { // Do not modify the document. return; } var docChangeVector = TableValueToChangeVector(context, (int)DocumentsTable.ChangeVector, ref tvr); if (ChangeVectorUtils.GetConflictStatus(changeVector, docChangeVector) == ConflictStatus.Update) { _documentsStorage.Delete(context, lowerId, id, null, lastModifiedTicks, changeVector, collectionName, nonPersistentFlags | NonPersistentDocumentFlags.FromRevision); } } DeleteFromRevisionIfChangeVectorIsGreater(); } var newEtag = _database.DocumentsStorage.GenerateNextEtag(); var newEtagSwapBytes = Bits.SwapBytes(newEtag); using (table.Allocate(out TableValueBuilder tvb)) using (Slice.From(context.Allocator, changeVector, out var cv)) { tvb.Add(cv.Content.Ptr, cv.Size); tvb.Add(lowerId); tvb.Add(SpecialChars.RecordSeparator); tvb.Add(newEtagSwapBytes); tvb.Add(idSlice); tvb.Add(deleteRevisionDocument.BasePointer, deleteRevisionDocument.Size); tvb.Add((int)(DocumentFlags.DeleteRevision | flags)); tvb.Add(newEtagSwapBytes); tvb.Add(lastModifiedTicks); tvb.Add(context.GetTransactionMarker()); if (flags.Contain(DocumentFlags.Resolved)) { tvb.Add((int)DocumentFlags.Resolved); } else { tvb.Add(0); } tvb.Add(Bits.SwapBytes(lastModifiedTicks)); var isNew = table.Set(tvb); if (isNew == false) { // It might be just an update from replication as we call this twice, both for the doc delete and for deleteRevision. return; } } DeleteOldRevisions(context, table, lowerId, collectionName, configuration, nonPersistentFlags, changeVector, lastModifiedTicks); }