Exemple #1
0
        public unsafe void Can_define_compressed_table_and_read_write_large()
        {
            using (var tx = Env.WriteTransaction())
            {
                Slice.From(tx.Allocator, "Compression", out var etagIndexName);
                var fixedSizedIndex = new TableSchema.FixedSizeSchemaIndexDef
                {
                    Name       = etagIndexName,
                    IsGlobal   = true,
                    StartIndex = 1,
                };

                var tableSchema = new TableSchema()
                                  .CompressValues(fixedSizedIndex, true)
                                  .DefineFixedSizeIndex(fixedSizedIndex)
                                  .DefineKey(new TableSchema.SchemaIndexDef
                {
                    StartIndex = 0,
                    Count      = 1,
                });

                tableSchema.Create(tx, "Items", 16);
                var        itemsTable = tx.OpenTable(tableSchema, "Items");
                const long number     = 1L;

                var str = Enumerable.Range(0, 10_000)
                          .Aggregate(new StringBuilder(), (sb, i) => sb.Append(i))
                          .ToString();

                using (itemsTable.Allocate(out TableValueBuilder builder))
                    using (Slice.From(tx.Allocator, "val1", out var key))
                        using (Slice.From(tx.Allocator, str, out var val))
                        {
                            builder.Add(key);
                            builder.Add(Bits.SwapBytes(number));
                            builder.Add(val);
                            long id            = itemsTable.Insert(builder);
                            long allocatedSize = itemsTable.GetAllocatedSize(id);
                            Assert.True(allocatedSize > 8192 && allocatedSize < str.Length);
                        }

                using (Slice.From(tx.Allocator, "val1", out var key))
                {
                    Assert.True(itemsTable.ReadByKey(key, out var reader));
                    var ptr = reader.Read(2, out var size);
                    using var _ = Slice.External(tx.Allocator, ptr, size, out var slice);
                    Assert.Equal(str, slice.ToString());
                }

                using (Slice.From(tx.Allocator, "val1", out var key))
                {
                    Assert.True(itemsTable.ReadByKey(key, out var reader));

                    Assert.True(itemsTable.ReadByKey(key, out var reader2));


                    Assert.Equal(new IntPtr(reader.Pointer), new IntPtr(reader2.Pointer));
                }
            }
        }
Exemple #2
0
        public void ErrorsOnInvalidSchemaWithSingleFixedIndex()
        {
            using (var tx = Env.WriteTransaction())
            {
                var expectedSchema = new TableSchema();

                var def = new TableSchema.FixedSizeSchemaIndexDef
                {
                    StartIndex = 2,
                };
                Slice.From(tx.Allocator, "Test Name", ByteStringType.Immutable, out def.Name);

                expectedSchema.DefineFixedSizeIndex(def);

                var actualSchema = new TableSchema();

                def = new TableSchema.FixedSizeSchemaIndexDef
                {
                    StartIndex = 4,
                };
                Slice.From(tx.Allocator, "Bad Test Name", ByteStringType.Immutable, out def.Name);
                actualSchema.DefineFixedSizeIndex(def);


                Assert.Throws <ArgumentNullException>(delegate { expectedSchema.Validate(null); });
                Assert.Throws <ArgumentException>(delegate { expectedSchema.Validate(actualSchema); });
            }
        }
