public IEnumerable <IndexConflictEntry> GetConflictsFor(Transaction tx, TransactionOperationContext context, string name, int start, int take) { int taken = 0; int skipped = 0; var table = tx.OpenTable(ConflictsTableSchema, SchemaNameConstants.ConflictMetadataTable); Debug.Assert(table != null); Slice nameSlice; using (DocumentKeyWorker.GetSliceFromKey(context, name, out nameSlice)) { foreach (var seekResult in table.SeekForwardFrom(ConflictsTableSchema.Indexes[NameAndEtagIndexName], nameSlice, true)) { foreach (var tvr in seekResult.Results) { if (start > skipped) { skipped++; continue; } if (taken++ >= take) { yield break; } yield return(TableValueToConflict(tvr, context)); } } } }
public IReadOnlyList <ChangeVectorEntry[]> DeleteConflictsFor(Transaction tx, TransactionOperationContext context, string name) { Slice nameSlice; using (DocumentKeyWorker.GetSliceFromKey(context, name, out nameSlice)) return(DeleteConflictsFor(tx, nameSlice)); }
public void AddConflict(TransactionOperationContext context, Transaction tx, string name, IndexEntryType type, ChangeVectorEntry[] changeVector, BlittableJsonReaderObject definition) { if (!TrySetConflictedByName(context, tx, name)) { throw new InvalidOperationException($"When trying to add a conflict on {type} {name}, we couldn't find {name} in the index metadata. Shouldn't happen and likely a bug."); } var conflictsTable = tx.OpenTable(ConflictsTableSchema, SchemaNameConstants.ConflictMetadataTable); var metadataTable = tx.OpenTable(IndexesTableSchema, SchemaNameConstants.IndexMetadataTable); Slice indexNameAsSlice; var newEtag = GetNewEtag(metadataTable); var bitSwappedEtag = Bits.SwapBytes(newEtag); using (DocumentKeyWorker.GetSliceFromKey(context, name, out indexNameAsSlice)) { fixed(ChangeVectorEntry *pChangeVector = changeVector) { byte byteAsType = (byte)type; conflictsTable.Set(new TableValueBuilder { indexNameAsSlice, {&bitSwappedEtag, sizeof(long) }, {&byteAsType, sizeof(byte) }, { (byte *)pChangeVector, sizeof(ChangeVectorEntry) * changeVector.Length }, { definition.BasePointer, definition.Size } }); } } }
public IndexEntryMetadata GetIndexMetadataByName <TTransaction>(Transaction tx, TransactionOperationContext <TTransaction> context, string name, bool returnNullIfTombstone = true) where TTransaction : RavenTransaction { var table = tx.OpenTable(IndexesTableSchema, SchemaNameConstants.IndexMetadataTable); Debug.Assert(table != null); Slice nameAsSlice; TableValueReader tvr; using (DocumentKeyWorker.GetSliceFromKey(context, name, out nameAsSlice)) tvr = table.ReadByKey(nameAsSlice); return(tvr == null ? null : TableValueToMetadata(tvr, context, returnNullIfTombstone)); }
public bool TrySetConflictedByName(TransactionOperationContext context, Transaction tx, string name) { var table = tx.OpenTable(IndexesTableSchema, SchemaNameConstants.IndexMetadataTable); Debug.Assert(table != null); TableValueReader tvr; Slice nameAsSlice; using (DocumentKeyWorker.GetSliceFromKey(context, name, out nameAsSlice)) tvr = table.ReadByKey(nameAsSlice); if (tvr == null) { return(false); } var metadata = TableValueToMetadata(tvr, context, false); WriteEntry(tx, name, metadata.Type, metadata.Id, context, isConflicted: true, allowOverwrite: true); return(true); }
private long WriteEntry(Transaction tx, string indexName, IndexEntryType type, int indexIndexId, TransactionOperationContext context, bool isConflicted = false, bool allowOverwrite = false, ChangeVectorEntry[] changeVector = null) { var table = tx.OpenTable(IndexesTableSchema, SchemaNameConstants.IndexMetadataTable); Debug.Assert(table != null); var newEtag = GetNewEtag(table); Slice nameAsSlice; IndexEntryMetadata existing = null; ChangeVectorEntry[] changeVectorForWrite; using (DocumentKeyWorker.GetSliceFromKey(context, indexName, out nameAsSlice)) { var tvr = table.ReadByKey(nameAsSlice); //SetIndexTransformerChangeVectorForLocalChange also merges vectors if conflicts exist changeVectorForWrite = SetIndexTransformerChangeVectorForLocalChange(tx, context, nameAsSlice, tvr, newEtag, changeVector); if (tvr != null) { existing = TableValueToMetadata(tvr, context, false); } } //precautions if (changeVectorForWrite == null) { throw new ArgumentException("changeVector == null, should not be so"); } Slice indexNameAsSlice; using (DocumentKeyWorker.GetSliceFromKey(context, indexName, out indexNameAsSlice)) { if (!allowOverwrite) { ThrowIfAlreadyExistsAndOverwriting(indexName, type, indexIndexId, table, indexNameAsSlice, existing); } fixed(ChangeVectorEntry *pChangeVector = changeVectorForWrite) { var bitSwappedEtag = Bits.SwapBytes(newEtag); var bitSwappedId = Bits.SwapBytes(indexIndexId); table.Set(new TableValueBuilder { { (byte *)&bitSwappedId, sizeof(int) }, { (byte *)&bitSwappedEtag, sizeof(long) }, indexNameAsSlice, { (byte *)&type, sizeof(byte) }, { (byte *)pChangeVector, sizeof(ChangeVectorEntry) * changeVectorForWrite.Length }, { (byte *)&isConflicted, sizeof(bool) } }); } } MergeEntryVectorWithGlobal(tx, context.Allocator, changeVectorForWrite); return(newEtag); }