예제 #1
0
        private void ReplayWriteAction(WriteActivityEntry activityEntry, ref Transaction tx)
        {
            var tree = tx.ReadTree(activityEntry.TreeName);

            switch (activityEntry.ActionType)
            {
            case DebugActionType.Add:
                tree.Add(activityEntry.Key, activityEntry.ValueStream);
                break;

            case DebugActionType.Delete:
                tree.Delete(activityEntry.Key);
                break;

            case DebugActionType.MultiAdd:
                tree.MultiAdd(activityEntry.Key, new Slice(Encoding.UTF8.GetBytes(activityEntry.Value.ToString())));
                break;

            case DebugActionType.MultiDelete:
                tree.MultiDelete(activityEntry.Key, new Slice(Encoding.UTF8.GetBytes(activityEntry.Value.ToString())));
                break;

            case DebugActionType.CreateTree:
                _env.CreateTree(tx, activityEntry.TreeName);
                break;

            case DebugActionType.Increment:
                var buffer = new byte[sizeof(long)];
                activityEntry.ValueStream.Read(buffer, 0, buffer.Length);
                var delta = EndianBitConverter.Little.ToInt64(buffer, 0);
                tree.Increment(activityEntry.Key, delta);
                break;

            case DebugActionType.AddStruct:
                tree.Add(activityEntry.Key, activityEntry.ValueStream);
                break;

            case DebugActionType.RenameTree:
                _env.RenameTree(tx, activityEntry.TreeName, activityEntry.Key.ToString());
                break;

            default:     //precaution against newly added action types
                throw new InvalidOperationException("unsupported tree action type: " + activityEntry.ActionType);
            }
        }
예제 #2
0
        public void Record_debug_journal_and_replay_it()
        {
            var structSchema = new StructureSchema <SampleStruct>()
                               .Add <int>(SampleStruct.Foo)
                               .Add <string>(SampleStruct.Bar);

            using (var env = new StorageEnvironment(StorageEnvironmentOptions.CreateMemoryOnly()))
            {
                env.DebugJournal = new DebugJournal(debugJouralName, env, true);
                using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
                {
                    env.CreateTree(tx, "test-tree");
                    tx.Commit();
                }

                using (var writeBatch = new WriteBatch())
                {
                    var valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("{ \"title\": \"foo\",\"name\":\"bar\"}"));
                    writeBatch.Add("foo", valueBuffer, "test-tree");

                    valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("testing testing 1 2!"));
                    writeBatch.Add("bar", valueBuffer, "test-tree");

                    valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("testing testing 1 2 3!"));
                    writeBatch.Add("foo-bar", valueBuffer, "test-tree");

                    writeBatch.MultiAdd("multi-foo", "AA", "test-tree");
                    env.Writer.Write(writeBatch);
                }

                using (var writeBatch = new WriteBatch())
                {
                    writeBatch.Increment("incr-key", 5, "test-tree");
                    env.Writer.Write(writeBatch);
                }

                using (var tx = env.NewTransaction(TransactionFlags.Read))
                {
                    Assert.Equal(5, tx.ReadTree("test-tree").Read("incr-key").Reader.ReadLittleEndianInt64());

                    using (var writeBatch = new WriteBatch())
                    {
                        writeBatch.Increment("incr-key", 5, "test-tree");
                        env.Writer.Write(writeBatch);
                    }

                    Assert.Equal(5, tx.ReadTree("test-tree").Read("incr-key").Reader.ReadLittleEndianInt64());
                }

                using (var tx = env.NewTransaction(TransactionFlags.Read))
                {
                    Assert.Equal(10, tx.ReadTree("test-tree").Read("incr-key").Reader.ReadLittleEndianInt64());
                }

                using (var writeBatch = new WriteBatch())
                {
                    writeBatch.MultiAdd("multi-foo", "BB", "test-tree");
                    writeBatch.MultiAdd("multi-foo", "CC", "test-tree");

                    writeBatch.Delete("foo-bar", "test-tree");
                    env.Writer.Write(writeBatch);
                }

                using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
                {
                    env.CreateTree(tx, "test-tree2");
                    tx.Commit();
                }

                using (var writeBatch = new WriteBatch())
                {
                    var valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("testing testing 1!"));
                    writeBatch.Add("foo", valueBuffer, "test-tree2");

                    valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("testing testing 1 2!"));
                    writeBatch.Add("bar", valueBuffer, "test-tree2");

                    valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("testing testing 1 2 3!"));
                    writeBatch.Add("foo-bar", valueBuffer, "test-tree2");
                    env.Writer.Write(writeBatch);
                }

                using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
                {
                    env.CreateTree(tx, "structures-tree");
                    tx.Commit();
                }

                using (var writeBatch = new WriteBatch())
                {
                    writeBatch.AddStruct("structs/1", new Structure <SampleStruct>(structSchema)
                                         .Set(SampleStruct.Foo, 13)
                                         .Set(SampleStruct.Bar, "debug journal testing"),
                                         "structures-tree");

                    env.Writer.Write(writeBatch);
                }

                using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
                {
                    env.CreateTree(tx, "rename-me");
                    tx.Commit();
                }

                using (var writeBatch = new WriteBatch())
                {
                    writeBatch.Add("item", "renaming tree test", "rename-me");

                    env.Writer.Write(writeBatch);
                }

                using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
                {
                    env.RenameTree(tx, "rename-me", "renamed");

                    tx.Commit();
                }
            }

            using (var env = new StorageEnvironment(StorageEnvironmentOptions.CreateMemoryOnly()))
            {
                env.DebugJournal = DebugJournal.FromFile(debugJouralName, env);
                env.DebugJournal.Replay();

                using (var snapshot = env.CreateSnapshot())
                {
                    Assert.Equal("{ \"title\": \"foo\",\"name\":\"bar\"}", snapshot.Read("test-tree", "foo").Reader.ToStringValue());
                    Assert.Equal("testing testing 1 2!", snapshot.Read("test-tree", "bar").Reader.ToStringValue());

                    Assert.Equal("testing testing 1!", snapshot.Read("test-tree2", "foo").Reader.ToStringValue());
                    Assert.Equal("testing testing 1 2!", snapshot.Read("test-tree2", "bar").Reader.ToStringValue());
                    Assert.Equal("testing testing 1 2 3!", snapshot.Read("test-tree2", "foo-bar").Reader.ToStringValue());

                    Assert.Equal(10, snapshot.Read("test-tree", "incr-key").Reader.ReadLittleEndianInt64());

                    Assert.Equal(0, snapshot.ReadVersion("test-tree", "foo-bar"));

                    using (var iter = snapshot.MultiRead("test-tree", "multi-foo"))
                    {
                        iter.Seek(Slice.BeforeAllKeys);
                        Assert.Equal("AA", iter.CurrentKey.ToString());
                        Assert.DoesNotThrow(() => iter.MoveNext());
                        Assert.Equal("BB", iter.CurrentKey.ToString());
                        Assert.DoesNotThrow(() => iter.MoveNext());
                        Assert.Equal("CC", iter.CurrentKey.ToString());
                    }

                    var structReader = snapshot.ReadStruct("structures-tree", "structs/1", structSchema).Reader;

                    Assert.Equal(13, structReader.ReadInt(SampleStruct.Foo));
                    Assert.Equal("debug journal testing", structReader.ReadString(SampleStruct.Bar));

                    Assert.Equal("renaming tree test", snapshot.Read("renamed", "item").Reader.ToStringValue());
                }
            }
        }