Exemple #3
0
        public void delete_by_fixed_sized_index()
        {
            using (var tx = Env.WriteTransaction())
            {
                Slice.From(tx.Allocator, "EtagIndexName", out var etagIndexName);
                var fixedSizedIndex = new TableSchema.FixedSizeSchemaIndexDef
                {
                    Name       = etagIndexName,
                    IsGlobal   = true,
                    StartIndex = 1,
                };

                var tableSchema = new TableSchema()
                                  .DefineFixedSizeIndex(fixedSizedIndex)
                                  .DefineKey(new TableSchema.SchemaIndexDef
                {
                    StartIndex = 0,
                    Count      = 1,
                });

                tableSchema.Create(tx, "Items", 16);
                var        itemsTable = tx.OpenTable(tableSchema, "Items");
                const long number1    = 1L;
                const long number2    = 2L;
                const long number3    = 3L;

                using (itemsTable.Allocate(out TableValueBuilder builder))
                    using (Slice.From(tx.Allocator, "val1", out var key))
                    {
                        builder.Add(key);
                        builder.Add(Bits.SwapBytes(number1));
                        itemsTable.Set(builder);
                    }

                using (itemsTable.Allocate(out TableValueBuilder builder))
                    using (Slice.From(tx.Allocator, "val2", out var key))
                    {
                        builder.Add(key);
                        builder.Add(Bits.SwapBytes(number2));
                        itemsTable.Set(builder);
                    }

                using (itemsTable.Allocate(out TableValueBuilder builder))
                    using (Slice.From(tx.Allocator, "val3", out var key))
                    {
                        builder.Add(key);
                        builder.Add(Bits.SwapBytes(number3));
                        itemsTable.Set(builder);
                    }

                Assert.False(itemsTable.DeleteByIndex(fixedSizedIndex, 0L));
                Assert.True(itemsTable.DeleteByIndex(fixedSizedIndex, 2L));
                Assert.True(itemsTable.DeleteByIndex(fixedSizedIndex, 3L));
                Assert.True(itemsTable.DeleteByIndex(fixedSizedIndex, 1L));
            }
        }
Exemple #4
0
        public void Can_update_compressed_value()
        {
            using (var tx = Env.WriteTransaction())
            {
                Slice.From(tx.Allocator, "Compression", out var etagIndexName);
                var fixedSizedIndex = new TableSchema.FixedSizeSchemaIndexDef
                {
                    Name       = etagIndexName,
                    IsGlobal   = true,
                    StartIndex = 1,
                };

                var tableSchema = new TableSchema()
                                  .CompressValues(fixedSizedIndex, true)
                                  .DefineFixedSizeIndex(fixedSizedIndex)
                                  .DefineKey(new TableSchema.SchemaIndexDef
                {
                    StartIndex = 0,
                    Count      = 1,
                });

                tableSchema.Create(tx, "Items", 16);
                var        itemsTable = tx.OpenTable(tableSchema, "Items");
                const long number     = 1L;

                using (itemsTable.Allocate(out TableValueBuilder builder))
                    using (Slice.From(tx.Allocator, "val1", out var key))
                        using (Slice.From(tx.Allocator, new string('a', 1024 * 16), out var val))
                        {
                            builder.Add(key);
                            builder.Add(Bits.SwapBytes(number));
                            builder.Add(val);
                            long id            = itemsTable.Insert(builder);
                            var  allocatedSize = itemsTable.GetAllocatedSize(id);
                            Assert.True(allocatedSize < 128);
                        }

                using (itemsTable.Allocate(out TableValueBuilder builder))
                    using (Slice.From(tx.Allocator, "val1", out var key))
                        using (Slice.From(tx.Allocator, new string('a', 1024 * 32), out var val))
                        {
                            builder.Add(key);
                            builder.Add(Bits.SwapBytes(number));
                            builder.Add(val);
                            itemsTable.Set(builder);
                        }

                using (Slice.From(tx.Allocator, "val1", out var key))
                {
                    Assert.True(itemsTable.ReadByKey(key, out var reader));
                    Assert.True(itemsTable.GetAllocatedSize(reader.Id) < 128);
                }
            }
        }
Exemple #5
0
 private void FixedSchemaIndexDefEqual(TableSchema.FixedSizeSchemaIndexDef expectedIndex,
                                       TableSchema.FixedSizeSchemaIndexDef actualIndex)
 {
     if (expectedIndex == null)
     {
         Assert.Equal(null, actualIndex);
     }
     else
     {
         Assert.Equal(expectedIndex.IsGlobal, actualIndex.IsGlobal);
         Assert.True(SliceComparer.Equals(expectedIndex.Name, actualIndex.Name));
         Assert.Equal(expectedIndex.StartIndex, actualIndex.StartIndex);
     }
 }
