public void ErrorsOnInvalidSchemaWithMultipleIndexes() { using (var tx = Env.WriteTransaction()) { var expectedSchema = new TableSchema(); var def = new TableSchema.SchemaIndexDef { Count = 3, StartIndex = 2, }; Slice.From(tx.Allocator, "Test Name", ByteStringType.Immutable, out def.Name); expectedSchema.DefineIndex(def); var actualSchema = new TableSchema(); actualSchema.DefineIndex(def); expectedSchema.Validate(actualSchema); def = new TableSchema.SchemaIndexDef { StartIndex = 4, }; Slice.From(tx.Allocator, "Bad Test Name", ByteStringType.Immutable, out def.Name); actualSchema.DefineIndex(def); Assert.Throws <ArgumentNullException>(delegate { expectedSchema.Validate(null); }); Assert.Throws <ArgumentException>(delegate { expectedSchema.Validate(actualSchema); }); } }
static ConflictsStorage() { using (StorageEnvironment.GetStaticContext(out var ctx)) { Slice.From(ctx, "ChangeVector", ByteStringType.Immutable, out ChangeVectorSlice); Slice.From(ctx, "ConflictsId", ByteStringType.Immutable, out ConflictsIdSlice); Slice.From(ctx, "IdAndChangeVector", ByteStringType.Immutable, out IdAndChangeVectorSlice); Slice.From(ctx, "AllConflictedDocsEtags", ByteStringType.Immutable, out AllConflictedDocsEtagsSlice); Slice.From(ctx, "ConflictedCollection", ByteStringType.Immutable, out ConflictedCollectionSlice); Slice.From(ctx, "Conflicts", ByteStringType.Immutable, out ConflictsSlice); } /* * The structure of conflicts table starts with the following fields: * [ Conflicted Doc Id | Separator | Change Vector | ... the rest of fields ... ] * PK of the conflicts table will be 'Change Vector' field, because when dealing with conflicts, * the change vectors will always be different, hence the uniqueness of the ID. (inserts/updates will not overwrite) * * Additional index is set to have composite ID of 'Conflicted Doc Id' and 'Change Vector' so we will be able to iterate * on conflicts by conflicted doc id (using 'starts with') * * We need a separator in order to delete all conflicts all "users/1" without deleting "users/11" conflicts. */ ConflictsSchema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = (int)ConflictsTable.ChangeVector, Count = 1, IsGlobal = false, Name = ChangeVectorSlice }); // required to get conflicts by ID ConflictsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)ConflictsTable.LowerId, Count = 3, IsGlobal = false, Name = IdAndChangeVectorSlice }); ConflictsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)ConflictsTable.LowerId, Count = 1, IsGlobal = true, Name = ConflictsIdSlice }); ConflictsSchema.DefineFixedSizeIndex(new TableSchema.FixedSizeSchemaIndexDef { StartIndex = (int)ConflictsTable.Etag, IsGlobal = true, Name = AllConflictedDocsEtagsSlice }); ConflictsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)ConflictsTable.Collection, Count = 1, IsGlobal = true, Name = ConflictedCollectionSlice }); }
static TimeSeriesStats() { using (StorageEnvironment.GetStaticContext(out ByteStringContext ctx)) { Slice.From(ctx, RawTimeSeriesPolicy.PolicyString, SpecialChars.RecordSeparator, ByteStringType.Immutable, out RawPolicySlice); Slice.From(ctx, nameof(TimeSeriesStatsKey), ByteStringType.Immutable, out TimeSeriesStatsKey); Slice.From(ctx, nameof(PolicyIndex), ByteStringType.Immutable, out PolicyIndex); Slice.From(ctx, nameof(StartTimeIndex), ByteStringType.Immutable, out StartTimeIndex); } TimeSeriesStatsSchema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = (int)StatsColumns.Key, Count = 1, Name = TimeSeriesStatsKey, IsGlobal = true }); TimeSeriesStatsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)StatsColumns.PolicyName, Name = PolicyIndex }); TimeSeriesStatsSchema.DefineIndex(new TableSchema.SchemaIndexDef { // policy, separator, start StartIndex = (int)StatsColumns.PolicyName, Count = 2, Name = StartTimeIndex }); }
static RevisionsStorage() { using (StorageEnvironment.GetStaticContext(out var ctx)) { Slice.From(ctx, "RevisionsChangeVector", ByteStringType.Immutable, out var changeVectorSlice); Slice.From(ctx, "RevisionsIdAndEtag", ByteStringType.Immutable, out IdAndEtagSlice); Slice.From(ctx, "DeleteRevisionEtag", ByteStringType.Immutable, out DeleteRevisionEtagSlice); Slice.From(ctx, "AllRevisionsEtags", ByteStringType.Immutable, out AllRevisionsEtagsSlice); Slice.From(ctx, "CollectionRevisionsEtags", ByteStringType.Immutable, out CollectionRevisionsEtagsSlice); Slice.From(ctx, "RevisionsCount", ByteStringType.Immutable, out RevisionsCountSlice); Slice.From(ctx, nameof(ResolvedFlagByEtagSlice), ByteStringType.Immutable, out ResolvedFlagByEtagSlice); Slice.From(ctx, RevisionsTombstones, ByteStringType.Immutable, out RevisionsTombstonesSlice); Slice.From(ctx, CollectionName.GetTablePrefix(CollectionTableType.Revisions), ByteStringType.Immutable, out RevisionsPrefix); RevisionsSchema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = (int)RevisionsTable.ChangeVector, Count = 1, Name = changeVectorSlice, IsGlobal = true }); RevisionsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)RevisionsTable.LowerId, Count = 3, Name = IdAndEtagSlice, IsGlobal = true }); RevisionsSchema.DefineFixedSizeIndex(new TableSchema.FixedSizeSchemaIndexDef { StartIndex = (int)RevisionsTable.Etag, Name = AllRevisionsEtagsSlice, IsGlobal = true }); RevisionsSchema.DefineFixedSizeIndex(new TableSchema.FixedSizeSchemaIndexDef { StartIndex = (int)RevisionsTable.Etag, Name = CollectionRevisionsEtagsSlice }); RevisionsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)RevisionsTable.DeletedEtag, Count = 1, Name = DeleteRevisionEtagSlice, IsGlobal = true }); RevisionsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)RevisionsTable.Resolved, Count = 2, Name = ResolvedFlagByEtagSlice, IsGlobal = true }); } }
static RevisionsStorage() { Slice.From(StorageEnvironment.LabelsContext, "RevisionsChangeVector", ByteStringType.Immutable, out var changeVectorSlice); Slice.From(StorageEnvironment.LabelsContext, "RevisionsIdAndEtag", ByteStringType.Immutable, out IdAndEtagSlice); Slice.From(StorageEnvironment.LabelsContext, "RevisionsFlagsAndEtag", ByteStringType.Immutable, out FlagsAndEtagSlice); Slice.From(StorageEnvironment.LabelsContext, "AllRevisionsEtags", ByteStringType.Immutable, out AllRevisionsEtagsSlice); Slice.From(StorageEnvironment.LabelsContext, "CollectionRevisionsEtags", ByteStringType.Immutable, out CollectionRevisionsEtagsSlice); Slice.From(StorageEnvironment.LabelsContext, "RevisionsCount", ByteStringType.Immutable, out RevisionsCountSlice); Slice.From(StorageEnvironment.LabelsContext, RevisionsTombstones, ByteStringType.Immutable, out RevisionsTombstonesSlice); var deleteRevision = DocumentFlags.DeleteRevision; Slice.From(StorageEnvironment.LabelsContext, (byte *)&deleteRevision, sizeof(DocumentFlags), ByteStringType.Immutable, out DeleteRevisionSlice); DocsSchema = new TableSchema() { TableType = (byte)TableType.Revisions }; DocsSchema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = (int)Columns.ChangeVector, Count = 1, Name = changeVectorSlice, IsGlobal = true }); DocsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)Columns.LowerId, Count = 3, Name = IdAndEtagSlice, IsGlobal = true }); DocsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)Columns.Flags, Count = 2, Name = FlagsAndEtagSlice, IsGlobal = true }); DocsSchema.DefineFixedSizeIndex(new TableSchema.FixedSizeSchemaIndexDef { StartIndex = (int)Columns.Etag, Name = AllRevisionsEtagsSlice, IsGlobal = true }); DocsSchema.DefineFixedSizeIndex(new TableSchema.FixedSizeSchemaIndexDef { StartIndex = (int)Columns.Etag, Name = CollectionRevisionsEtagsSlice }); }
static From40011() { using (StorageEnvironment.GetStaticContext(out var ctx)) { Slice.From(ctx, "Items", out Items); Slice.From(ctx, "CertificatesSlice", out CertificatesSlice); Slice.From(ctx, "CertificatesHashSlice", out CertificatesHashSlice); } ItemsSchema = new TableSchema(); ItemsSchema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = 0, Count = 1 }); CertificatesSchema = new TableSchema(); CertificatesSchema.DefineKey(new TableSchema.SchemaIndexDef() { StartIndex = (int)CertificatesTable.Key, Count = 1, IsGlobal = false, Name = CertificatesSlice }); CertificatesSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)CertificatesTable.Hash, Count = 1, IsGlobal = false, Name = CertificatesHashSlice }); }
private static Tree GetNewErrorTimestampsTreeFromErrorsTable(UpdateStep step, Slice errorTimestampsSlice) { var newTableSchema = new TableSchema(); var indexDef = new TableSchema.SchemaIndexDef { StartIndex = 0, IsGlobal = false, Name = errorTimestampsSlice }; newTableSchema.DefineIndex(indexDef); newTableSchema.Create(step.WriteTx, "Errors", 16); var newErrorsTable = step.WriteTx.OpenTable(newTableSchema, "Errors"); var newErrorsTableTableTree = step.WriteTx.ReadTree("Errors", RootObjectType.Table); byte *ptr; using (var indexTree = Tree.Create(step.WriteTx.LowLevelTransaction, step.WriteTx, indexDef.Name, isIndexTree: true)) { using (newErrorsTableTableTree.DirectAdd(indexDef.Name, sizeof(TreeRootHeader), out ptr)) { indexTree.State.CopyTo((TreeRootHeader *)ptr); } } var newErrorTimestampsIndexTree = newErrorsTable.GetTree(newTableSchema.Indexes[errorTimestampsSlice]); return(newErrorTimestampsIndexTree); }
static RachisLogHistory() { using (StorageEnvironment.GetStaticContext(out var ctx)) { Slice.From(ctx, "LogHistory", out LogHistorySlice); Slice.From(ctx, "LogHistoryIndex", out LogHistoryIndexSlice); Slice.From(ctx, "LogHistoryDateTime", out LogHistoryDateTimeSlice); } LogHistoryTable = new TableSchema(); LogHistoryTable.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = (int)LogHistoryColumn.Guid, }); LogHistoryTable.DefineIndex(new TableSchema.SchemaIndexDef { Name = LogHistoryIndexSlice, StartIndex = (int)LogHistoryColumn.Index, Count = 1 }); LogHistoryTable.DefineFixedSizeIndex(new TableSchema.FixedSizeSchemaIndexDef { Name = LogHistoryDateTimeSlice, StartIndex = (int)LogHistoryColumn.Ticks }); }
private static Table GetOldErrorsTable(UpdateStep step, Slice errorTimestampsSlice, out TableSchema oldTableSchema) { oldTableSchema = new TableSchema(); oldTableSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 0, IsGlobal = true, Name = errorTimestampsSlice }); var oldErrorsTable = step.ReadTx.OpenTable(oldTableSchema, "Errors"); return(oldErrorsTable); }
private unsafe void CreateSchema(DocumentDatabase documentDatabase) { _errorsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 0, // there is just a single instance of this table // but we need it to be local so we'll be able to compact it IsGlobal = false, Name = IndexSchema.ErrorTimestampsSlice }); using (_contextPool.AllocateOperationContext(out TransactionOperationContext context)) using (var tx = context.OpenWriteTransaction()) { _errorsSchema.Create(tx.InnerTransaction, "Errors", 16); var typeInt = (int)_index.Type; var statsTree = tx.InnerTransaction.CreateTree(IndexSchema.StatsTree); using (Slice.External(context.Allocator, (byte *)&typeInt, sizeof(int), out Slice tmpSlice)) statsTree.Add(IndexSchema.TypeSlice, tmpSlice); var sourceTypeInt = (int)_index.SourceType; using (Slice.External(context.Allocator, (byte *)&sourceTypeInt, sizeof(int), out Slice tmpSlice)) statsTree.Add(IndexSchema.SourceTypeSlice, tmpSlice); if (statsTree.Read(IndexSchema.CreatedTimestampSlice) == null) { var binaryDate = SystemTime.UtcNow.ToBinary(); using (Slice.External(context.Allocator, (byte *)&binaryDate, sizeof(long), out Slice tmpSlice)) statsTree.Add(IndexSchema.CreatedTimestampSlice, tmpSlice); } using (Slice.From(context.Allocator, documentDatabase.DbBase64Id, out var dbId)) statsTree.Add(IndexSchema.DatabaseIdSlice, dbId); tx.InnerTransaction.CreateTree(IndexSchema.EtagsTree); tx.InnerTransaction.CreateTree(IndexSchema.EtagsTombstoneTree); tx.InnerTransaction.CreateTree(IndexSchema.References); tx.InnerTransaction.CreateTree(IndexSchema.ReferencesForCompareExchange); _lastDatabaseEtagOnIndexCreation = InitializeLastDatabaseEtagOnIndexCreation(context); _index.Definition.Persist(context, _environment.Options); tx.Commit(); } }
static IndexesEtagsStorage() { Slice.From(StorageEnvironment.LabelsContext, "EtagIndexName", out EtagIndexName); Slice.From(StorageEnvironment.LabelsContext, "NameAndEtagIndexName", out NameAndEtagIndexName); // Table schema is: // - index id - int (-1 if tombstone) // - etag - long // - name - string, lowercase // - type - enum (index / transformer) // - change vector // - is conflicted - boolean //(is conflicted --> a flag, so we will not have to read another table in voron just to check if the index/transformer is conlficted) IndexesTableSchema = new TableSchema(); IndexesTableSchema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = (int)MetadataFields.Name, Count = 1 }); IndexesTableSchema.DefineFixedSizeIndex(new TableSchema.FixedSizeSchemaIndexDef { StartIndex = (int)MetadataFields.Etag, Name = EtagIndexName }); //Table schema is: // - name -> string, lowercase // - etag -> long // - type -> enum (index / transformer) // - change vector // - definition of conflicted index/transformer (blittable json) ConflictsTableSchema = new TableSchema(); ConflictsTableSchema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = 1 }); ConflictsTableSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = (int)ConflictFields.Name, Count = 2, Name = NameAndEtagIndexName }); }
public bool Update(UpdateStep step) { using (Slice.From(step.ReadTx.Allocator, "ErrorTimestamps", out var errorTimestampsSlice)) { var tableSchema = new TableSchema(); tableSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 0, IsGlobal = false, Name = errorTimestampsSlice }); var tableTree = step.WriteTx.CreateTree("Errors", RootObjectType.Table); tableSchema.SerializeSchemaIntoTableTree(tableTree); return(true); } }
static VersioningStorage() { Slice.From(StorageEnvironment.LabelsContext, "KeyAndEtag", ByteStringType.Immutable, out KeyAndEtagSlice); Slice.From(StorageEnvironment.LabelsContext, "Etag", ByteStringType.Immutable, out EtagSlice); // The documents schema is as follows // 5 fields (lowered key, recored separator, etag, lazy string key, document) // We are you using the record separator in order to avoid loading another documents that has the same key prefix, // e.g. fitz(record-separator)01234567 and fitz0(record-separator)01234567, without the record separator we would have to load also fitz0 and filter it. // format of lazy string key is detailed in GetLowerKeySliceAndStorageKey DocsSchema = new TableSchema(); DocsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 0, Count = 3, Name = KeyAndEtagSlice }); DocsSchema.DefineFixedSizeIndex(new TableSchema.FixedSizeSchemaIndexDef { StartIndex = 2, Name = EtagSlice }); }
private unsafe void CreateSchema() { _errorsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 0, IsGlobal = true, Name = IndexSchema.ErrorTimestampsSlice }); TransactionOperationContext context; using (_contextPool.AllocateOperationContext(out context)) using (var tx = context.OpenWriteTransaction()) { _errorsSchema.Create(tx.InnerTransaction, "Errors", 16); var typeInt = (int)_index.Type; var statsTree = tx.InnerTransaction.CreateTree(IndexSchema.StatsTree); Slice tmpSlice; using (Slice.External(context.Allocator, (byte *)&typeInt, sizeof(int), out tmpSlice)) statsTree.Add(IndexSchema.TypeSlice, tmpSlice); if (statsTree.Read(IndexSchema.CreatedTimestampSlice) == null) { var binaryDate = SystemTime.UtcNow.ToBinary(); using (Slice.External(context.Allocator, (byte *)&binaryDate, sizeof(long), out tmpSlice)) statsTree.Add(IndexSchema.CreatedTimestampSlice, tmpSlice); } tx.InnerTransaction.CreateTree(IndexSchema.EtagsTree); tx.InnerTransaction.CreateTree(IndexSchema.EtagsTombstoneTree); tx.InnerTransaction.CreateTree(IndexSchema.References); _index.Definition.Persist(context, _environment.Options); tx.Commit(); } }
static TimeSeriesRollups() { using (StorageEnvironment.GetStaticContext(out var ctx)) { Slice.From(ctx, nameof(TimeSeriesRollupTable), ByteStringType.Immutable, out TimeSeriesRollupTable); Slice.From(ctx, nameof(RollupKey), ByteStringType.Immutable, out RollupKey); Slice.From(ctx, nameof(NextRollupIndex), ByteStringType.Immutable, out NextRollupIndex); } RollupSchema = new TableSchema(); RollupSchema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = (int)RollupColumns.Key, Count = 1, Name = RollupKey }); RollupSchema.DefineIndex(new TableSchema.SchemaIndexDef // this isn't fixed-size since we expect to have duplicates { StartIndex = (int)RollupColumns.NextRollup, Count = 1, Name = NextRollupIndex }); }
private unsafe void CreateSchema(DocumentDatabase documentDatabase) { _errorsSchema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 0, // there is just a single instance of this table // but we need it to be local so we'll be able to compact it IsGlobal = false, Name = IndexSchema.ErrorTimestampsSlice }); using (_contextPool.AllocateOperationContext(out TransactionOperationContext context)) using (var tx = context.OpenWriteTransaction()) { _errorsSchema.Create(tx.InnerTransaction, "Errors", 16); var typeInt = (int)_index.Type; var statsTree = tx.InnerTransaction.CreateTree(IndexSchema.StatsTree); using (Slice.External(context.Allocator, (byte *)&typeInt, sizeof(int), out Slice tmpSlice)) statsTree.Add(IndexSchema.TypeSlice, tmpSlice); var sourceTypeInt = (int)_index.SourceType; using (Slice.External(context.Allocator, (byte *)&sourceTypeInt, sizeof(int), out Slice tmpSlice)) statsTree.Add(IndexSchema.SourceTypeSlice, tmpSlice); if (statsTree.Read(IndexSchema.CreatedTimestampSlice) == null) { var binaryDate = SystemTime.UtcNow.ToBinary(); using (Slice.External(context.Allocator, (byte *)&binaryDate, sizeof(long), out Slice tmpSlice)) statsTree.Add(IndexSchema.CreatedTimestampSlice, tmpSlice); } using (Slice.From(context.Allocator, documentDatabase.DbBase64Id, out var dbId)) statsTree.Add(IndexSchema.DatabaseIdSlice, dbId); tx.InnerTransaction.CreateTree(IndexSchema.EtagsTree); tx.InnerTransaction.CreateTree(IndexSchema.EtagsTombstoneTree); tx.InnerTransaction.CreateTree(IndexSchema.References); tx.InnerTransaction.CreateTree(IndexSchema.ReferencesForCompareExchange); _lastDatabaseEtagOnIndexCreation = InitializeLastDatabaseEtagOnIndexCreation(context); _index.Definition.Persist(context, _environment.Options); PersistConfiguration(); tx.Commit(); void PersistConfiguration() { var configurationTree = tx.InnerTransaction.CreateTree(IndexSchema.ConfigurationTree); AssertAndPersistAnalyzer(configurationTree, RavenConfiguration.GetKey(x => x.Indexing.DefaultAnalyzer), _index.Configuration.DefaultAnalyzer, Raven.Client.Constants.Documents.Indexing.Analyzers.Default); AssertAndPersistAnalyzer(configurationTree, RavenConfiguration.GetKey(x => x.Indexing.DefaultExactAnalyzer), _index.Configuration.DefaultExactAnalyzer, Raven.Client.Constants.Documents.Indexing.Analyzers.DefaultExact); AssertAndPersistAnalyzer(configurationTree, RavenConfiguration.GetKey(x => x.Indexing.DefaultSearchAnalyzer), _index.Configuration.DefaultSearchAnalyzer, Raven.Client.Constants.Documents.Indexing.Analyzers.DefaultSearch); } void AssertAndPersistAnalyzer(Tree configurationTree, string configurationKey, string expectedAnalyzer, string defaultAnalyzer) { var result = configurationTree.Read(configurationKey); string persistedConfigurationValue = null; if (result != null) { persistedConfigurationValue = result.Reader.ToStringValue(); } else if (_index.Definition.Version < IndexDefinitionBaseServerSide.IndexVersion.Analyzers) { persistedConfigurationValue = defaultAnalyzer; } if (persistedConfigurationValue != null) { if (persistedConfigurationValue != expectedAnalyzer) { throw new InvalidOperationException($"Invalid analyzer. The index '{_index.Name}' was created with analyzer '{persistedConfigurationValue}' for '{configurationKey}' configuration, but current one is '{expectedAnalyzer}'. Please reset the index."); } return; } configurationTree.Add(configurationKey, expectedAnalyzer); } } }
public unsafe void CanDeleteTableWithLargeValues() { TableSchema schema = new TableSchema(); schema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = 0, Count = 1, Name = Etag, IsGlobal = true }); schema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 0, Count = 1, Name = Local, IsGlobal = false }); using (Transaction tx = Env.WriteTransaction()) { schema.Create(tx, "first", 256); schema.Create(tx, "second", 256); Table fst = tx.OpenTable(schema, "first"); Table snd = tx.OpenTable(schema, "second"); for (var i = 0; i < 1000;) { var bytes = new byte[2 * RawDataSection.MaxItemSize + 100]; new Random(i).NextBytes(bytes); TableValueBuilder tvb1 = new TableValueBuilder(); TableValueBuilder tvb2 = new TableValueBuilder(); tvb1.Add(i++); tvb2.Add(i++); fixed(byte *ptr = bytes) { tvb1.Add(ptr, bytes.Length); tvb2.Add(ptr, bytes.Length); fst.Insert(tvb1); snd.Insert(tvb2); } } tx.Commit(); } using (var tx = Env.WriteTransaction()) { tx.DeleteTable("first"); tx.DeleteTable("second"); tx.Commit(); } using (var tx = Env.WriteTransaction()) { Assert.Null(tx.LowLevelTransaction.RootObjects.Read("first")); Assert.Null(tx.LowLevelTransaction.RootObjects.Read("second")); } }
public unsafe void CanDeleteTableWithLargeValues() { TableSchema schema = new TableSchema(); schema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = 0, Count = 1, Name = Etag, IsGlobal = true }); schema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 0, Count = 1, Name = Local, IsGlobal = false }); using (Transaction tx = Env.WriteTransaction()) { schema.Create(tx, "first", 256); schema.Create(tx, "second", 256); Table fst = tx.OpenTable(schema, "first"); Table snd = tx.OpenTable(schema, "second"); for (var i = 0; i < 1000;) { var bytes = new byte[2 * RawDataSection.MaxItemSize + 100]; new Random(i).NextBytes(bytes); TableValueBuilder tvb1 = new TableValueBuilder(); TableValueBuilder tvb2 = new TableValueBuilder(); tvb1.Add(i++); tvb2.Add(i++); fixed(byte *ptr = bytes) { tvb1.Add(ptr, bytes.Length); tvb2.Add(ptr, bytes.Length); fst.Insert(tvb1); snd.Insert(tvb2); } } tx.Commit(); } using (var tx = Env.WriteTransaction()) { var firstTable = tx.OpenTable(schema, "first"); firstTable.DeleteByPrimaryKey(Slices.BeforeAllKeys, x => { if (schema.Key.IsGlobal) { return(firstTable.IsOwned(x.Reader.Id)); } return(true); }); var secondTable = tx.OpenTable(schema, "first"); secondTable.DeleteByPrimaryKey(Slices.BeforeAllKeys, x => { if (schema.Key.IsGlobal) { return(secondTable.IsOwned(x.Reader.Id)); } return(true); }); tx.Commit(); } }
public unsafe void CanBeSafelyModifiedOnEither() { using (var tx = Env.WriteTransaction()) { Slice.From(tx.Allocator, "RevisionsChangeVector", ByteStringType.Immutable, out var changeVectorSlice); Slice.From(tx.Allocator, "Etag", ByteStringType.Immutable, out var etag); var revisionsSchema = new TableSchema(); revisionsSchema.DefineKey(new TableSchema.SchemaIndexDef { StartIndex = 0, Count = 1, Name = changeVectorSlice, IsGlobal = false }); var indexDef = new TableSchema.SchemaIndexDef { StartIndex = 1, Name = etag, IsGlobal = true }; revisionsSchema.DefineIndex(indexDef); revisionsSchema.Create(tx, "users", 32); revisionsSchema.Create(tx, "people", 32); var usersTbl = tx.OpenTable(revisionsSchema, "users"); var peopleTbl = tx.OpenTable(revisionsSchema, "people"); using (usersTbl.Allocate(out var builder)) using (Slice.From(tx.Allocator, Guid.NewGuid().ToString(), out var key)) { builder.Add(key); builder.Add(0L); usersTbl.Insert(builder); } for (int i = 0; i < 127; i++) { using (peopleTbl.Allocate(out var builder)) using (Slice.From(tx.Allocator, Guid.NewGuid().ToString(), out var key)) { builder.Add(key); builder.Add(0L); peopleTbl.Insert(builder); } } using (peopleTbl.Allocate(out var builder)) using (Slice.From(tx.Allocator, Guid.NewGuid().ToString(), out var key)) { builder.Add(key); builder.Add(0L); peopleTbl.Insert(builder); } using (Slice.From(tx.Allocator, new byte[8], out var empty)) { var userIndex = usersTbl.GetFixedSizeTree(usersTbl.GetTree(indexDef), empty, 0, true); var peopleIndex = peopleTbl.GetFixedSizeTree(usersTbl.GetTree(indexDef), empty, 0, true); Assert.Equal(userIndex.NumberOfEntries, peopleIndex.NumberOfEntries); Assert.Equal(userIndex.Type, peopleIndex.Type); } } }
public unsafe void SameTransaction() { TableSchema schema = new TableSchema(); schema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 1, Count = 1, Name = Global, IsGlobal = true }); schema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 2, Count = 1, Name = Local, IsGlobal = false }); using (Transaction tx = Env.WriteTransaction()) { schema.Create(tx, "test", 256); Table tbl = tx.OpenTable(schema, "test"); schema.Create(tx, "snd", 256); Table snd = tx.OpenTable(schema, "snd"); for (int i = 0; i < 20_000; i += 2) { var tvb = new TableValueBuilder(); tvb.Add(i); tvb.Add(0); tvb.Add(i); tbl.Insert(tvb); } for (int i = 1; i < 20_000; i += 2) { TableValueBuilder tvb = new TableValueBuilder(); tvb.Add(i); tvb.Add(0); tvb.Add(i); snd.Insert(tvb); } tx.Commit(); } using (var tx = Env.WriteTransaction()) { Table snd = tx.OpenTable(schema, "snd"); var a = snd.DeleteForwardFrom(schema.Indexes[Local], Slices.BeforeAllKeys, false, long.MaxValue); Assert.Equal(10_000, a); } }
public unsafe void ShouldNotError() { TableSchema schema = new TableSchema(); schema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 0, Count = 1, Name = Etag, IsGlobal = true }); schema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 1, Count = 1, Name = Global, IsGlobal = true }); schema.DefineIndex(new TableSchema.SchemaIndexDef { StartIndex = 2, Count = 1, Name = Local, IsGlobal = false }); using (Transaction tx = Env.WriteTransaction()) { schema.Create(tx, "test", 256); Table fst = tx.OpenTable(schema, "test"); schema.Create(tx, "snd", 256); for (int i = 0; i < 20_000; i++) { TableValueBuilder tvb = new TableValueBuilder(); tvb.Add(i); tvb.Add(0); tvb.Add(i); fst.Insert(tvb); } tx.Commit(); } using (Transaction tx = Env.WriteTransaction()) { Table snd = tx.OpenTable(schema, "snd"); Table fst = tx.OpenTable(schema, "test"); for (int i = 1; i < 20_000; i += 2) { using (Slice.From(tx.Allocator, BitConverter.GetBytes(i), out var key)) { var a = fst.DeleteForwardFrom(schema.Indexes[Etag], key, true, 1); Assert.True(1 == a, $"{a} on {i}"); } snd.Insert(new TableValueBuilder { i, 0, i }); } tx.Commit(); } using (var tx = Env.WriteTransaction()) { Table snd = tx.OpenTable(schema, "snd"); for (int i = 1; i < 20_000; i += 2) { using (Slice.From(tx.Allocator, BitConverter.GetBytes(i), out var key)) { var a = snd.DeleteForwardFrom(schema.Indexes[Etag], key, true, 1); Assert.True(1 == a, $"{a} on {i}"); } } } }