KeyValuePair <DatabaseEntry, MultipleDatabaseEntry> GetBothMultiple( DatabaseEntry key, DatabaseEntry data, int BufferSize, Transaction txn, LockingInfo info) { KeyValuePair <DatabaseEntry, DatabaseEntry> kvp; int datasz = (int)data.Data.Length; for (; ;) { byte[] udata = new byte[BufferSize]; Array.Copy(data.Data, udata, datasz); data.UserData = udata; data.size = (uint)datasz; try { kvp = Get(key, data, txn, info, DbConstants.DB_MULTIPLE | DbConstants.DB_GET_BOTH); break; } catch (MemoryException) { int sz = (int)data.size; if (sz > BufferSize) { BufferSize = sz; } else { BufferSize *= 2; } } } MultipleDatabaseEntry dbe = new MultipleDatabaseEntry(kvp.Value); return(new KeyValuePair <DatabaseEntry, MultipleDatabaseEntry>( kvp.Key, dbe)); }
/// <summary> /// Move the cursor to the specified key/data pair of the database. The /// cursor is positioned to a key/data pair if both the key and data /// match the values provided on the key and data parameters. /// </summary> /// <remarks> /// <para> /// If positioning the cursor fails, <see cref="Current"/> will contain /// an empty <see cref="KeyValuePair{T,T}"/>. /// </para> /// <para> /// If this flag is specified on a database configured without sorted /// duplicate support, the value of <paramref name="exact"/> is ignored. /// </para> /// </remarks> /// <param name="pair"> /// The key/data pair at which to position the cursor. /// </param> /// <param name="exact"> /// If true, require the given key and data to match the key and data /// in the database exactly. If false, position the cursor at the /// smallest data value which is greater than or equal to the value /// provided by <paramref name="pair.Value"/> (as determined by the /// comparison function). /// </param> /// <param name="info">The locking behavior to use.</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool Move(KeyValuePair <DatabaseEntry, KeyValuePair <DatabaseEntry, DatabaseEntry> > pair, bool exact, LockingInfo info) { return(PGet(pair.Key, pair.Value.Key, pair.Value.Value, exact ? DbConstants.DB_GET_BOTH : DbConstants.DB_GET_BOTH_RANGE, info)); }
/// <summary> /// Position the cursor at a specific key/data pair in the database, and /// store the key/data pair in <see cref="Cursor.Current"/>. /// </summary> /// <param name="recno"> /// The specific numbered record of the database at which to position /// the cursor. /// </param> /// <param name="info">The locking behavior to use</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool Move(uint recno, LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); key.Data = BitConverter.GetBytes(recno); DatabaseEntry data = new DatabaseEntry(); return base.Get(key, data, DbConstants.DB_SET_RECNO, info); }
/// <summary> /// Retrieve a specific numbered key and all duplicate data items from /// the database. /// </summary> /// <param name="recno"> /// The record number of the record to be retrieved. /// </param> /// <param name="BufferSize"> /// The initial size of the buffer to fill with duplicate data items. If /// the buffer is not large enough, it is automatically resized. /// </param> /// <param name="txn"> /// <paramref name="txn"/> is a Transaction object returned from /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if /// the operation is part of a Berkeley DB Concurrent Data Store group, /// <paramref name="txn"/> is a handle returned from /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. /// </param> /// <param name="info">The locking behavior to use.</param> /// <exception cref="NotFoundException"> /// A NotFoundException is thrown if <paramref name="recno"/> is not in /// the database. /// </exception> /// <returns> /// A <see cref="KeyValuePair{T,T}"/> whose Key parameter is /// <paramref name="recno"/> and whose Value parameter is the retrieved /// data items. /// </returns> public KeyValuePair <DatabaseEntry, MultipleDatabaseEntry> GetMultiple( uint recno, int BufferSize, Transaction txn, LockingInfo info) { KeyValuePair <DatabaseEntry, DatabaseEntry> kvp; DatabaseEntry key = new DatabaseEntry(); key.Data = BitConverter.GetBytes(recno); DatabaseEntry data = new DatabaseEntry(); for (; ;) { data.UserData = new byte[BufferSize]; try { kvp = Get(key, data, txn, info, DbConstants.DB_MULTIPLE | DbConstants.DB_SET_RECNO); break; } catch (MemoryException) { int sz = (int)data.size; if (sz > BufferSize) { BufferSize = sz; } else { BufferSize *= 2; } } } MultipleDatabaseEntry dbe = new MultipleDatabaseEntry(kvp.Value); return(new KeyValuePair <DatabaseEntry, MultipleDatabaseEntry>( kvp.Key, dbe)); }
/// <summary> /// Store the secondary key and primary key/data pair to which the /// cursor refers in <see cref="Current"/>. /// </summary> /// <remarks> /// If positioning the cursor fails, <see cref="Current"/> will contain /// an empty <see cref="KeyValuePair{T,T}"/>. /// </remarks> /// <param name="info">The locking behavior to use.</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool Refresh(LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); DatabaseEntry pkey = new DatabaseEntry(); DatabaseEntry data = new DatabaseEntry(); return(PGet(key, pkey, data, DbConstants.DB_CURRENT, info)); }
/// <summary> /// If the cursor is not yet initialized, MovePrevUnique is identical to /// <see cref="MoveLast(LockingInfo)"/>. Otherwise, move the cursor to /// the previous non-duplicate key in the database, and store the /// secondary key and primary key/data pair in <see cref="Current"/>. /// MovePrevUnique will return false if no non-duplicate key/data pairs /// exist after the cursor position in the database. /// </summary> /// <remarks> /// If positioning the cursor fails, <see cref="Current"/> will contain /// an empty <see cref="KeyValuePair{T,T}"/>. /// </remarks> /// <param name="info">The locking behavior to use.</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool MovePrevUnique(LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); DatabaseEntry pkey = new DatabaseEntry(); DatabaseEntry data = new DatabaseEntry(); return(PGet(key, pkey, data, DbConstants.DB_PREV_NODUP, info)); }
/// <summary> /// If the next key/data pair of the database is a duplicate data record /// for the current key/data pair, move the cursor to the next key/data /// pair in the database, and store the secondary key and primary /// key/data pair in <see cref="Current"/>. MoveNextDuplicate will /// return false if the next key/data pair of the database is not a /// duplicate data record for the current key/data pair. /// </summary> /// <remarks> /// If positioning the cursor fails, <see cref="Current"/> will contain /// an empty <see cref="KeyValuePair{T,T}"/>. /// </remarks> /// <param name="info">The locking behavior to use.</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool MoveNextDuplicate(LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); DatabaseEntry pkey = new DatabaseEntry(); DatabaseEntry data = new DatabaseEntry(); return(PGet(key, pkey, data, DbConstants.DB_NEXT_DUP, info)); }
/// <summary> /// Set the cursor to refer to the last key/data pair of the database, /// and store the secondary key and primary key/data pair in /// <see cref="Current"/>. If the last key has duplicate values, the /// last data item in the set of duplicates is stored in /// <see cref="Current"/>. /// </summary> /// <remarks> /// If positioning the cursor fails, <see cref="Current"/> will contain /// an empty <see cref="KeyValuePair{T,T}"/>. /// </remarks> /// <param name="info">The locking behavior to use.</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool MoveLast(LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); DatabaseEntry pkey = new DatabaseEntry(); DatabaseEntry data = new DatabaseEntry(); return(PGet(key, pkey, data, DbConstants.DB_LAST, info)); }
/// <summary> /// Set the cursor to refer to <paramref name="key"/>, and store the /// primary key/data pair associated with the given secondary key in /// <see cref="Current"/>. In the presence of duplicate key values, the /// first data item in the set of duplicates is stored in /// <see cref="Current"/>. /// </summary> /// <remarks> /// If positioning the cursor fails, <see cref="Current"/> will contain /// an empty <see cref="KeyValuePair{T,T}"/>. /// </remarks> /// <param name="key">The key at which to position the cursor</param> /// <param name="exact"> /// If true, require the given key to match the key in the database /// exactly. If false, position the cursor at the smallest key greater /// than or equal to the specified key, permitting partial key matches /// and range searches. /// </param> /// <param name="info">The locking behavior to use.</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool Move(DatabaseEntry key, bool exact, LockingInfo info) { DatabaseEntry pkey = new DatabaseEntry(); DatabaseEntry data = new DatabaseEntry(); return(PGet(key, pkey, data, exact ? DbConstants.DB_SET : DbConstants.DB_SET_RANGE, info)); }
/* * Move the cursor according to recno. The recno * starts from 1 and is increased by 1. */ public void MoveCursorToRecno(BTreeCursor cursor, LockingInfo lck) { for (uint i = 1; i <= 5; i++) if (lck == null) Assert.IsTrue(cursor.Move(i)); else Assert.IsTrue(cursor.Move(i, lck)); }
/// <summary> /// Position the cursor at a specific key/data pair in the database, and /// store the key/data pair in <see cref="Cursor.Current"/>. /// </summary> /// <param name="recno"> /// The specific numbered record of the database at which to position /// the cursor. /// </param> /// <param name="info">The locking behavior to use</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool Move(uint recno, LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); key.Data = BitConverter.GetBytes(recno); DatabaseEntry data = new DatabaseEntry(); return(base.Get(key, data, DbConstants.DB_SET_RECNO, info)); }
/// <summary> /// Return the record number associated with the cursor's current /// position. /// </summary> /// <param name="info">The locking behavior to use</param> /// <returns>The record number associated with the cursor.</returns> public uint Recno(LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); DatabaseEntry data = new DatabaseEntry(); base.Get(key, data, DbConstants.DB_GET_RECNO, info); return(BitConverter.ToUInt32(base.Current.Value.Data, 0)); }
/// <summary> /// Retrieve a specific numbered key/data pair from the database. /// </summary> /// <param name="recno"> /// The record number of the record to be retrieved. /// </param> /// <param name="txn"> /// <paramref name="txn"/> is a Transaction object returned from /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if /// the operation is part of a Berkeley DB Concurrent Data Store group, /// <paramref name="txn"/> is a handle returned from /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. /// </param> /// <param name="info">The locking behavior to use.</param> /// <returns> /// A <see cref="KeyValuePair{T,T}"/> whose Key /// parameter is <paramref name="recno"/> and whose Value parameter is /// the retrieved data. /// </returns> public KeyValuePair <DatabaseEntry, DatabaseEntry> Get( uint recno, Transaction txn, LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); key.Data = BitConverter.GetBytes(recno); return(Get(key, null, txn, info, DbConstants.DB_SET_RECNO)); }
/// <summary> /// Position the cursor at a specific key/data pair in the database, and /// store the key/data pair and as many duplicate data items that can /// fit in a buffer the size of one database page in /// <see cref="Cursor.CurrentMultiple"/>. /// </summary> /// <param name="recno"> /// The specific numbered record of the database at which to position /// the cursor. /// </param> /// <param name="BufferSize"> /// The size of a buffer to fill with duplicate data items. Must be at /// least the page size of the underlying database and be a multiple of /// 1024. /// </param> /// <param name="info">The locking behavior to use</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool MoveMultiple(uint recno, int BufferSize, LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); key.Data = BitConverter.GetBytes(recno); DatabaseEntry data = new DatabaseEntry(); return(base.GetMultiple( key, data, BufferSize, DbConstants.DB_SET_RECNO, info, false)); }
/// <summary> /// Return the record number and data from the available record closest /// to the head of the queue, and delete the record. /// </summary> /// <param name="wait"> /// If true and the Queue database is empty, the thread of control will /// wait until there is data in the queue before returning. /// </param> /// <param name="txn"> /// <paramref name="txn"/> is a Transaction object returned from /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if /// the operation is part of a Berkeley DB Concurrent Data Store group, /// <paramref name="txn"/> is a handle returned from /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. /// </param> /// <param name="info">The locking behavior to use.</param> /// <exception cref="LockNotGrantedException"> /// If lock or transaction timeouts have been specified, a /// <see cref="LockNotGrantedException"/> may be thrown. This failure, /// by itself, does not require the enclosing transaction be aborted. /// </exception> /// <returns> /// A <see cref="KeyValuePair{T,T}"/> whose Key /// parameter is the record number and whose Value parameter is the /// retrieved data. /// </returns> public KeyValuePair <uint, DatabaseEntry> Consume( bool wait, Transaction txn, LockingInfo info) { KeyValuePair <DatabaseEntry, DatabaseEntry> record; record = Get(null, null, txn, info, wait ? DbConstants.DB_CONSUME_WAIT : DbConstants.DB_CONSUME); return(new KeyValuePair <uint, DatabaseEntry>( BitConverter.ToUInt32(record.Key.Data, 0), record.Value)); }
/// <summary> /// Protected method wrapping DBC->pget() /// </summary> /// <param name="key">The secondary key</param> /// <param name="pkey">The primary key</param> /// <param name="data">The primary data</param> /// <param name="flags">Flags to pass to DBC->pget</param> /// <param name="info">Locking parameters</param> /// <returns></returns> protected bool PGet( DatabaseEntry key, DatabaseEntry pkey, DatabaseEntry data, uint flags, LockingInfo info) { flags |= (info == null) ? 0 : info.flags; try { dbc.pget(key, pkey, data, flags); Current = new KeyValuePair <DatabaseEntry, KeyValuePair <DatabaseEntry, DatabaseEntry> >(key, new KeyValuePair <DatabaseEntry, DatabaseEntry>(pkey, data)); return(true); } catch (NotFoundException) { Current = new KeyValuePair <DatabaseEntry, KeyValuePair <DatabaseEntry, DatabaseEntry> >( null, new KeyValuePair <DatabaseEntry, DatabaseEntry>()); return(false); } }
private bool MoveNext(LockingInfo info, bool joinItem) { int ret; uint flags = 0; DatabaseEntry key = new DatabaseEntry(); DatabaseEntry data = new DatabaseEntry(); flags |= joinItem ? DbConstants.DB_JOIN_ITEM : 0; flags |= (info == null) ? 0 : info.flags; try { ret = dbc.get(key, data, flags); Current = new KeyValuePair <DatabaseEntry, DatabaseEntry>(key, data); return(true); } catch (NotFoundException) { Current = new KeyValuePair <DatabaseEntry, DatabaseEntry>(); return(false); } }
/// <summary> /// Retrieve a specific numbered key/data pair from the database. /// </summary> /// <param name="recno"> /// The record number of the record to be retrieved. /// </param> /// <param name="txn"> /// <paramref name="txn"/> is a Transaction object returned from /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if /// the operation is part of a Berkeley DB Concurrent Data Store group, /// <paramref name="txn"/> is a handle returned from /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. /// </param> /// <param name="info">The locking behavior to use.</param> /// <returns> /// A <see cref="KeyValuePair{T,T}"/> whose Key /// parameter is <paramref name="recno"/> and whose Value parameter is /// the retrieved data. /// </returns> public KeyValuePair<DatabaseEntry, DatabaseEntry> Get( uint recno, Transaction txn, LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); key.Data = BitConverter.GetBytes(recno); return Get(key, null, txn, info, DbConstants.DB_SET_RECNO); }
/* * Move the cursor to last record in a nonempty * database. The returning value should be true. */ public void MoveCursorToLast(Cursor dbc, LockingInfo lck) { if (lck == null) Assert.IsTrue(dbc.MoveLast()); else Assert.IsTrue(dbc.MoveLast(lck)); }
public void TestMoveLastWithLockingInfo() { testName = "TestMoveLastWithLockingInfo"; SetUpTest(true); string dbFileName = testName + ".db"; string dbSecFileName = testName + "_sec.db"; /* * Open environment, primary database and * secondary database. */ BTreeDatabase db; DatabaseEnvironment env; SecondaryBTreeDatabase secDB; OpenSecDBInTxn(testHome, dbFileName, dbSecFileName, out env, out db, out secDB); // Write ten records into the database. WriteRecordsInTxn(db, env); /* * Move the cursor to the last record(10, 6), that is * record(6, 10) in primary database. */ Transaction cursorTxn = env.BeginTransaction(); SecondaryCursor cursor = secDB.SecondaryCursor(cursorTxn); LockingInfo lockingInfo = new LockingInfo(); lockingInfo.IsolationDegree = Isolation.DEGREE_THREE; lockingInfo.ReadModifyWrite = true; Assert.IsTrue(cursor.MoveLast(lockingInfo)); Assert.AreEqual(BitConverter.GetBytes((int)10), cursor.Current.Key.Data); Assert.IsTrue(cursor.MoveLast( new DatabaseEntry(0, 1), new DatabaseEntry(), new DatabaseEntry(2, 2), lockingInfo)); CheckPartial(cursor.Current.Key, 0, 1, null, 0, 0, cursor.Current.Value.Value, 2, 2); /* Disable the test. Assert.IsTrue(cursor.MoveLast( new DatabaseEntry(0, 1), new DatabaseEntry(1, 1), new DatabaseEntry(2, 2), lockingInfo)); CheckPartial(cursor.Current.Key, 0, 1, cursor.Current.Value.Key, 1, 1, cursor.Current.Value.Value, 2, 2);*/ cursor.Close(); cursorTxn.Commit(); // Close all. secDB.Close(); db.Close(); env.Close(); }
public void TestMoveNextWithLockingInfo() { testName = "TestMoveNextWithLockingInfo"; SetUpTest(true); string dbFileName = testName + ".db"; string dbSecFileName = testName + "_sec.db"; /* * Open environment, primary database and * secondary database. */ BTreeDatabase db; DatabaseEnvironment env; SecondaryBTreeDatabase secDB; OpenSecDBInTxn(testHome, dbFileName, dbSecFileName, out env, out db, out secDB); // Write ten records into the database. WriteRecordsInTxn(db, env); /* * Move cursor to the first record and move to next * record for five times. */ Transaction cursorTxn = env.BeginTransaction(); SecondaryCursor cursor = secDB.SecondaryCursor(cursorTxn); LockingInfo lockingInfo = new LockingInfo(); lockingInfo.IsolationDegree = Isolation.DEGREE_THREE; lockingInfo.ReadModifyWrite = true; cursor.MoveFirst(lockingInfo); for (int i = 0; i < 5; i++) { Assert.IsTrue(cursor.MoveNext(lockingInfo)); cursor.MovePrev(lockingInfo); Assert.IsTrue(cursor.MoveNext( new DatabaseEntry(0, 1), new DatabaseEntry(), new DatabaseEntry(2, 2), lockingInfo)); CheckPartial(cursor.Current.Key, 0, 1, null, 0, 0, cursor.Current.Value.Value, 2, 2); /* Disable the test. Assert.IsTrue(cursor.MoveNext( new DatabaseEntry(0, 1), new DatabaseEntry(1, 1), new DatabaseEntry(2, 2), lockingInfo)); CheckPartial(cursor.Current.Key, 0, 1, cursor.Current.Value.Key, 1, 1, cursor.Current.Value.Value, 2, 2);*/ } cursor.Close(); cursorTxn.Commit(); // Close all. secDB.Close(); db.Close(); env.Close(); }
/* * Move the cursor to previous unique record in a * database with more than 2 records. The returning * value should be true. */ public void MoveCursorToPrevUnique(Cursor dbc, LockingInfo lck) { for (int i = 0; i < 5; i++) if (lck == null) dbc.MovePrevUnique(); else dbc.MovePrevUnique(lck); }
public void MoveToPosWithLockingInfo(string home, string dbFileName, string dbSecFileName, bool ifPair) { // Open a primary database and its secondary database. BTreeDatabase db; DatabaseEnvironment env; SecondaryBTreeDatabase secDB; OpenSecDBInTxn(home, dbFileName, dbSecFileName, out env, out db, out secDB); // Write ten records into the database. WriteRecordsInTxn(db, env); // Create an secondary cursor. Transaction cursorTxn = env.BeginTransaction(); SecondaryCursor secCursor = secDB.SecondaryCursor( cursorTxn); DatabaseEntry key = new DatabaseEntry( BitConverter.GetBytes((int)0)); LockingInfo lockingInfo = new LockingInfo(); lockingInfo.IsolationDegree = Isolation.DEGREE_THREE; lockingInfo.ReadModifyWrite = true; if (ifPair == false) { Assert.IsTrue(secCursor.Move( key, true, lockingInfo)); Assert.IsTrue(secCursor.Move(key, new DatabaseEntry(), new DatabaseEntry(2, 2), true)); CheckPartial(null, 0, 0, null, 0, 0, secCursor.Current.Value.Value, 2, 2); /* Disable the test. Assert.IsTrue(secCursor.Move(key, new DatabaseEntry(1, 1), new DatabaseEntry(2, 2), true)); CheckPartial(null, 0, 0, secCursor.Current.Value.Key, 1, 1, secCursor.Current.Value.Value, 2, 2);*/ byte[] partByte = new byte[] {key.Data[2]}; key = new DatabaseEntry(partByte, 2, 1); Assert.IsTrue(secCursor.Move(key, false)); CheckPartial(secCursor.Current.Key, 2, 1, null, 0, 0, null, 0, 0); } else { KeyValuePair<DatabaseEntry, KeyValuePair< DatabaseEntry, DatabaseEntry>> pair; pair = new KeyValuePair<DatabaseEntry, KeyValuePair<DatabaseEntry, DatabaseEntry>>(key, new KeyValuePair<DatabaseEntry, DatabaseEntry>( key, key)); Assert.IsTrue(secCursor.Move(pair, true, lockingInfo)); } secCursor.Close(); cursorTxn.Commit(); secDB.Close(); db.Close(); env.Close(); }
/* * Move the cursor to last record in a nonempty * database. The returning value should be true. */ public void MoveCursorToLast(Cursor dbc, uint kOffset, uint kLen, uint dOffset, uint dLen, LockingInfo lck) { DatabaseEntry key = new DatabaseEntry(kOffset, kLen); DatabaseEntry data = new DatabaseEntry(dOffset, dLen); if (lck == null) { Assert.IsTrue(dbc.MoveLast()); Assert.IsTrue(dbc.MoveLast(key, data)); } else { Assert.IsTrue(dbc.MoveLast(lck)); Assert.IsTrue(dbc.MoveLast(key, data, lck)); } CheckPartial(dbc.Current.Key, kOffset, kLen, dbc.Current.Value, dOffset, dLen); }
/* * Move the cursor to previous record in the database. * The returning value should be true; */ public void MoveCursorToPrev(Cursor dbc, LockingInfo lck) { if (lck == null) { dbc.MoveLast(); for (int i = 0; i < 5; i++) Assert.IsTrue(dbc.MovePrev()); } else { dbc.MoveLast(lck); for (int i = 0; i < 5; i++) Assert.IsTrue(dbc.MovePrev(lck)); } }
/// <summary> /// Position the cursor at a specific key/data pair in the database, and /// store the key/data pair and as many ensuing key/data pairs that can /// fit in a buffer the size of one database page in /// <see cref="Cursor.CurrentMultipleKey"/>. /// </summary> /// <param name="recno"> /// The specific numbered record of the database at which to position /// the cursor. /// </param> /// <param name="info">The locking behavior to use</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool MoveMultipleKey(uint recno, LockingInfo info) { return(MoveMultipleKey(recno, (int)pgsz, info)); }
/* * Move the cursor to next unique record in the database. * The returning value should be true. */ public void MoveCursorToNextUnique(Cursor dbc, uint kOffset, uint kLen, uint dOffset, uint dLen, LockingInfo lck) { for (int i = 0; i < 5; i++) { if (lck == null) { Assert.IsTrue(dbc.MoveNextUnique()); Assert.IsTrue(dbc.MoveNextUnique( new DatabaseEntry(kOffset, kLen), new DatabaseEntry(dOffset, dLen))); } else { Assert.IsTrue(dbc.MoveNextUnique(lck)); Assert.IsTrue(dbc.MoveNextUnique( new DatabaseEntry(kOffset, kLen), new DatabaseEntry(dOffset, dLen), lck)); } CheckPartial(dbc.Current.Key, kOffset, kLen, dbc.Current.Value, dOffset, dLen); } }
/* * Move the cursor to previous record in the database. * The returning value should be true; */ public void MoveCursorToPrev(Cursor dbc, uint kOffset, uint kLen, uint dOffset, uint dLen, LockingInfo lck) { if (lck == null) { dbc.MoveLast(); for (int i = 0; i < 5; i++) { Assert.IsTrue(dbc.MovePrev()); dbc.MoveNext(); Assert.IsTrue(dbc.MovePrev( new DatabaseEntry(kOffset, kLen), new DatabaseEntry(dOffset, dLen))); CheckPartial( dbc.Current.Key, kOffset, kLen, dbc.Current.Value, dOffset, dLen); } } else { dbc.MoveLast(lck); for (int i = 0; i < 5; i++) { Assert.IsTrue(dbc.MovePrev(lck)); dbc.MoveNext(); Assert.IsTrue(dbc.MovePrev( new DatabaseEntry(kOffset, kLen), new DatabaseEntry(dOffset, dLen), lck)); CheckPartial( dbc.Current.Key, kOffset, kLen, dbc.Current.Value, dOffset, dLen); } } }
/* * Move the cursor to a duplicate record and then to * another duplicate one. And finally move to it previous * one. Since the previous duplicate one exist, the return * value of move previous duplicate record should be * true; */ public void MoveCursorToPrevDuplicate(Cursor dbc, uint kOffset, uint kLen, uint dOffset, uint dLen, LockingInfo lck) { if (lck == null) { dbc.Move(new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("key")), true); dbc.MoveNextDuplicate(); Assert.IsTrue(dbc.MovePrevDuplicate()); dbc.Move(new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("key")), true); dbc.MoveNextDuplicate(); Assert.IsTrue(dbc.MovePrevDuplicate( new DatabaseEntry(kOffset, kLen), new DatabaseEntry(dOffset, dLen))); } else { dbc.Move(new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("key")), true, lck); dbc.MoveNextDuplicate(lck); Assert.IsTrue(dbc.MovePrevDuplicate(lck)); dbc.Move(new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("key")), true, lck); dbc.MoveNextDuplicate(lck); Assert.IsTrue(dbc.MovePrevDuplicate( new DatabaseEntry(kOffset, kLen), new DatabaseEntry(dOffset, dLen), lck)); } CheckPartial(dbc.Current.Key, kOffset, kLen, dbc.Current.Value, dOffset, dLen); }
public void TestRefresh() { BTreeDatabase db; BTreeCursor cursor; DatabaseEnvironment env; Transaction txn; testName = "TestRefresh"; SetUpTest(true); GetCursorInBtreeDBWithoutEnv(testHome, testName, out db, out cursor); // Write a record with cursor and Refresh the cursor. MoveCursorToCurrentRec(cursor, 1, 1, 2, 2, null); cursor.Dispose(); db.Dispose(); Configuration.ClearDir(testHome); GetCursorInBtreeDBInTDS(testHome, testName, null, out env, out db, out cursor, out txn); LockingInfo lockingInfo = new LockingInfo(); lockingInfo.IsolationDegree = Isolation.DEGREE_ONE; MoveCursorToCurrentRec(cursor, 1, 1, 2, 2, lockingInfo); cursor.Close(); txn.Commit(); db.Close(); env.Close(); }
/* * Move the cursor to the next duplicate record in * the database which has more than 2 duplicate * records. The returning value should be true. */ public void MoveCursorToNextDuplicate(Cursor dbc, LockingInfo lck) { DatabaseEntry key = new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("key")); /* * The cursor should point to any record in the * database before it move to the next duplicate * record. */ if (lck == null) { dbc.Move(key, true); Assert.IsTrue(dbc.MoveNextDuplicate()); } else { /* * Both the move and move next duplicate * operation should use LockingInfo. If any * one doesn't use LockingInfo, deadlock still * occurs. */ dbc.Move(key, true, lck); Assert.IsTrue(dbc.MoveNextDuplicate(lck)); } }
/// <summary> /// Iterate over the values associated with the keys to which each /// <see cref="SecondaryCursor"/> passed to <see cref="Database.Join"/> /// was initialized. Any data value that appears in all /// <see cref="SecondaryCursor"/>s is then used as a key into the /// primary, and the key/data pair found in the primary is stored in /// <see cref="Current"/>. /// </summary> /// <param name="info">The locking behavior to use.</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool MoveNext(LockingInfo info) { return(MoveNext(info, false)); }
/* * Move the cursor to next unique record in the database. * The returning value should be true. */ public void MoveCursorToNextUnique(Cursor dbc, LockingInfo lck) { for (int i = 0; i < 5; i++) { if (lck == null) Assert.IsTrue(dbc.MoveNextUnique()); else Assert.IsTrue(dbc.MoveNextUnique(lck)); } }
/// <summary> /// Iterate over the values associated with the keys to which each /// <see cref="SecondaryCursor"/> passed to <see cref="Database.Join"/> /// was initialized. Any data value that appears in all /// <see cref="SecondaryCursor"/>s is then stored in /// <see cref="Current">Current.Key</see>. /// </summary> /// <remarks> /// <see cref="Current">Current.Value</see> contains an empty /// <see cref="DatabaseEntry"/>. /// </remarks> /// <param name="info">The locking behavior to use.</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool MoveNextItem(LockingInfo info) { return(MoveNext(info, true)); }
/* * Move the cursor to a duplicate record and then to * another duplicate one. And finally move to it previous * one. Since the previous duplicate one exist, the return * value of move previous duplicate record should be * true; */ public void MoveCursorToPrevDuplicate(Cursor dbc, LockingInfo lck) { if (lck == null) { dbc.Move(new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("key")), true); dbc.MoveNextDuplicate(); Assert.IsTrue(dbc.MovePrevDuplicate()); } else { dbc.Move(new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("key")),true, lck); dbc.MoveNextDuplicate(lck); Assert.IsTrue(dbc.MovePrevDuplicate(lck)); } }
/// <summary> /// Position the cursor at a specific key/data pair in the database, and /// store the key/data pair and as many ensuing key/data pairs that can /// fit in a buffer the size of one database page in /// <see cref="Cursor.CurrentMultipleKey"/>. /// </summary> /// <param name="recno"> /// The specific numbered record of the database at which to position /// the cursor. /// </param> /// <param name="BufferSize"> /// The size of a buffer to fill with key/data pairs. Must be at least /// the page size of the underlying database and be a multiple of 1024. /// </param> /// <param name="info">The locking behavior to use</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool MoveMultipleKey( uint recno, int BufferSize, LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); key.Data = BitConverter.GetBytes(recno); DatabaseEntry data = new DatabaseEntry(); return base.GetMultiple( key, data, BufferSize, DbConstants.DB_SET_RECNO, info, true); }
public void RdMfWt() { Transaction txn = paramEnv.BeginTransaction(); Cursor dbc = paramDB.Cursor(txn); try { LockingInfo lck = new LockingInfo(); lck.ReadModifyWrite = true; // Read record. cursorFunc(dbc, lck); // Block the current thread until event is set. signal.WaitOne(); // Write new records into database. DatabaseEntry key = new DatabaseEntry( BitConverter.GetBytes(55)); DatabaseEntry data = new DatabaseEntry( BitConverter.GetBytes(55)); dbc.Add(new KeyValuePair<DatabaseEntry, DatabaseEntry>(key, data)); dbc.Close(); txn.Commit(); } catch (DeadlockException) { dbc.Close(); txn.Abort(); } }
/// <summary> /// If a key/data pair in the database matches <paramref name="key"/> /// and <paramref name="data"/>, return the key and all duplicate data /// items. /// </summary> /// <param name="key">The key to search for</param> /// <param name="data">The data to search for</param> /// <param name="BufferSize"> /// The initial size of the buffer to fill with duplicate data items. If /// the buffer is not large enough, it is automatically resized. /// </param> /// <param name="txn"> /// <paramref name="txn"/> is a Transaction object returned from /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if /// the operation is part of a Berkeley DB Concurrent Data Store group, /// <paramref name="txn"/> is a handle returned from /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. /// </param> /// <param name="info">The locking behavior to use.</param> /// <exception cref="NotFoundException"> /// A NotFoundException is thrown if <paramref name="key"/> and /// <paramref name="data"/> are not in the database. /// </exception> /// <exception cref="KeyEmptyException"> /// A KeyEmptyException is thrown if the database is a /// <see cref="QueueDatabase"/> or <see cref="RecnoDatabase"/> /// database and <paramref name="key"/> exists, but was never explicitly /// created by the application or was later deleted. /// </exception> /// <returns> /// A <see cref="KeyValuePair{T,T}"/> /// whose Key parameter is <paramref name="key"/> and whose Value /// parameter is the retrieved data items. /// </returns> public KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> GetBothMultiple( DatabaseEntry key, DatabaseEntry data, int BufferSize, Transaction txn, LockingInfo info) { KeyValuePair<DatabaseEntry, DatabaseEntry> kvp; int datasz = (int)data.Data.Length; for (; ; ) { byte[] udata = new byte[BufferSize]; Array.Copy(data.Data, udata, datasz); data.UserData = udata; data.size = (uint)datasz; try { kvp = Get(key, data, txn, info, DbConstants.DB_MULTIPLE | DbConstants.DB_GET_BOTH); break; } catch (MemoryException) { int sz = (int)data.size; if (sz > BufferSize) BufferSize = sz; else BufferSize *= 2; } } MultipleDatabaseEntry dbe = new MultipleDatabaseEntry(kvp.Value); return new KeyValuePair<DatabaseEntry, MultipleDatabaseEntry>( kvp.Key, dbe); }
public void TestRefreshWithLockingInfo() { testName = "TestRefreshWithLockingInfo"; SetUpTest(true); string dbFileName = testName + ".db"; string dbSecFileName = testName + "_sec.db"; /* * Open environment, primary database and * secondary database. */ BTreeDatabase db; DatabaseEnvironment env; SecondaryBTreeDatabase secDB; OpenSecDBInTxn(testHome, dbFileName, dbSecFileName, out env, out db, out secDB); // Write ten records into the database. WriteRecordsInTxn(db, env); Transaction cursorTxn = env.BeginTransaction(); SecondaryCursor cursor = secDB.SecondaryCursor(cursorTxn); LockingInfo lockingInfo = new LockingInfo(); lockingInfo.IsolationDegree = Isolation.DEGREE_TWO; lockingInfo.ReadModifyWrite = true; // Move cursor to a record and refresh it. KeyValuePair<DatabaseEntry, KeyValuePair< DatabaseEntry, DatabaseEntry>> pair; DatabaseEntry pKey, pData; pKey = new DatabaseEntry(BitConverter.GetBytes((int)6)); pData = new DatabaseEntry(BitConverter.GetBytes((int)10)); pair = new KeyValuePair<DatabaseEntry, KeyValuePair< DatabaseEntry, DatabaseEntry>>(pData, new KeyValuePair<DatabaseEntry, DatabaseEntry>( pKey, pData)); cursor.Move(pair, true, lockingInfo); Assert.IsTrue(cursor.Refresh(lockingInfo)); Assert.AreEqual(pData.Data, cursor.Current.Key.Data); Assert.AreEqual(pKey.Data, cursor.Current.Value.Key.Data); Assert.IsTrue(cursor.Refresh( new DatabaseEntry(0, 1), new DatabaseEntry(), new DatabaseEntry(2, 2), lockingInfo)); CheckPartial(cursor.Current.Key, 0, 1, null, 0, 0, cursor.Current.Value.Value, 2, 2); /* Disable the test. Assert.IsTrue(cursor.Refresh( new DatabaseEntry(0, 1), new DatabaseEntry(1, 1), new DatabaseEntry(2, 2), lockingInfo)); CheckPartial(cursor.Current.Key, 0, 1, cursor.Current.Value.Key, 1, 1, cursor.Current.Value.Value, 2, 2);*/ cursor.Close(); cursorTxn.Commit(); // Close all. secDB.Close(); db.Close(); env.Close(); }
/* * Move the cursor to current existing record. The returning * value should be true. */ public void MoveCursorToCurrentRec(Cursor dbc, uint kOffset, uint kLen, uint dOffset, uint dLen, LockingInfo lck) { DatabaseEntry key, data; // Add a record to the database. KeyValuePair<DatabaseEntry, DatabaseEntry> pair; key = new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("key")); data = new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("data")); pair = new KeyValuePair<DatabaseEntry, DatabaseEntry>(key, data); dbc.Add(pair); if (lck == null) Assert.IsTrue(dbc.Refresh()); else Assert.IsTrue(dbc.Refresh(lck)); Assert.AreEqual(key.Data, dbc.Current.Key.Data); Assert.AreEqual(data.Data, dbc.Current.Value.Data); key = new DatabaseEntry(kOffset, kLen); data = new DatabaseEntry(dOffset, dLen); if (lck == null) Assert.IsTrue(dbc.Refresh(key, data)); else Assert.IsTrue(dbc.Refresh(key, data, lck)); CheckPartial(dbc.Current.Key, kOffset, kLen, dbc.Current.Value, dOffset, dLen); }
public void TestMoveNextUniqueWithLockingInfo() { testName = "TestMoveNextUniqueWithLockingInfo"; SetUpTest(true); string dbFileName = testName + ".db"; string dbSecFileName = testName + "_sec.db"; /* * Open environment, primary database and * secondary database. */ BTreeDatabase db; DatabaseEnvironment env; SecondaryBTreeDatabase secDB; OpenSecDBInTxn(testHome, dbFileName, dbSecFileName, out env, out db, out secDB); // Write ten records into the database. WriteRecordsInTxn(db, env); /* * Move cursor to duplicate record. Since the duplicate * record has the largest key, moving to the next * unique record should fail. */ Transaction cursorTxn = env.BeginTransaction(); SecondaryCursor cursor = secDB.SecondaryCursor(cursorTxn); LockingInfo lockingInfo = new LockingInfo(); lockingInfo.IsolationDegree = Isolation.DEGREE_THREE; lockingInfo.ReadModifyWrite = true; cursor.Move(new DatabaseEntry( BitConverter.GetBytes((int)10)), true); Assert.IsFalse(cursor.MoveNextUnique(lockingInfo)); cursor.Move(new DatabaseEntry( BitConverter.GetBytes((int)3)), true, lockingInfo); Assert.IsTrue(cursor.MoveNextUnique( new DatabaseEntry(0, 1), new DatabaseEntry(), new DatabaseEntry(2, 2), lockingInfo)); CheckPartial(cursor.Current.Key, 0, 1, null, 0, 0, cursor.Current.Value.Value, 2, 2); /* Disable the test. Assert.IsTrue(cursor.MoveNextUnique( new DatabaseEntry(0, 1), new DatabaseEntry(1, 1), new DatabaseEntry(2, 2), lockingInfo)); CheckPartial(cursor.Current.Key, 0, 1, cursor.Current.Value.Key, 1, 1, cursor.Current.Value.Value, 2, 2);*/ cursor.Close(); cursorTxn.Commit(); // Close all. secDB.Close(); db.Close(); env.Close(); }
/* * Move the cursor to current existing record. The returning * value should be true. */ public void MoveCursorToCurrentRec(Cursor dbc, LockingInfo lck) { // Add a record to the database. KeyValuePair<DatabaseEntry, DatabaseEntry> pair; pair = new KeyValuePair<DatabaseEntry,DatabaseEntry>( new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("key")), new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("key"))); dbc.Add(pair); if (lck == null) dbc.Refresh(); else dbc.Refresh(lck); Assert.IsNotNull(dbc.Current.Key); }
/// <summary> /// Position the cursor at a specific key/data pair in the database, and /// store the key/data pair and as many ensuing key/data pairs that can /// fit in a buffer the size of one database page in /// <see cref="Cursor.CurrentMultipleKey"/>. /// </summary> /// <param name="recno"> /// The specific numbered record of the database at which to position /// the cursor. /// </param> /// <param name="info">The locking behavior to use</param> /// <returns> /// True if the cursor was positioned successfully, false otherwise. /// </returns> public bool MoveMultipleKey(uint recno, LockingInfo info) { return MoveMultipleKey(recno, (int)pgsz, info); }
/* * Move the cursor to previous unique record in a * database with more than 2 records. The returning * value should be true. */ public void MoveCursorToPrevUnique(Cursor dbc, uint kOffset, uint kLen, uint dOffset, uint dLen, LockingInfo lck) { DatabaseEntry key = new DatabaseEntry(kOffset, kLen); DatabaseEntry data = new DatabaseEntry(dOffset, dLen); for (int i = 0; i < 5; i++) { if (lck == null) { Assert.IsTrue(dbc.MovePrevUnique()); Assert.IsTrue( dbc.MovePrevUnique(key, data)); } else { Assert.IsTrue(dbc.MovePrevUnique(lck)); Assert.IsTrue( dbc.MovePrevUnique(key, data, lck)); } CheckPartial(dbc.Current.Key, kOffset, kLen, dbc.Current.Value, dOffset, dLen); } }
/// <summary> /// Return the record number associated with the cursor's current /// position. /// </summary> /// <param name="info">The locking behavior to use</param> /// <returns>The record number associated with the cursor.</returns> public uint Recno(LockingInfo info) { DatabaseEntry key = new DatabaseEntry(); DatabaseEntry data = new DatabaseEntry(); base.Get(key, data, DbConstants.DB_GET_RECNO, info); return BitConverter.ToUInt32(base.Current.Value.Data, 0); }
/* * Move the cursor to an exisiting key and key/data * pair with LockingInfo. */ public void MoveCursor(Cursor dbc, LockingInfo lck) { DatabaseEntry key, data; KeyValuePair<DatabaseEntry, DatabaseEntry> pair; key = new DatabaseEntry( BitConverter.GetBytes((int)0)); data = new DatabaseEntry( BitConverter.GetBytes((int)0)); pair = new KeyValuePair<DatabaseEntry, DatabaseEntry>(key, data); // Move to an existing key. Assert.IsTrue(dbc.Move(key, true, lck)); // Move to an existing key/data pair. Assert.IsTrue(dbc.Move(pair, true, lck)); }
/// <summary> /// Retrieve a key and all duplicate data items from the database. /// </summary> /// <param name="key">The key to search for</param> /// <param name="BufferSize"> /// The initial size of the buffer to fill with duplicate data items. If /// the buffer is not large enough, it is automatically resized. /// </param> /// <param name="txn"> /// <paramref name="txn"/> is a Transaction object returned from /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if /// the operation is part of a Berkeley DB Concurrent Data Store group, /// <paramref name="txn"/> is a handle returned from /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. /// </param> /// <param name="info">The locking behavior to use.</param> /// <returns> /// A <see cref="KeyValuePair{T,T}"/> /// whose Key parameter is <paramref name="key"/> and whose Value /// parameter is the retrieved data items. /// </returns> public KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> GetMultiple( DatabaseEntry key, int BufferSize, Transaction txn, LockingInfo info) { KeyValuePair<DatabaseEntry, DatabaseEntry> kvp; DatabaseEntry data = new DatabaseEntry(); for (; ; ) { data.UserData = new byte[BufferSize]; try { kvp = Get(key, data, txn, info, DbConstants.DB_MULTIPLE); break; } catch (MemoryException) { int sz = (int)data.size; if (sz > BufferSize) BufferSize = sz; else BufferSize *= 2; } } MultipleDatabaseEntry dbe = new MultipleDatabaseEntry(kvp.Value); return new KeyValuePair<DatabaseEntry, MultipleDatabaseEntry>( kvp.Key, dbe); }
/* * Move the cursor to an exisiting key and key/data * pair with LockingInfo. */ public void MoveCursor(Cursor dbc, uint kOffset, uint kLen, uint dOffset, uint dLen, LockingInfo lck) { DatabaseEntry key, data; KeyValuePair<DatabaseEntry, DatabaseEntry> pair; key = new DatabaseEntry( BitConverter.GetBytes((int)0)); data = new DatabaseEntry( BitConverter.GetBytes((int)0)); pair = new KeyValuePair<DatabaseEntry, DatabaseEntry>(key, data); if (lck == null) { // Move to an existing key. Assert.IsTrue(dbc.Move(key, true)); // Move to an existing key/data pair. Assert.IsTrue(dbc.Move(pair, true)); /* Move to an existing key, and return * partial data. */ data = new DatabaseEntry(dOffset, dLen); Assert.IsTrue(dbc.Move(key, data, true)); CheckPartial(null, 0, 0, dbc.Current.Value, dOffset, dLen); // Partially key match. byte[] partbytes = new byte[kLen]; for (int i = 0; i < kLen; i++) partbytes[i] = BitConverter.GetBytes( (int)1)[kOffset + i]; key = new DatabaseEntry(partbytes, kOffset, kLen); Assert.IsTrue(dbc.Move(key, false)); Assert.AreEqual(kLen, dbc.Current.Key.Data.Length); CheckPartial(dbc.Current.Key, kOffset, kLen, null, 0, 0); } else { // Move to an existing key. Assert.IsTrue(dbc.Move(key, true, lck)); // Move to an existing key/data pair. Assert.IsTrue(dbc.Move(pair, true, lck)); /* * Move to an existing key, and return * partial data. */ data = new DatabaseEntry(dOffset, dLen); Assert.IsTrue(dbc.Move(key, data, true, lck)); CheckPartial(null, 0, 0, dbc.Current.Value, dOffset, dLen); // Partially key match. byte[] partbytes = new byte[kLen]; for (int i = 0; i < kLen; i++) partbytes[i] = BitConverter.GetBytes( (int)1)[kOffset + i]; key = new DatabaseEntry(partbytes, kOffset, kLen); Assert.IsTrue(dbc.Move(key, false, lck)); Assert.AreEqual(kLen, dbc.Current.Key.Data.Length); CheckPartial(dbc.Current.Key, kOffset, kLen, null, 0, 0); } }