Exemple #6
0
        public void CanSerializeMultiIndexSchema()
        {
            using (var tx = Env.WriteTransaction())
            {
                var def1 = new TableSchema.SchemaIndexDef
                {
                    StartIndex = 2,
                    Count      = 1,
                };
                Slice.From(tx.Allocator, "Test Name 1", ByteStringType.Immutable, out def1.Name);

                var def2 = new TableSchema.SchemaIndexDef
                {
                    StartIndex = 1,
                    Count      = 1,
                };
                Slice.From(tx.Allocator, "Test Name 2", ByteStringType.Immutable, out def2.Name);

                var def3 = new TableSchema.FixedSizeSchemaIndexDef()
                {
                    StartIndex = 2,
                    IsGlobal   = true,
                };
                Slice.From(tx.Allocator, "Test Name 3", ByteStringType.Immutable, out def3.Name);

                var tableSchema = new TableSchema()
                                  .DefineIndex(def1)
                                  .DefineIndex(def2)
                                  .DefineFixedSizeIndex(def3)
                                  .DefineKey(new TableSchema.SchemaIndexDef
                {
                    StartIndex = 3,
                    Count      = 1,
                });

                byte[] serialized = tableSchema.SerializeSchema();

                fixed(byte *ptr = serialized)
                {
                    var actualTableSchema = TableSchema.ReadFrom(tx.Allocator, ptr, serialized.Length);

                    // This checks that reserializing is the same
                    Assert.Equal(serialized, actualTableSchema.SerializeSchema());
                    // This checks that what was deserialized is correct
                    SchemaDefEqual(tableSchema, actualTableSchema);
                    tableSchema.Validate(actualTableSchema);
                }
            }
        }
Exemple #7
0
        public void Insert_same_value_to_fixed_sized_index_throws()
        {
            using (var tx = Env.WriteTransaction())
            {
                Slice.From(tx.Allocator, "EtagIndexName", out var etagIndexName);
                var fixedSizedIndex = new TableSchema.FixedSizeSchemaIndexDef
                {
                    Name       = etagIndexName,
                    IsGlobal   = true,
                    StartIndex = 1,
                };

                var tableSchema = new TableSchema()
                                  .DefineFixedSizeIndex(fixedSizedIndex)
                                  .DefineKey(new TableSchema.SchemaIndexDef
                {
                    StartIndex = 0,
                    Count      = 1,
                });

                tableSchema.Create(tx, "Items", 16);
                var        itemsTable = tx.OpenTable(tableSchema, "Items");
                const long number     = 1L;

                using (itemsTable.Allocate(out TableValueBuilder builder))
                    using (Slice.From(tx.Allocator, "val1", out var key))
                    {
                        builder.Add(key);
                        builder.Add(Bits.SwapBytes(number));
                        itemsTable.Set(builder);
                    }

                using (itemsTable.Allocate(out TableValueBuilder builder))
                    using (Slice.From(tx.Allocator, "val2", out var key))
                    {
                        builder.Add(key);
                        builder.Add(Bits.SwapBytes(number));

                        var exception = Assert.Throws <VoronErrorException>(() => itemsTable.Set(builder));
                        Assert.True(exception.Message.StartsWith("Attempt to add duplicate value"));
                    }
            }
        }