예제 #3
0
        private static void Migrate(StorageEnvironment env, string tableName, Action <string> output, Action <Slice, RavenJObject> modifyRecord)
        {
            long entriesCount;

            using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
            {
                entriesCount = tx.ReadTree(tableName).State.EntriesCount;
            }

            if (entriesCount == 0)
            {
                output(string.Format("No records to migrate in '{0}' table.", tableName));
                return;
            }

            output(string.Format("Starting to migrate '{0}' table to. Records to process: {1}", tableName, entriesCount));


            using (var txw = env.NewTransaction(TransactionFlags.ReadWrite))
            {
                env.DeleteTree(txw, "Temp_" + tableName);

                txw.Commit();
            }

            using (var txw = env.NewTransaction(TransactionFlags.ReadWrite))
            {
                env.CreateTree(txw, "Temp_" + tableName);

                txw.Commit();
            }

            var migrated  = 0L;
            var keyToSeek = Slice.BeforeAllKeys;

            do
            {
                using (var txw = env.NewTransaction(TransactionFlags.ReadWrite))
                {
                    var destTree = txw.ReadTree("Temp_" + tableName);
                    var srcTree  = txw.ReadTree(tableName);

                    var iterator = srcTree.Iterate();

                    if (iterator.Seek(keyToSeek) == false)
                    {
                        break;
                    }

                    var itemsInBatch = 0;

                    do
                    {
                        keyToSeek = iterator.CurrentKey;

                        if (itemsInBatch != 0 && itemsInBatch % 100 == 0)
                        {
                            break;
                        }

                        using (var stream = iterator.CreateReaderForCurrent().AsStream())
                        {
                            var value = stream.ToJObject();

                            modifyRecord(iterator.CurrentKey, value);

                            using (var streamValue = new MemoryStream())
                            {
                                value.WriteTo(streamValue);
                                streamValue.Position = 0;

                                destTree.Add(iterator.CurrentKey, streamValue);
                            }

                            migrated++;
                            itemsInBatch++;
                        }
                    } while (iterator.MoveNext());

                    txw.Commit();

                    output(string.Format("{0} of {1} entries processed.", migrated, entriesCount));
                }
            } while (migrated < entriesCount);

            using (var txw = env.NewTransaction(TransactionFlags.ReadWrite))
            {
                env.DeleteTree(txw, tableName);
                env.RenameTree(txw, "Temp_" + tableName, tableName);

                txw.Commit();
            }
        }
