void PersistTableInfo(TableInfo tableInfo) { _keyValueTrProtector.Start(); if (tableInfo.LastPersistedVersion != tableInfo.ClientTypeVersion) { if (tableInfo.LastPersistedVersion <= 0) { _keyValueTr.SetKeyPrefix(ObjectDB.TableNamesPrefix); if (_keyValueTr.CreateKey(BuildKeyFromOid(tableInfo.Id))) { using (var writer = new KeyValueDBValueWriter(_keyValueTr)) { writer.WriteString(tableInfo.Name); } } } _keyValueTr.SetKeyPrefix(ObjectDB.TableVersionsPrefix); if (_keyValueTr.CreateKey(TableInfo.BuildKeyForTableVersions(tableInfo.Id, tableInfo.ClientTypeVersion))) { var tableVersionInfo = tableInfo.ClientTableVersionInfo; using (var writer = new KeyValueDBValueWriter(_keyValueTr)) { tableVersionInfo.Save(writer); } } } if (tableInfo.NeedStoreSingletonOid) { _keyValueTr.SetKeyPrefix(ObjectDB.TableSingletonsPrefix); _keyValueTr.CreateOrUpdateKeyValue(BuildKeyFromOid(tableInfo.Id), BuildKeyFromOid((ulong)tableInfo.SingletonOid)); } }
public AbstractBufferedWriter PrepareToWriteObject(ulong id) { var shouldStop = false; try { _keyValueTrProtector.Start(ref shouldStop); _keyValueTr.SetKeyPrefix(ObjectDB.AllObjectsPrefix); var key = new byte[PackUnpack.LengthVUInt(id)]; var ofs = 0; PackUnpack.PackVUInt(key, ref ofs, id); _keyValueTr.CreateKey(key); var writer = new KeyValueDBValueProtectedWriter(_keyValueTr, _keyValueTrProtector); shouldStop = false; return(writer); } finally { if (shouldStop) { _keyValueTrProtector.Stop(); } } }
void DoRandomWork() { var opCounter = 0; var random = new Random(); using (var stream = CreateTestStream()) //using (IKeyValueDB db = new KeyValueDBReplayProxy(new KeyValueDB(), new PositionLessStreamWriter(new PositionLessStreamProxy("btdb.log")))) using (IKeyValueDB db = new KeyValueDB()) { db.Open(stream, false); IKeyValueDBTransaction tr = db.StartTransaction(); while (opCounter < 100000) { if (opCounter % 1000 == 0) { Console.WriteLine(string.Format("Operation {0}", opCounter)); Console.WriteLine(tr.CalculateStats().ToString()); } opCounter++; var action = random.Next(100); if (action < 10) { if (action > 1) { //Console.WriteLine("Commit"); tr.Commit(); } else { //Console.WriteLine("Rollback"); } tr.Dispose(); tr = db.StartTransaction(); } else if (action < 50 || tr.GetKeyIndex() < 0) { var key = new byte[random.Next(1, 1000)]; random.NextBytes(key); //Console.WriteLine(string.Format("CreateKey {0}", key.Length)); tr.CreateKey(key); } else if (action < 60) { //Console.WriteLine("EraseCurrent"); tr.EraseCurrent(); } else if (action < 65) { //Console.WriteLine("FindNextKey"); tr.FindNextKey(); } else if (action < 70) { //Console.WriteLine("FindPreviousKey"); tr.FindPreviousKey(); } else { var value = new byte[random.Next(1, 100000)]; random.NextBytes(value); //Console.WriteLine(string.Format("SetValue {0}", value.Length)); tr.SetValue(value); } } tr.Dispose(); } }
/// <summary> /// Reads and inserts all key value pairs into current prefix from stream /// </summary> /// <param name="transaction">transaction where to import all data</param> /// <param name="stream">where to read it from</param> public static void Import(IKeyValueDBTransaction transaction, Stream stream) { if (transaction == null) throw new ArgumentNullException("transaction"); if (stream == null) throw new ArgumentNullException("stream"); if (!stream.CanRead) throw new ArgumentException("stream must be readable", "stream"); var tempbuf = new byte[4096]; if (stream.Read(tempbuf, 0, 16) != 16) throw new EndOfStreamException(); if (tempbuf[0] != 'B' || tempbuf[1] != 'T' || tempbuf[2] != 'D' || tempbuf[3] != 'B' || tempbuf[4] != 'E' || tempbuf[5] != 'X' || tempbuf[6] != 'P' || tempbuf[7] != '1') { throw new BTDBException("Invalid header (it should start with BTDBEXP1)"); } var keyValuePairs = PackUnpack.UnpackInt64LE(tempbuf, 8); if (keyValuePairs < 0) throw new BTDBException("Negative number of key value pairs"); for (var kv = 0; kv < keyValuePairs; kv++) { if (stream.Read(tempbuf, 0, 4) != 4) throw new EndOfStreamException(); var keySize = PackUnpack.UnpackInt32LE(tempbuf, 0); if (keySize < 0) throw new BTDBException("Negative key size"); if (keySize > tempbuf.Length) tempbuf = new byte[keySize]; if (stream.Read(tempbuf, 0, keySize) != keySize) throw new EndOfStreamException(); transaction.CreateKey(tempbuf); if (stream.Read(tempbuf, 0, 8) != 8) throw new EndOfStreamException(); var valueSize = PackUnpack.UnpackInt64LE(tempbuf, 0); if (valueSize < 0) throw new BTDBException("Negative value size"); if (valueSize <= tempbuf.Length) { if (stream.Read(tempbuf, 0, (int)valueSize) != valueSize) throw new EndOfStreamException(); transaction.SetValue(tempbuf, 0, (int)valueSize); } else { transaction.SetValueSize(valueSize); long pos = 0; while (pos < valueSize) { int toRead = (int)Math.Min(valueSize - pos, tempbuf.Length); if (stream.Read(tempbuf, 0, toRead) != toRead) throw new EndOfStreamException(); transaction.WriteValue(pos,toRead,tempbuf,0); pos += toRead; } } } }
/// <summary> /// Reads and inserts all key value pairs into current prefix from stream /// </summary> /// <param name="transaction">transaction where to import all data</param> /// <param name="stream">where to read it from</param> public static void Import(IKeyValueDBTransaction transaction, Stream stream) { if (transaction == null) { throw new ArgumentNullException("transaction"); } if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanRead) { throw new ArgumentException("stream must be readable", "stream"); } var tempbuf = new byte[4096]; if (stream.Read(tempbuf, 0, 16) != 16) { throw new EndOfStreamException(); } if (tempbuf[0] != 'B' || tempbuf[1] != 'T' || tempbuf[2] != 'D' || tempbuf[3] != 'B' || tempbuf[4] != 'E' || tempbuf[5] != 'X' || tempbuf[6] != 'P' || tempbuf[7] != '1') { throw new BTDBException("Invalid header (it should start with BTDBEXP1)"); } var keyValuePairs = PackUnpack.UnpackInt64LE(tempbuf, 8); if (keyValuePairs < 0) { throw new BTDBException("Negative number of key value pairs"); } for (var kv = 0; kv < keyValuePairs; kv++) { if (stream.Read(tempbuf, 0, 4) != 4) { throw new EndOfStreamException(); } var keySize = PackUnpack.UnpackInt32LE(tempbuf, 0); if (keySize < 0) { throw new BTDBException("Negative key size"); } if (keySize > tempbuf.Length) { tempbuf = new byte[keySize]; } if (stream.Read(tempbuf, 0, keySize) != keySize) { throw new EndOfStreamException(); } transaction.CreateKey(tempbuf); if (stream.Read(tempbuf, 0, 8) != 8) { throw new EndOfStreamException(); } var valueSize = PackUnpack.UnpackInt64LE(tempbuf, 0); if (valueSize < 0) { throw new BTDBException("Negative value size"); } if (valueSize <= tempbuf.Length) { if (stream.Read(tempbuf, 0, (int)valueSize) != valueSize) { throw new EndOfStreamException(); } transaction.SetValue(tempbuf, 0, (int)valueSize); } else { transaction.SetValueSize(valueSize); long pos = 0; while (pos < valueSize) { int toRead = (int)Math.Min(valueSize - pos, tempbuf.Length); if (stream.Read(tempbuf, 0, toRead) != toRead) { throw new EndOfStreamException(); } transaction.WriteValue(pos, toRead, tempbuf, 0); pos += toRead; } } } }