Exemple #8
0
        public void ErrorsOnInvalidFixedSizeDef()
        {
            using (var tx = Env.WriteTransaction())
            {
                var expectedIndex = new TableSchema.FixedSizeSchemaIndexDef
                {
                    StartIndex = 2,
                };
                Slice.From(tx.Allocator, "Test Name", ByteStringType.Immutable, out expectedIndex.Name);

                var actualIndex = new TableSchema.FixedSizeSchemaIndexDef
                {
                    StartIndex = 5,
                };
                Slice.From(tx.Allocator, "Test Name", ByteStringType.Immutable, out actualIndex.Name);

                Assert.Throws <ArgumentNullException>(delegate { expectedIndex.Validate(null); });
                Assert.Throws <ArgumentException>(delegate { expectedIndex.Validate(actualIndex); });
            }
        }
Exemple #9
0
        public void CanSerializeFixedIndex()
        {
            using (var tx = Env.WriteTransaction())
            {
                var expectedIndex = new TableSchema.FixedSizeSchemaIndexDef
                {
                    StartIndex = 2,
                    IsGlobal   = true,
                };
                Slice.From(tx.Allocator, "Test Name 2", ByteStringType.Immutable, out expectedIndex.Name);

                byte[] serialized = expectedIndex.Serialize();

                fixed(byte *serializedPtr = serialized)
                {
                    var actualIndex = TableSchema.FixedSizeSchemaIndexDef.ReadFrom(tx.Allocator, serializedPtr, serialized.Length);

                    Assert.Equal(serialized, actualIndex.Serialize());
                    FixedSchemaIndexDefEqual(expectedIndex, actualIndex);
                    expectedIndex.Validate(actualIndex);
                }
            }
        }
Exemple #10
0
        public void WillNotRememberOldDictionariesAfterRestart()
        {
            RequireFileBasedPager();


            using var allocator = new ByteStringContext(SharedMultipleUseFlag.None);
            using var ____      = Slice.From(allocator, "PK", out var pk);
            using var ___       = Slice.From(allocator, "Etags", out var etags);
            using var __        = Slice.From(allocator, "Table", out var tbl);

            var idx = new TableSchema.FixedSizeSchemaIndexDef {
                Name = etags, IsGlobal = false, StartIndex = 0
            };
            var schema = new TableSchema()
                         .DefineKey(new TableSchema.SchemaIndexDef
            {
                Name       = pk,
                IsGlobal   = false,
                StartIndex = 0,
                Count      = 1
            })
                         .DefineFixedSizeIndex(idx)
                         .CompressValues(idx, true);

            using (var wtx = Env.WriteTransaction())
            {
                schema.Create(wtx, tbl, null);
                wtx.Commit();
            }


            using (var wtx = Env.WriteTransaction())
            {
                var table = wtx.OpenTable(schema, tbl);

                using var _ = Slice.From(allocator, LongRandomString(), out var val);

                for (long i = 0; i < 1024 * 4; i++)
                {
                    using (table.Allocate(out var builder))
                    {
                        builder.Add(Bits.SwapBytes(i));
                        builder.Add(val);
                        table.Insert(builder);
                    }
                }

                wtx.Commit();
            }

            using (var wtx = Env.WriteTransaction())
            {
                var table = wtx.OpenTable(schema, tbl);

                using var _ = Slice.From(allocator, LongRandomString(), out var val);

                for (long i = 20_000; i < 20_000 + 1024 * 4; i++)
                {
                    using (table.Allocate(out var builder))
                    {
                        builder.Add(Bits.SwapBytes(i));
                        builder.Add(val);
                        table.Insert(builder);
                    }

                    table.ReadLast(idx); // force to read the new dictionary
                }

                // explicitly discard the change
                //wtx.Commit();
            }

            using (var wtx = Env.WriteTransaction())
            {
                var table = wtx.OpenTable(schema, tbl);

                using var _ = Slice.From(allocator, LongRandomString(), out var val);

                for (long i = 20_000; i < 20_000 + 1020 * 4; i++)
                {
                    using (table.Allocate(out var builder))
                    {
                        builder.Add(Bits.SwapBytes(i));
                        builder.Add(val);
                        table.Insert(builder);
                    }
                }

                wtx.Commit();
            }

            RestartDatabase();

            using (var rtx = Env.ReadTransaction())
            {
                var table = rtx.OpenTable(schema, tbl);

                using (var it = table.SeekForwardFrom(idx, 0, 0).GetEnumerator())
                {
                    while (it.MoveNext())
                    {
                    }
                }
            }
        }