예제 #4
0
		public void Record_debug_journal_and_replay_it()
		{
			var structSchema = new StructureSchema<SampleStruct>()
					.Add<int>(SampleStruct.Foo)
					.Add<string>(SampleStruct.Bar);

			using (var env = new StorageEnvironment(StorageEnvironmentOptions.CreateMemoryOnly()))
			{
				env.DebugJournal = new DebugJournal(debugJouralName, env, true);
				using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
				{
					env.CreateTree(tx, "test-tree");
					tx.Commit();
				}

				using (var writeBatch = new WriteBatch())
				{
					var valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("{ \"title\": \"foo\",\"name\":\"bar\"}"));
					writeBatch.Add("foo", valueBuffer, "test-tree");

					valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("testing testing 1 2!"));
					writeBatch.Add("bar", valueBuffer, "test-tree");

					valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("testing testing 1 2 3!"));
					writeBatch.Add("foo-bar", valueBuffer, "test-tree");

					writeBatch.MultiAdd("multi-foo", "AA", "test-tree");
					env.Writer.Write(writeBatch);
				}

                using (var writeBatch = new WriteBatch())
                {
                    writeBatch.Increment("incr-key", 5, "test-tree");
                    env.Writer.Write(writeBatch);
                }

                using (var tx = env.NewTransaction(TransactionFlags.Read))
                {
                    Assert.Equal(5, tx.ReadTree("test-tree").Read("incr-key").Reader.ReadLittleEndianInt64());

                    using (var writeBatch = new WriteBatch())
                    {
                        writeBatch.Increment("incr-key", 5, "test-tree");
                        env.Writer.Write(writeBatch);
                    }

                    Assert.Equal(5, tx.ReadTree("test-tree").Read("incr-key").Reader.ReadLittleEndianInt64());
                }

			    using (var tx = env.NewTransaction(TransactionFlags.Read))
			    {
                    Assert.Equal(10, tx.ReadTree("test-tree").Read("incr-key").Reader.ReadLittleEndianInt64());
			    }

			    using (var writeBatch = new WriteBatch())
				{
					writeBatch.MultiAdd("multi-foo", "BB", "test-tree");
					writeBatch.MultiAdd("multi-foo", "CC", "test-tree");

					writeBatch.Delete("foo-bar", "test-tree");
					env.Writer.Write(writeBatch);
				}

				using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
				{
					env.CreateTree(tx, "test-tree2");
					tx.Commit();
				}

				using (var writeBatch = new WriteBatch())
				{
					var valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("testing testing 1!"));
					writeBatch.Add("foo", valueBuffer, "test-tree2");

					valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("testing testing 1 2!"));
					writeBatch.Add("bar", valueBuffer, "test-tree2");

					valueBuffer = new MemoryStream(Encoding.UTF8.GetBytes("testing testing 1 2 3!"));
					writeBatch.Add("foo-bar", valueBuffer, "test-tree2");
					env.Writer.Write(writeBatch);
				}

				using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
				{
					env.CreateTree(tx, "structures-tree");
					tx.Commit();
				}

				using (var writeBatch = new WriteBatch())
				{
					writeBatch.AddStruct("structs/1", new Structure<SampleStruct>(structSchema)
						.Set(SampleStruct.Foo, 13)
						.Set(SampleStruct.Bar, "debug journal testing"),
						"structures-tree");

					env.Writer.Write(writeBatch);
				}

				using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
				{
					env.CreateTree(tx, "rename-me");
					tx.Commit();
				}

				using (var writeBatch = new WriteBatch())
				{
					writeBatch.Add("item", "renaming tree test", "rename-me");

					env.Writer.Write(writeBatch);
				}

				using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
				{
					env.RenameTree(tx, "rename-me", "renamed");

					tx.Commit();
				}
			}

			using (var env = new StorageEnvironment(StorageEnvironmentOptions.CreateMemoryOnly()))
			{
				env.DebugJournal = DebugJournal.FromFile(debugJouralName, env);
				env.DebugJournal.Replay();

				using (var snapshot = env.CreateSnapshot())
				{
					Assert.Equal("{ \"title\": \"foo\",\"name\":\"bar\"}", snapshot.Read("test-tree", "foo").Reader.ToStringValue());
				    Assert.Equal("testing testing 1 2!", snapshot.Read("test-tree", "bar").Reader.ToStringValue());

				    Assert.Equal("testing testing 1!", snapshot.Read("test-tree2", "foo").Reader.ToStringValue());
				    Assert.Equal("testing testing 1 2!", snapshot.Read("test-tree2", "bar").Reader.ToStringValue());
				    Assert.Equal("testing testing 1 2 3!", snapshot.Read("test-tree2", "foo-bar").Reader.ToStringValue());

                    Assert.Equal(10, snapshot.Read("test-tree", "incr-key").Reader.ReadLittleEndianInt64());

					Assert.Equal(0,snapshot.ReadVersion("test-tree","foo-bar"));

					using (var iter = snapshot.MultiRead("test-tree","multi-foo"))
					{
						iter.Seek(Slice.BeforeAllKeys);
						Assert.Equal("AA",iter.CurrentKey.ToString());
						Assert.DoesNotThrow(() => iter.MoveNext());
						Assert.Equal("BB",iter.CurrentKey.ToString());
						Assert.DoesNotThrow(() => iter.MoveNext());
						Assert.Equal("CC",iter.CurrentKey.ToString());
					}

					var structReader = snapshot.ReadStruct("structures-tree", "structs/1", structSchema).Reader;

					Assert.Equal(13, structReader.ReadInt(SampleStruct.Foo));
					Assert.Equal("debug journal testing", structReader.ReadString(SampleStruct.Bar));

					Assert.Equal("renaming tree test", snapshot.Read("renamed", "item").Reader.ToStringValue());
				}
			}			

		}
