public bool Delete(string key) { DbEntry keyEntry = DbEntry.InOut(Encoding.Default.GetBytes(key)); DeleteStatus res = btree.Delete(txn, ref keyEntry); return(res == DeleteStatus.Success); }
public void Delete <T>(IEnumerable <T> items) where T : class { dbName = typeof(T).FullName; initDatabase(); Txn trans = env.TxnBegin(null, Txn.BeginFlags.ReadCommitted); foreach (T t in items) { MemoryStream memKey = new MemoryStream(); MemoryStream memVal = new MemoryStream(); formatter.Serialize(memKey, t.GetHashCode()); formatter.Serialize(memVal, t); DbEntry key = DbEntry.InOut(memKey.ToArray()); DeleteStatus status = dbInstance.Delete(trans, ref key); if (status == DeleteStatus.NotFound) { Debug.Print("key {0} not found", t.GetHashCode()); } } trans.Commit(Txn.CommitMode.None); env.Close(); }
public bool ContainsKey(string key) { DbEntry keyEntry = DbEntry.InOut(Encoding.Default.GetBytes(key)); DbEntry dataEntry = DbEntry.InOut(dataStream.GetBuffer()); ReadStatus res = btree.Get(txn, ref keyEntry, ref dataEntry, DbFile.ReadFlags.None); return(res == ReadStatus.NotFound); }
/// <summary>Serializes a <c>null</c> into a <see cref="DbEntry"/> instance.</summary> /// <remarks>Companion method for <see cref="ToDbEntry{T}(ref T)"> /// ToDbEntry<T>(ref T)</see>.</remarks> /// <returns>A properly initialized <see cref="DbEntry"/> instance containing /// a serialized <c>null</c>.</returns> public DbEntry NullToDbEntry() { int index = 0; byte[] buffer = NextBuffer(); InitSerialization(buffer, index); SerializeNull(); index = FinishSerialization(); return(DbEntry.InOut(buffer, 0, index)); }
/// <summary>Serializes reference type sequences accessible through <see cref="IEnumerable{T}"/> /// using a specific <see cref="Field{T, F}"/> instance.</summary> /// <typeparam name="T">Type of sequence elements - must be reference type.</typeparam> /// <param name="value"><see cref="IEnumerable{T}"/> sequence to serialize.</param> /// <param name="field">Field that serializes the sequence elements.</param> /// <returns>A properly initialized <see cref="DbEntry"/> instance containing /// the serialized collection.</returns> public DbEntry ObjectsToDbEntry <T>(IEnumerable <T> value, ReferenceField <T, Formatter> field) where T : class { int index = 0; byte[] buffer = NextBuffer(); InitSerialization(buffer, index); SerializeObjects <T>(value, field); index = FinishSerialization(); return(DbEntry.InOut(buffer, 0, index)); }
/// <summary>Serializes value type sequences accessible through <see cref="IEnumerable{T}"/> /// using a specific <see cref="Field{T, F}"/> instance.</summary> /// <typeparam name="T">Type of sequence elements - must be value type.</typeparam> /// <param name="value"><see cref="IEnumerable{T}"/> sequence to serialize.</param> /// <param name="field">Field that serializes the sequence elements.</param> /// <returns>A properly initialized <see cref="DbEntry"/> instance containing /// the serialized collection.</returns> public DbEntry ValuesToDbEntry <T>(IEnumerable <T> value, ValueField <T, Formatter> field) where T : struct { int index = 0; byte[] buffer = NextBuffer(); InitSerialization(buffer, index); SerializeValues <T>(value, field); index = FinishSerialization(); return(DbEntry.InOut(buffer, 0, index)); }
/// <summary>Serializes a reference type into a <see cref="DbEntry"/> instance /// using a specific <see cref="Field{T, F}"/> instance.</summary> /// <typeparam name="T">Reference type to serialize.</typeparam> /// <param name="obj">Object to serialize.</param> /// <param name="field"><see cref="ReferenceField{T, Formatter}"/> instance that /// serializes the <c>obj</c>argument.</param> /// <returns>A properly initialized <see cref="DbEntry"/> instance containing /// the serialized object graph.</returns> public DbEntry ToDbEntry <T>(T obj, ReferenceField <T, Formatter> field) where T : class { int index = 0; byte[] buffer = NextBuffer(); InitSerialization(buffer, index); field.Serialize(obj); index = FinishSerialization(); return(DbEntry.InOut(buffer, 0, index)); }
/// <summary>Serializes a value type into a <see cref="DbEntry"/> instance /// using a specific <see cref="Field{T, F}"/> instance.</summary> /// <remarks>Passing the value type by reference avoids copy overhead. /// However, this does not allow to pass <c>nulls</c>. Therefore the /// companion method <see cref="NullToDbEntry"/> is provided.</remarks> /// <typeparam name="T">Value type to serialize.</typeparam> /// <param name="value">Struct instance to serialize.</param> /// <param name="field"><see cref="ValueField{T, Formatter}"/> instance that /// serializes the <c>value</c>argument.</param> /// <returns>A properly initialized <see cref="DbEntry"/> instance containing /// the serialized object graph.</returns> public DbEntry ToDbEntry <T>(ref T value, ValueField <T, Formatter> field) where T : struct { int index = 0; byte[] buffer = NextBuffer(); InitSerialization(buffer, index); field.Serialize(ref value); index = FinishSerialization(); return(DbEntry.InOut(buffer, 0, index)); }
public string this[string key] { get { DbEntry keyEntry = DbEntry.InOut(Encoding.Default.GetBytes(key)); DbEntry dataEntry = DbEntry.InOut(dataStream.GetBuffer()); ReadStatus res = btree.Get(txn, ref keyEntry, ref dataEntry, DbFile.ReadFlags.None); return(Encoding.Default.GetString(dataEntry.Buffer, 0, dataEntry.Size)); } set { DbEntry keyEntry = DbEntry.InOut(Encoding.Default.GetBytes(key)); DbEntry dataEntry = DbEntry.InOut(Encoding.Default.GetBytes(value)); WriteStatus res = btree.Put(txn, ref keyEntry, ref dataEntry); } }
private void AddRecord(DbBTree btree, Txn txn, Customer value, TextWriter writer) { // use standard .NET serialization, with the binary formatter keyStream.Position = 0; formatter.Serialize(keyStream, value.Name); DbEntry key = DbEntry.InOut(keyStream.GetBuffer(), 0, (int)keyStream.Position); dataStream.Position = 0; formatter.Serialize(dataStream, value); DbEntry data = DbEntry.InOut(dataStream.GetBuffer(), 0, (int)dataStream.Position); // calling PutNew means we don't want to overwrite an existing record WriteStatus status = btree.PutNew(txn, ref key, ref data); // if we tried to insert a duplicate, let's report it if (status == WriteStatus.KeyExist) { writer.WriteLine("Duplicate record: " + value.Name); } }
public void Save <T>(IEnumerable <T> items) where T : class { dbName = typeof(T).FullName; initDatabase(); Txn trans = env.TxnBegin(null, Txn.BeginFlags.ReadCommitted); foreach (T t in items) { MemoryStream memKey = new MemoryStream( ); MemoryStream memVal = new MemoryStream(); formatter.Serialize(memKey, t.GetHashCode()); formatter.Serialize(memVal, t); memKey.Flush(); memVal.Flush(); DbEntry key = DbEntry.InOut(memKey.ToArray()); DbEntry value = DbEntry.InOut(memVal.ToArray()); WriteStatus status = dbInstance.PutUnique(trans, ref key, ref value); if (status == WriteStatus.KeyExist) { Debug.Print("key {0} duplicated", t.GetHashCode()); } if (status == WriteStatus.KeyExist) { Delete <T>(t); WriteStatus st = dbInstance.PutUnique(trans, ref key, ref value); } } trans.Commit(Txn.CommitMode.Sync); env.Close(); }
public IList <T> Lookup <T>(ICondition condition) where T : class { dbName = typeof(T).FullName; initDatabase(); List <T> result = new List <T>( ); Txn trans = env.TxnBegin(null, Txn.BeginFlags.None); switch (condition.Name) { case "SELECT_ALL": using (DbBTreeCursor cursor = dbInstance.OpenCursor(null, DbFileCursor.CreateFlags.None)) { T cust = null; IEnumerable <KeyDataPair> lst = cursor.ItemsForward(false, DbFileCursor.ReadFlags.None); foreach (KeyDataPair pair in lst) { using (MemoryStream mem = new MemoryStream(pair.Data.Buffer)) { T t = (T)formatter.Deserialize(mem); result.Add(t); } } } break; case "SELECT_BY_CODE": SelectByCodeCondition cond = condition as SelectByCodeCondition; if (cond == null) { throw new InvalidDataException(String.Format("Invalid {0} condition", condition.Name)); } foreach (int i in cond.HashCodes) { T t = null; byte[] buf = new byte[1024]; MemoryStream key = new MemoryStream( ); MemoryStream value = new MemoryStream(); formatter.Serialize(key, i); DbEntry dbKey = DbEntry.InOut(key.ToArray()); DbEntry dbVal = DbEntry.Out(buf); while (true) { ReadStatus status = dbInstance.GetExact(trans, ref dbKey, ref dbVal, DbFile.ReadFlags.None); switch (status) { case ReadStatus.BufferSmall: if (dbVal.Buffer.Length < dbVal.Size) { value.SetLength(dbVal.Size); dbVal = DbEntry.Out(value.GetBuffer()); } continue; case ReadStatus.KeyEmpty: goto brk; case ReadStatus.NotFound: goto brk; case ReadStatus.Success: value.Position = 0; value.SetLength(dbVal.Size); value.Write(dbVal.Buffer, 0, dbVal.Size); value.Flush(); value.Seek(0, SeekOrigin.Begin); t = (T)formatter.Deserialize(value); result.Add(t); key.Dispose(); value.Dispose(); break; } } brk :; } break; default: throw new NotImplementedException(String.Format("Condition {0} is not implemented", condition.Name)); } trans.Commit(Txn.CommitMode.Sync); env.Close(); return(result); }
private void loadBtn_Click(object sender, EventArgs e) { ClearDisplay(); MemoryStream errStream = new MemoryStream(); MemoryStream msgStream = new MemoryStream(); TextWriter errWriter = new StreamWriter(errStream); TextWriter msgWriter = new StreamWriter(msgStream); Db db = null; Txn txn = null; Env env = null; try { env = new Env(EnvCreateFlags.None); // configure for error and message reporting env.ErrorStream = errStream; env.ErrorPrefix = Path.GetFileName(Application.ExecutablePath); env.MessageStream = msgStream; // initialize environment for locking, logging, memory pool and transactions Env.OpenFlags envFlags = Env.OpenFlags.Create | Env.OpenFlags.InitLock | Env.OpenFlags.InitLog | Env.OpenFlags.InitMPool | Env.OpenFlags.InitTxn | Env.OpenFlags.Recover; env.Open(homeDir, envFlags, 0); // create, configure and open database under a transaction txn = env.TxnBegin(null, Txn.BeginFlags.None); db = env.CreateDatabase(DbCreateFlags.None); // set the BTree comparison function db.BTreeCompare = AppCompare; // error and message reporting already configured on environment // db.ErrorStream = errStream; // db.ErrorPrefix = Path.GetFileName(Application.ExecutablePath); // db.MessageStream = msgStream; DbBTree btree = (DbBTree)db.Open( txn, myDb, null, DbType.BTree, Db.OpenFlags.Create, 0); txn.Commit(Txn.CommitMode.None); // create a sequence named '###sequence1' under a transaction txn = env.TxnBegin(null, Txn.BeginFlags.None); Sequence seq = btree.CreateSequence(); byte[] seqName = utf8.GetBytes("###sequence1"); DbEntry seqNameEntry = DbEntry.InOut(seqName); seq.Open(txn, ref seqNameEntry, Sequence.OpenFlags.Create); seq.Close(); txn.Commit(Txn.CommitMode.None); // open sequence again, retrieve values and then remove the sequence seq = btree.CreateSequence(); txn = env.TxnBegin(null, Txn.BeginFlags.None); // seq.CacheSize = 1000; // cannot use transactions when CacheSize > 0 seq.Open(txn, ref seqNameEntry, Sequence.OpenFlags.None); Int64 seqVal; for (int indx = 0; indx < 500; indx++) { seqVal = seq.Get(txn, 1, Sequence.ReadFlags.None); } seq.Remove(txn, Sequence.RemoveFlags.None); txn.Commit(Txn.CommitMode.None); // add a few records under a transaction Customer cust; txn = env.TxnBegin(null, Txn.BeginFlags.None); cust = new Customer("John Doe", "122 Yonge Street", "Toronto", "ON", "M5R 5T9", DateTime.Parse("Dec 22, 1965")); AddRecord(btree, txn, cust, errWriter); cust = new Customer("Jane Doby", "23 Bloor Street", "Oshawa", "ON", "L1H 2K9", DateTime.Parse("Jun 1, 1962")); AddRecord(btree, txn, cust, errWriter); cust = new Customer("Rusty Nail", "77 Bond Street", "Markham", "ON", "L3T 7Y8", DateTime.Parse("Sep 9, 1915")); AddRecord(btree, txn, cust, errWriter); cust = new Customer("Rosy Cheek", "11 Adelaide Street", "Whitby", "ON", "K3P 4H4", DateTime.Parse("Jan 2, 1980")); AddRecord(btree, txn, cust, errWriter); // this last one is a duplicate of the first record cust = new Customer("John Doe", "1459 King Street", "Toronto", "ON", "N8N 2L0", DateTime.Parse("Apr 14, 1973")); AddRecord(btree, txn, cust, errWriter); txn.Commit(Txn.CommitMode.None); msgWriter.WriteLine("=================================================="); msgWriter.WriteLine("K E Y S T A T I S T I C S"); msgWriter.WriteLine("=================================================="); // get a key range, under a transaction txn = env.TxnBegin(null, Txn.BeginFlags.None); keyStream.Position = 0; formatter.Serialize(keyStream, "John Doe"); DbEntry key = DbEntry.InOut(keyStream.GetBuffer(), 0, (int)keyStream.Position); DbBTree.KeyRange keyRange = btree.GetKeyRange(txn, ref key); txn.Commit(Txn.CommitMode.None); msgWriter.WriteLine(); string msg = "KeyRange for 'John Doe': Less = {0}, Equal = {1}, Greater = {2}"; msgWriter.WriteLine(string.Format(msg, keyRange.Less, keyRange.Equal, keyRange.Greater)); msgWriter.WriteLine(); // retrieve some database statistics TxnStats stats = env.GetTxnStats(StatFlags.None); DbBTree.Stats btstats = btree.GetStats(null, DbFile.StatFlags.None); CacheFileStats[] cfStats = env.GetCacheFileStats(StatFlags.None); // we can also have them written to the message stream msgWriter.WriteLine("=================================================="); msgWriter.WriteLine("T R A N S A C T I O N S T A T I S T I C S"); msgWriter.WriteLine("=================================================="); msgWriter.WriteLine(); msgWriter.Flush(); env.PrintTxnStats(StatPrintFlags.None); msgWriter.WriteLine(); msgWriter.WriteLine("=================================================="); msgWriter.WriteLine("L O G S T A T I S T I C S"); msgWriter.WriteLine("=================================================="); msgWriter.WriteLine(); msgWriter.Flush(); env.PrintLogStats(StatPrintFlags.All); msgWriter.WriteLine(); msgWriter.WriteLine("=================================================="); msgWriter.WriteLine("L O C K S T A T I S T I C S"); msgWriter.WriteLine("=================================================="); msgWriter.WriteLine(); msgWriter.Flush(); env.PrintLogStats(StatPrintFlags.All); msgWriter.WriteLine(); msgWriter.WriteLine("=================================================="); msgWriter.WriteLine("C A C H E S T A T I S T I C S"); msgWriter.WriteLine("=================================================="); msgWriter.WriteLine(); msgWriter.Flush(); env.PrintCacheStats(CacheStatPrintFlags.All); msgWriter.WriteLine(); msgWriter.WriteLine("=================================================="); msgWriter.WriteLine("B T R E E S T A T I S T I C S"); msgWriter.WriteLine("=================================================="); msgWriter.WriteLine(); msgWriter.Flush(); btree.PrintStats(DbFile.StatPrintFlags.All); } catch (BdbException) { if (txn != null && !txn.IsDisposed) { txn.Abort(); } // errors are reported through error stream already return; } catch (Exception ex) { if (txn != null && !txn.IsDisposed) { txn.Abort(); } errWriter.WriteLine(ex.ToString()); return; } finally { if (db != null) { db.Close(); } if (env != null) { env.Close(); } msgWriter.Flush(); string msgText = utf8.GetString(msgStream.GetBuffer()); if (msgText != "") { msgBox.Text = msgText; } msgWriter.Close(); errWriter.Flush(); string errText = utf8.GetString(errStream.GetBuffer()); if (errText != "") { errBox.Text = errText; tabControl.SelectTab("errorPage"); } errWriter.Close(); } }