Exemple #11
0
        public unsafe void OnDataMoveShouldForgetOldCompressionIds()
        {
            var random = new Random(357);

            using (var tx = Env.WriteTransaction())
            {
                Slice.From(tx.Allocator, "Compression", out var etagIndexName);
                var fixedSizedIndex = new TableSchema.FixedSizeSchemaIndexDef
                {
                    Name       = etagIndexName,
                    IsGlobal   = true,
                    StartIndex = 1,
                };

                var tableSchema = new TableSchema()
                                  .CompressValues(fixedSizedIndex, true)
                                  .DefineFixedSizeIndex(fixedSizedIndex)
                                  .DefineKey(new TableSchema.SchemaIndexDef
                {
                    StartIndex = 0,
                    Count      = 1,
                });

                tableSchema.Create(tx, "Items", 16);
                var itemsTable = tx.OpenTable(tableSchema, "Items");


                var rnd = Enumerable.Range(1, 32)
                          .Select(i => Compression.RandomString(random, 123))
                          .ToList();

                for (int i = 0; i < 32 * 1024; i++)
                {
                    using (itemsTable.Allocate(out TableValueBuilder builder))
                        using (Slice.From(tx.Allocator, "val" + i, out var key))
                            using (Slice.From(tx.Allocator, rnd[i % rnd.Count], out var val))
                            {
                                builder.Add(key);
                                builder.Add(Bits.SwapBytes((long)i));
                                builder.Add(val);
                                itemsTable.Insert(builder);
                            }
                }

                AssertRemainingValues();

                for (int i = 32 * 1024 - 1; i >= 0; i--)
                {
                    using (Slice.From(tx.Allocator, "val" + i, out var key))
                    {
                        if (i % 10 != 0)
                        {
                            itemsTable.DeleteByKey(key);
                        }
                    }
                }

                AssertRemainingValues(validate: true);

                void AssertRemainingValues(bool validate = false)
                {
                    foreach (var reader in itemsTable.SeekBackwardFrom(fixedSizedIndex, long.MaxValue))
                    {
                        var p = reader.Reader.Read(1, out var sizeOfInt);
                        Assert.Equal(sizeOfInt, sizeof(long));
                        var i = Bits.SwapBytes(*(long *)p);

                        var keyPtr = reader.Reader.Read(0, out var keySize);
                        using (Slice.From(tx.Allocator, keyPtr, keySize, out var currentKey))
                            using (Slice.From(tx.Allocator, "val" + i, out var expectedKey))
                            {
                                Assert.True(SliceStructComparer.Instance.Equals(currentKey, expectedKey));
                            }

                        if (validate)
                        {
                            if (i % 10 != 0)
                            {
                                Assert.True(false, $"Oops {i}");
                            }
                        }
                    }
                }
            }
        }