예제 #5
0
        public void MigrateToStructures <T>(StorageEnvironment env, TableOfStructures <T> table, Action <string> output, Action <RavenJObject, Structure <T> > copyToStructure)
        {
            long entriesCount;

            using (var tx = env.NewTransaction(TransactionFlags.ReadWrite))
            {
                entriesCount = tx.ReadTree(table.TableName).State.EntriesCount;
            }

            if (entriesCount == 0)
            {
                output(string.Format("No records to migrate in '{0}' table.", table.TableName));
                return;
            }

            output(string.Format("Starting to migrate '{0}' table to use structures. Records to process: {1}", table.TableName, entriesCount));

            var migratedEntries = 0L;
            var keyToSeek       = Slice.BeforeAllKeys;

            // delete Temp_TabelName if exists
            using (var txw = env.NewTransaction(TransactionFlags.ReadWrite))
            {
                env.DeleteTree(txw, "Temp_" + table.TableName);

                txw.Commit();
            }
            using (var txw = env.NewTransaction(TransactionFlags.ReadWrite))
            {
                env.CreateTree(txw, "Temp_" + table.TableName);

                txw.Commit();
            }
            do
            {
                using (var txw = env.NewTransaction(TransactionFlags.ReadWrite))
                {
                    var destTree = txw.ReadTree("Temp_" + table.TableName);
                    var srcTree  = txw.ReadTree(table.TableName);

                    var iterator = srcTree.Iterate();

                    if (iterator.Seek(keyToSeek) == false)
                    {
                        break;
                    }

                    var writtenStructsSize = 0;

                    do
                    {
                        keyToSeek = iterator.CurrentKey;

                        if (writtenStructsSize > 8 * 1024 * 1024) // 8 MB
                        {
                            break;
                        }


                        var readerForCurrent = iterator.CreateReaderForCurrent();
                        using (var stream = readerForCurrent.AsStream())
                        {
                            var currentDataSize = iterator.GetCurrentDataSize();
                            try
                            {
                                RavenJObject jsonValue   = stream.ToJObject();
                                var          structValue = new Structure <T>(table.Schema);
                                copyToStructure(jsonValue, structValue);
                                destTree.WriteStruct(iterator.CurrentKey, structValue);
                                writtenStructsSize += structValue.GetSize();
                            }
                            catch (Exception)
                            {
                                // already converted this, probably, just move as is
                                int used;
                                var readBytes = readerForCurrent.ReadBytes(currentDataSize, out used);
                                destTree.Add(iterator.CurrentKey, readBytes);
                                writtenStructsSize += currentDataSize;
                            }

                            migratedEntries++;
                        }
                    } while (iterator.MoveNext());

                    txw.Commit();

                    output(string.Format("{0} of {1} records processed.", migratedEntries, entriesCount));
                }
            } while (migratedEntries < entriesCount);

            using (var txw = env.NewTransaction(TransactionFlags.ReadWrite))
            {
                env.DeleteTree(txw, table.TableName);
                env.RenameTree(txw, "Temp_" + table.TableName, table.TableName);

                txw.Commit();
            }

            output(string.Format("All records of '{0}' table have been migrated to structures.", table.TableName));
        }