Exemple #12
0
        public void Can_force_small_value_to_compress_to_large()
        {
            var random = new Random(222);

            using (var tx = Env.WriteTransaction())
            {
                Slice.From(tx.Allocator, "Compression", out var etagIndexName);
                var fixedSizedIndex = new TableSchema.FixedSizeSchemaIndexDef
                {
                    Name       = etagIndexName,
                    IsGlobal   = true,
                    StartIndex = 1,
                };

                var tableSchema = new TableSchema()
                                  .CompressValues(fixedSizedIndex, true)
                                  .DefineFixedSizeIndex(fixedSizedIndex)
                                  .DefineKey(new TableSchema.SchemaIndexDef
                {
                    StartIndex = 0,
                    Count      = 1,
                });

                tableSchema.Create(tx, "Items", 16);
                var  itemsTable = tx.OpenTable(tableSchema, "Items");
                long number     = 1L;

                var rnd = Enumerable.Range(1, 32)
                          .Select(i => RandomString(random, 1024))
                          .ToList();

                for (int i = 0; i < 16 * 1024; i++)
                {
                    using (itemsTable.Allocate(out TableValueBuilder builder))
                        using (Slice.From(tx.Allocator, "val" + i, out var key))
                            using (Slice.From(tx.Allocator, rnd[i % rnd.Count], out var val))
                            {
                                builder.Add(key);
                                builder.Add(Bits.SwapBytes(++number));
                                builder.Add(val);
                                itemsTable.Insert(builder);
                            }
                }

                for (int i = 512; i < 768; i++)
                {
                    using (Slice.From(tx.Allocator, "val" + i, out var key))
                    {
                        itemsTable.DeleteByKey(key);
                    }
                }

                var str = Enumerable.Range(0, 10_000)
                          .Aggregate(new StringBuilder(), (sb, i) => sb.Append((char)(i % 26 + 'A')))
                          .ToString();

                for (int i = 0; i < 256; i++)
                {
                    using (itemsTable.Allocate(out TableValueBuilder builder))
                        using (Slice.From(tx.Allocator, "val" + i, out var key))
                            using (Slice.From(tx.Allocator, str, out var val))
                            {
                                builder.Add(key);
                                builder.Add(Bits.SwapBytes(++number));
                                builder.Add(val);
                                itemsTable.Set(builder);
                            }
                }
            }
        }
Exemple #13
0
        public unsafe void Can_get_better_compression_rate_after_training()
        {
            using (var tx = Env.WriteTransaction())
            {
                Slice.From(tx.Allocator, "Compression", out var etagIndexName);
                var fixedSizedIndex = new TableSchema.FixedSizeSchemaIndexDef
                {
                    Name       = etagIndexName,
                    IsGlobal   = true,
                    StartIndex = 1,
                };

                var tableSchema = new TableSchema()
                                  .CompressValues(fixedSizedIndex, true)
                                  .DefineFixedSizeIndex(fixedSizedIndex)
                                  .DefineKey(new TableSchema.SchemaIndexDef
                {
                    StartIndex = 0,
                    Count      = 1,
                });

                tableSchema.Create(tx, "Items", 16);
                var  itemsTable = tx.OpenTable(tableSchema, "Items");
                long number     = 1L;
                var  random     = new Random(49941);
                var  data       = string.Join(", ", Enumerable.Range(0, 100).Select(_ =>
                {
                    var bytes = new byte[16];
                    random.NextBytes(bytes);
                    return(new Guid(bytes).ToString());
                }));

                int firstAllocatedSize;

                using (itemsTable.Allocate(out TableValueBuilder builder))
                    using (Slice.From(tx.Allocator, "val", out var key))
                        using (Slice.From(tx.Allocator, data, out var val))
                        {
                            builder.Add(key);
                            builder.Add(Bits.SwapBytes(number));
                            builder.Add(val);
                            long id = itemsTable.Insert(builder);
                            firstAllocatedSize = itemsTable.GetAllocatedSize(id);
                        }

                var minAllocatedSize = 0;
                for (int i = 0; i < 100; i++)
                {
                    using (itemsTable.Allocate(out TableValueBuilder builder))
                        using (Slice.From(tx.Allocator, "val" + i, out var key))
                            using (Slice.From(tx.Allocator, data, out var val))
                            {
                                builder.Add(key);
                                builder.Add(Bits.SwapBytes(++number));
                                builder.Add(val);
                                long id            = itemsTable.Insert(builder);
                                var  allocatedSize = itemsTable.GetAllocatedSize(id);
                                minAllocatedSize = Math.Min(minAllocatedSize, allocatedSize);
                            }
                }

                Assert.True(minAllocatedSize < firstAllocatedSize);
            }
        }