1 /*- 2 * Copyright (c) 2009, 2020 Oracle and/or its affiliates. All rights reserved. 3 * 4 * See the file LICENSE for license information. 5 * 6 */ 7 using System; 8 using System.Collections; 9 using System.Collections.Generic; 10 using System.IO; 11 using System.Text; 12 using System.Xml; 13 using NUnit.Framework; 14 using BerkeleyDB; 15 16 namespace CsharpAPITest 17 { 18 [TestFixture] 19 public class BTreeDatabaseTest : DatabaseTest 20 { 21 22 [TestFixtureSetUp] SetUpTestFixture()23 public void SetUpTestFixture() 24 { 25 testFixtureName = "BTreeDatabaseTest"; 26 base.SetUpTestfixture(); 27 } 28 29 [Test] TestBlob()30 public void TestBlob() 31 { 32 testName = "TestBlob"; 33 SetUpTest(false); 34 // Test opening the external file database without 35 // environment. 36 TestBlobBtreeDatabase(0, null, 6, null, false); 37 38 /* 39 * Test opening the external file database without 40 * environment 41 * but specifying external file directory. 42 */ 43 TestBlobBtreeDatabase(0, null, 6, 44 testHome + "/DBBLOB", true); 45 46 // Test opening the external file database with 47 // environment. 48 TestBlobBtreeDatabase(3, "ENVBLOB", 6, null, false); 49 50 /* 51 * Test opening the external file database with 52 * environment and specifying external file directory. 53 */ 54 TestBlobBtreeDatabase(3, null, 6, "/DBBLOB", true); 55 } 56 57 /* 58 * Test the external file database with or without environment. 59 * 1. Config and open the environment; 60 * 2. Verify the environment external file configs; 61 * 3. Config and open the database; 62 * 4. Verify the database external file configs; 63 * 5. Insert and verify some external file data by database 64 * methods; 65 * 6. Insert some external file data by cursor, update it and 66 * verify 67 * the update by database stream and cursor; 68 * 7. Verify the stats; 69 * 8. Close all handles. 70 * If "blobdbt" is true, set the data DatabaseEntry.Blob as 71 * true, otherwise make the data DatabaseEntry reach the 72 * external file threshold in size. 73 */ TestBlobBtreeDatabase(uint env_threshold, string env_blobdir, uint db_threshold, string db_blobdir, bool blobdbt)74 void TestBlobBtreeDatabase(uint env_threshold, 75 string env_blobdir, uint db_threshold, 76 string db_blobdir, bool blobdbt) 77 { 78 if (env_threshold == 0 && db_threshold == 0) 79 return; 80 81 string btreeDBName = 82 testHome + "/" + testName + ".db"; 83 84 Configuration.ClearDir(testHome); 85 BTreeDatabaseConfig cfg = new BTreeDatabaseConfig(); 86 cfg.Creation = CreatePolicy.ALWAYS; 87 string blrootdir = "__db_bl"; 88 89 // Open the environment and verify the external file 90 // configs. 91 if (env_threshold > 0) 92 { 93 DatabaseEnvironmentConfig envConfig = 94 new DatabaseEnvironmentConfig(); 95 envConfig.AutoCommit = true; 96 envConfig.Create = true; 97 envConfig.UseMPool = true; 98 envConfig.UseLogging = true; 99 envConfig.UseTxns = true; 100 envConfig.UseLocking = true; 101 envConfig.ExternalFileThreshold = env_threshold; 102 if (env_blobdir != null) 103 { 104 envConfig.ExternalFileDir = env_blobdir; 105 blrootdir = env_blobdir; 106 } 107 DatabaseEnvironment env = 108 DatabaseEnvironment.Open( 109 testHome, envConfig); 110 if (env_blobdir == null) 111 Assert.IsNull(env.ExternalFileDir); 112 else 113 Assert.AreEqual(0, env.ExternalFileDir. 114 CompareTo(env_blobdir)); 115 Assert.AreEqual(env_threshold, 116 env.ExternalFileThreshold); 117 cfg.Env = env; 118 btreeDBName = testName + ".db"; 119 } 120 121 // Open the database and verify the external file 122 // configs. 123 if (db_threshold > 0) 124 cfg.ExternalFileThreshold = db_threshold; 125 if (db_blobdir != null) 126 { 127 cfg.ExternalFileDir = db_blobdir; 128 /* 129 * The external file directory setting in the 130 * database is effective only when it is opened 131 * without an environment. 132 */ 133 if (cfg.Env == null) 134 blrootdir = db_blobdir; 135 } 136 137 BTreeDatabase db = 138 BTreeDatabase.Open(btreeDBName, cfg); 139 Assert.AreEqual( 140 db_threshold > 0 ? db_threshold : env_threshold, 141 db.ExternalFileThreshold); 142 if (db_blobdir == null && cfg.Env == null) 143 Assert.IsNull(db.ExternalFileDir); 144 else 145 Assert.AreEqual(0, 146 db.ExternalFileDir.CompareTo(blrootdir)); 147 148 // Insert and verify some external file data by 149 // database methods. 150 string[] records = {"a", "b", "c", "d", "e", "f", "g", 151 "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", 152 "r", "s", "t", "u", "v", "w", "x", "y", "z"}; 153 DatabaseEntry kdbt = new DatabaseEntry(); 154 DatabaseEntry ddbt = new DatabaseEntry(); 155 byte[] kdata, ddata; 156 string str; 157 KeyValuePair<DatabaseEntry, DatabaseEntry> pair; 158 ddbt.ExternalFile = blobdbt; 159 Assert.AreEqual(blobdbt, ddbt.ExternalFile); 160 for (int i = 0; i < records.Length; i++) 161 { 162 kdata = BitConverter.GetBytes(i); 163 str = records[i]; 164 if (!blobdbt) { 165 for (int j = 0; j < db_threshold; j++) 166 str = str + records[i]; 167 } 168 ddata = Encoding.ASCII.GetBytes(str); 169 kdbt.Data = kdata; 170 ddbt.Data = ddata; 171 db.Put(kdbt, ddbt); 172 try 173 { 174 pair = db.Get(kdbt); 175 } 176 catch (DatabaseException) 177 { 178 db.Close(); 179 if (cfg.Env != null) 180 cfg.Env.Close(); 181 throw new TestException(); 182 } 183 Assert.AreEqual(ddata, pair.Value.Data); 184 } 185 186 /* 187 * Insert some external file data by cursor, update it 188 * and verify the update by database stream. 189 */ 190 kdata = BitConverter.GetBytes(records.Length); 191 ddata = Encoding.ASCII.GetBytes("abc"); 192 kdbt.Data = kdata; 193 ddbt.Data = ddata; 194 ddbt.ExternalFile = true; 195 Assert.IsTrue(ddbt.ExternalFile); 196 pair = new KeyValuePair< 197 DatabaseEntry, DatabaseEntry>(kdbt, ddbt); 198 CursorConfig dbcConfig = new CursorConfig(); 199 Transaction txn = null; 200 if (cfg.Env != null) 201 txn = cfg.Env.BeginTransaction(); 202 BTreeCursor cursor = db.Cursor(dbcConfig, txn); 203 cursor.Add(pair); 204 DatabaseStreamConfig dbsc = new DatabaseStreamConfig(); 205 dbsc.SyncPerWrite = true; 206 DatabaseStream dbs = cursor.DbStream(dbsc); 207 Assert.AreNotEqual(null, dbs); 208 Assert.IsFalse(dbs.GetConfig.ReadOnly); 209 Assert.IsTrue(dbs.GetConfig.SyncPerWrite); 210 Assert.AreEqual(3, dbs.Size()); 211 DatabaseEntry sdbt = dbs.Read(0, 3); 212 Assert.IsNotNull(sdbt); 213 Assert.AreEqual(ddata, sdbt.Data); 214 sdbt = new DatabaseEntry( 215 Encoding.ASCII.GetBytes("defg")); 216 Assert.IsTrue(dbs.Write(sdbt, 3)); 217 Assert.AreEqual(7, dbs.Size()); 218 sdbt = dbs.Read(0, 7); 219 Assert.IsNotNull(sdbt); 220 Assert.AreEqual( 221 Encoding.ASCII.GetBytes("abcdefg"), sdbt.Data); 222 dbs.Close(); 223 224 /* 225 * Verify the database stream can not write when it is 226 * configured to be read-only. 227 */ 228 dbsc.ReadOnly = true; 229 dbs = cursor.DbStream(dbsc); 230 Assert.IsTrue(dbs.GetConfig.ReadOnly); 231 try 232 { 233 dbs.Write(sdbt, 7); 234 throw new TestException(); 235 } 236 catch (DatabaseException) 237 { 238 } 239 dbs.Close(); 240 241 // Verify the update by cursor. 242 Assert.IsTrue(cursor.Move(kdbt, true)); 243 pair = cursor.Current; 244 Assert.AreEqual(Encoding.ASCII.GetBytes("abcdefg"), 245 pair.Value.Data); 246 cursor.Close(); 247 if (cfg.Env != null) 248 txn.Commit(); 249 250 /* 251 * Verify the external file files are created 252 * in the expected location. 253 * This part of test code is disabled since 254 * BTreeDatabase.BlobSubDir is not exposed to users. 255 */ 256 257 //if (cfg.Env != null) 258 // blrootdir = testHome + "/" + blrootdir; 259 //string blobdir = blrootdir + "/" + db.BlobSubDir; 260 //Assert.AreEqual(records.Length + 1, 261 // Directory.GetFiles(blobdir, "__db.bl*").Length); 262 //Assert.AreEqual(1, Directory.GetFiles( 263 // blobdir, "__db_blob_meta.db").Length); 264 265 // Verify the stats. 266 BTreeStats st = db.Stats(); 267 Assert.AreEqual(records.Length + 1, st.nExternalFiles); 268 269 // Close all handles. 270 db.Close(); 271 if (cfg.Env != null) 272 cfg.Env.Close(); 273 274 /* 275 * Remove the default external file directory when it 276 * is not under the test home. 277 */ 278 if (db_blobdir == null && cfg.Env == null) 279 Directory.Delete("__db_bl", true); 280 } 281 282 [Test] TestCompactWithoutTxn()283 public void TestCompactWithoutTxn() 284 { 285 int i, nRecs; 286 nRecs = 1000; 287 testName = "TestCompactWithoutTxn"; 288 SetUpTest(true); 289 string btreeDBFileName = testHome + "/" + 290 testName + ".db"; 291 292 BTreeDatabaseConfig btreeDBConfig = 293 new BTreeDatabaseConfig(); 294 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 295 // The minimum page size 296 btreeDBConfig.PageSize = 512; 297 btreeDBConfig.BTreeCompare = 298 new EntryComparisonDelegate(dbIntCompare); 299 using (BTreeDatabase btreeDB = BTreeDatabase.Open( 300 btreeDBFileName, btreeDBConfig)) 301 { 302 DatabaseEntry key; 303 DatabaseEntry data; 304 305 // Fill the database with entries from 0 to 999 306 for (i = 0; i < nRecs; i++) 307 { 308 key = new DatabaseEntry( 309 BitConverter.GetBytes(i)); 310 data = new DatabaseEntry( 311 ASCIIEncoding.ASCII.GetBytes(Configuration.RandomString(100))); 312 btreeDB.Put(key, data); 313 } 314 315 /* 316 * Delete entries below 50, between 300 and 317 * 500 and above 700 318 */ 319 for (i = 0; i < nRecs; i++) 320 if (i < (int)(nRecs * 0.05) || 321 i > (int)(nRecs * 0.7) || 322 (i < (int)(nRecs * 0.5) && 323 i > (int)(nRecs * 0.3))) 324 { 325 key = new DatabaseEntry( 326 BitConverter.GetBytes(i)); 327 btreeDB.Delete(key); 328 } 329 330 btreeDB.Sync(); 331 long fileSize = new FileInfo( 332 btreeDBFileName).Length; 333 334 // Compact database 335 CompactConfig cCfg = new CompactConfig(); 336 cCfg.FillPercentage = 80; 337 cCfg.Pages = 4; 338 cCfg.Timeout = 1000; 339 cCfg.TruncatePages = true; 340 cCfg.start = new DatabaseEntry( 341 BitConverter.GetBytes(1)); 342 cCfg.stop = new DatabaseEntry( 343 BitConverter.GetBytes(7000)); 344 CompactData compactData = btreeDB.Compact(cCfg); 345 // Verify output statistics fields. 346 Assert.AreEqual(0, compactData.Deadlocks); 347 Assert.LessOrEqual(0, compactData.EmptyBuckets); 348 Assert.LessOrEqual(0, compactData.Levels); 349 Assert.Less(0, compactData.PagesExamined); 350 Assert.Less(0, compactData.PagesFreed); 351 Assert.Less(compactData.PagesFreed, 352 compactData.PagesTruncated); 353 354 btreeDB.Sync(); 355 long compactedFileSize = 356 new FileInfo(btreeDBFileName).Length; 357 Assert.Less(compactedFileSize, fileSize); 358 } 359 } 360 361 [Test] TestCompression()362 public void TestCompression() { 363 testName = "TestCompression"; 364 SetUpTest(true); 365 string btreeDBName = testHome + "/" + testName + ".db"; 366 367 BTreeDatabaseConfig cfg = new BTreeDatabaseConfig(); 368 cfg.Creation = CreatePolicy.ALWAYS; 369 cfg.SetCompression(compress, decompress); 370 BTreeDatabase db = BTreeDatabase.Open(btreeDBName, cfg); 371 DatabaseEntry key, data; 372 char[] keyData = { 'A', 'A', 'A', 'A' }; 373 data = new DatabaseEntry( 374 ASCIIEncoding.ASCII.GetBytes("abcdefghij")); 375 int i; 376 for (i = 0; i < 2000; i++) { 377 // Write random data 378 key = new DatabaseEntry( 379 ASCIIEncoding.ASCII.GetBytes(keyData)); 380 db.Put(key, data); 381 382 // Bump the key. Rollover from Z to A if necessary 383 int j = keyData.Length; 384 do { 385 j--; 386 if (keyData[j]++ == 'Z') 387 keyData[j] = 'A'; 388 } while (keyData[j] == 'A'); 389 } 390 db.Close(); 391 } 392 compress(DatabaseEntry prevKey, DatabaseEntry prevData, DatabaseEntry key, DatabaseEntry data, ref byte[] dest, out int size)393 bool compress(DatabaseEntry prevKey, DatabaseEntry prevData, 394 DatabaseEntry key, DatabaseEntry data, ref byte[] dest, out int size) { 395 /* 396 * Just a dummy function that doesn't do any compression. It just 397 * writes the 5 byte key and 10 byte data to the buffer. 398 */ 399 size = key.Data.Length + data.Data.Length; 400 if (size > dest.Length) 401 return false; 402 key.Data.CopyTo(dest, 0); 403 data.Data.CopyTo(dest, key.Data.Length); 404 return true; 405 } 406 decompress( DatabaseEntry prevKey, DatabaseEntry prevData, byte[] compressed, out uint bytesRead)407 KeyValuePair<DatabaseEntry, DatabaseEntry> decompress( 408 DatabaseEntry prevKey, DatabaseEntry prevData, byte[] compressed, out uint bytesRead) { 409 byte[] keyData = new byte[4]; 410 byte[] dataData = new byte[10]; 411 Array.ConstrainedCopy(compressed, 0, keyData, 0, 4); 412 Array.ConstrainedCopy(compressed, 4, dataData, 0, 10); 413 DatabaseEntry key = new DatabaseEntry(keyData); 414 DatabaseEntry data = new DatabaseEntry(dataData); 415 bytesRead = (uint)(key.Data.Length + data.Data.Length); 416 return new KeyValuePair<DatabaseEntry, DatabaseEntry>(key, data); 417 } 418 419 /* 420 * Test the default compression - which is prefix compression 421 * of keys. This should work well with ordered keys and short 422 * data items. 423 */ 424 [Test] TestCompressionDefault()425 public void TestCompressionDefault() { 426 testName = "TestCompressionDefault"; 427 SetUpTest(true); 428 string btreeDBName = testHome + "/" + testName + ".db"; 429 430 BTreeDatabaseConfig cfg = new BTreeDatabaseConfig(); 431 cfg.Creation = CreatePolicy.ALWAYS; 432 BTreeDatabase db = BTreeDatabase.Open(btreeDBName, cfg); 433 DatabaseEntry key, data; 434 char[] keyData = { 'A', 'A', 'A', 'A' }; 435 data = new DatabaseEntry( 436 ASCIIEncoding.ASCII.GetBytes("A")); 437 int i; 438 for (i = 0; i < 5000; i++) { 439 // Write random data 440 key = new DatabaseEntry( 441 ASCIIEncoding.ASCII.GetBytes(keyData)); 442 db.Put(key, data); 443 444 // Bump the key. 445 int j = keyData.Length; 446 do { 447 j--; 448 if (keyData[j]++ == 'Z') 449 keyData[j] = 'A'; 450 } while (keyData[j] == 'A'); 451 } 452 db.Close(); 453 454 FileInfo dbInfo = new FileInfo(btreeDBName); 455 long uncompressedSize = dbInfo.Length; 456 Configuration.ClearDir(testHome); 457 458 cfg = new BTreeDatabaseConfig(); 459 cfg.Creation = CreatePolicy.ALWAYS; 460 cfg.SetCompression(); 461 db = BTreeDatabase.Open(btreeDBName, cfg); 462 keyData = new char[]{ 'A', 'A', 'A', 'A' }; 463 data = new DatabaseEntry( 464 ASCIIEncoding.ASCII.GetBytes("A")); 465 for (i = 0; i < 5000; i++) { 466 // Write random data 467 key = new DatabaseEntry( 468 ASCIIEncoding.ASCII.GetBytes(keyData)); 469 db.Put(key, data); 470 471 // Bump the key. 472 int j = keyData.Length; 473 do { 474 j--; 475 if (keyData[j]++ == 'Z') 476 keyData[j] = 'A'; 477 } while (keyData[j] == 'A'); 478 } 479 Cursor dbc = db.Cursor(); 480 foreach (KeyValuePair<DatabaseEntry, DatabaseEntry> kvp 481 in dbc) 482 i--; 483 dbc.Close(); 484 Assert.AreEqual(i, 0); 485 db.Close(); 486 487 dbInfo = new FileInfo(btreeDBName); 488 Assert.Less(dbInfo.Length, uncompressedSize); 489 Console.WriteLine( 490 "Uncompressed: {0}", uncompressedSize); 491 Console.WriteLine("Compressed: {0}", dbInfo.Length); 492 493 Configuration.ClearDir(testHome); 494 495 cfg = new BTreeDatabaseConfig(); 496 cfg.Creation = CreatePolicy.ALWAYS; 497 cfg.SetCompression(); 498 db = BTreeDatabase.Open(btreeDBName, cfg); 499 for (i = 1023; i < 1124; i++){ 500 key = new DatabaseEntry(BitConverter.GetBytes(i)); 501 data = new DatabaseEntry(BitConverter.GetBytes(i + 3)); 502 db.Put(key, data); 503 } 504 dbc = db.Cursor(); 505 foreach (KeyValuePair<DatabaseEntry, DatabaseEntry> kvp in dbc){ 506 int keyInt = BitConverter.ToInt32(kvp.Key.Data, 0); 507 int dataInt = BitConverter.ToInt32(kvp.Value.Data, 0); 508 Assert.AreEqual(3, dataInt - keyInt); 509 } 510 dbc.Close(); 511 512 db.Close(); 513 } 514 515 [Test, ExpectedException(typeof(AccessViolationException))] TestClose()516 public void TestClose() 517 { 518 testName = "TestClose"; 519 SetUpTest(true); 520 string btreeDBFileName = testHome + "/" + 521 testName + ".db"; 522 523 BTreeDatabaseConfig btreeDBConfig = 524 new BTreeDatabaseConfig(); 525 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 526 BTreeDatabase btreeDB = BTreeDatabase.Open( 527 btreeDBFileName, btreeDBConfig); 528 btreeDB.Close(); 529 DatabaseEntry key = new DatabaseEntry( 530 ASCIIEncoding.ASCII.GetBytes("hi")); 531 DatabaseEntry data = new DatabaseEntry( 532 ASCIIEncoding.ASCII.GetBytes("hi")); 533 btreeDB.Put(key, data); 534 } 535 536 [Test] TestCloseWithoutSync()537 public void TestCloseWithoutSync() 538 { 539 testName = "TestCloseWithoutSync"; 540 SetUpTest(true); 541 string btreeDBName = testName + ".db"; 542 543 DatabaseEnvironmentConfig envConfig = 544 new DatabaseEnvironmentConfig(); 545 envConfig.Create = true; 546 envConfig.ForceFlush = true; 547 envConfig.UseTxns = true; 548 envConfig.UseMPool = true; 549 envConfig.UseLogging = true; 550 envConfig.LogSystemCfg = new LogConfig(); 551 envConfig.LogSystemCfg.ForceSync = false; 552 envConfig.LogSystemCfg.AutoRemove = true; 553 DatabaseEnvironment env = DatabaseEnvironment.Open( 554 testHome, envConfig); 555 556 TransactionConfig txnConfig = new TransactionConfig(); 557 txnConfig.SyncAction = 558 TransactionConfig.LogFlush.WRITE_NOSYNC; 559 Transaction txn = env.BeginTransaction(txnConfig); 560 561 BTreeDatabaseConfig btreeConfig = 562 new BTreeDatabaseConfig(); 563 btreeConfig.Creation = CreatePolicy.ALWAYS; 564 btreeConfig.Env = env; 565 566 BTreeDatabase btreeDB = BTreeDatabase.Open( 567 btreeDBName, btreeConfig, txn); 568 569 DatabaseEntry key = new DatabaseEntry( 570 ASCIIEncoding.ASCII.GetBytes("key")); 571 DatabaseEntry data = new DatabaseEntry( 572 ASCIIEncoding.ASCII.GetBytes("data")); 573 Assert.IsFalse(btreeDB.Exists(key, txn)); 574 btreeDB.Put(key, data, txn); 575 btreeDB.Close(false); 576 txn.Commit(); 577 env.Close(); 578 579 BTreeDatabaseConfig dbConfig = 580 new BTreeDatabaseConfig(); 581 dbConfig.Creation = CreatePolicy.NEVER; 582 using (BTreeDatabase db = BTreeDatabase.Open( 583 testHome + "/" + btreeDBName, dbConfig)) 584 { 585 Assert.IsFalse(db.Exists(key)); 586 } 587 } 588 589 [Test] TestCursorWithoutEnv()590 public void TestCursorWithoutEnv() 591 { 592 BTreeCursor cursor; 593 BTreeDatabase db; 594 string dbFileName; 595 596 testName = "TestCursorWithoutEnv"; 597 SetUpTest(true); 598 dbFileName = testHome + "/" + testName + ".db"; 599 600 // Open btree database. 601 OpenBtreeDB(null, null, dbFileName, out db); 602 603 // Get a cursor. 604 cursor = db.Cursor(); 605 606 /* 607 * Add a record to the database with cursor and 608 * confirm that the record exists in the database. 609 */ 610 CursorTest.AddOneByCursor(db, cursor); 611 612 // Close cursor and database. 613 cursor.Close(); 614 db.Close(); 615 } 616 617 [Test] TestCursorWithConfigInTxn()618 public void TestCursorWithConfigInTxn() 619 { 620 BTreeCursor cursor; 621 BTreeDatabase db; 622 DatabaseEnvironment env; 623 Transaction txn; 624 string dbFileName; 625 626 testName = "TestCursorWithConfigInTxn"; 627 SetUpTest(true); 628 dbFileName = testName + ".db"; 629 630 // Open environment and begin a transaction. 631 632 SetUpEnvAndTxn(testHome, out env, out txn); 633 OpenBtreeDB(env, txn, dbFileName, out db); 634 635 // Config and get a cursor. 636 cursor = db.Cursor(new CursorConfig(), txn); 637 638 /* 639 * Add a record to the database with cursor and 640 * confirm that the record exists in the database. 641 */ 642 CursorTest.AddOneByCursor(db, cursor); 643 644 /* 645 * Close cursor, database, commit the transaction 646 * and close the environment. 647 */ 648 cursor.Close(); 649 db.Close(); 650 txn.Commit(); 651 env.Close(); 652 } 653 654 [Test] TestCursorWithoutConfigInTxn()655 public void TestCursorWithoutConfigInTxn() 656 { 657 BTreeCursor cursor; 658 BTreeDatabase db; 659 DatabaseEnvironment env; 660 Transaction txn; 661 string dbFileName; 662 663 testName = "TestCursorWithoutConfigInTxn"; 664 SetUpTest(true); 665 dbFileName = testName + ".db"; 666 667 // Open environment and begin a transaction. 668 SetUpEnvAndTxn(testHome, out env, out txn); 669 OpenBtreeDB(env, txn, dbFileName, out db); 670 671 // Get a cursor in the transaction. 672 cursor = db.Cursor(txn); 673 674 /* 675 * Add a record to the database with cursor and 676 * confirm that the record exists in the database. 677 */ 678 CursorTest.AddOneByCursor(db, cursor); 679 680 /* 681 * Close cursor, database, commit the transaction 682 * and close the environment. 683 */ 684 cursor.Close(); 685 db.Close(); 686 txn.Commit(); 687 env.Close(); 688 } 689 690 [Test, ExpectedException(typeof(ExpectedTestException))] TestDelete()691 public void TestDelete() 692 { 693 testName = "TestDelete"; 694 SetUpTest(true); 695 string btreeDBFileName = testHome + "/" + 696 testName + ".db"; 697 698 BTreeDatabaseConfig btreeDBConfig = 699 new BTreeDatabaseConfig(); 700 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 701 BTreeDatabase btreeDB = BTreeDatabase.Open( 702 btreeDBFileName, btreeDBConfig); 703 DatabaseEntry key = new DatabaseEntry( 704 ASCIIEncoding.ASCII.GetBytes("key")); 705 DatabaseEntry data = new DatabaseEntry( 706 ASCIIEncoding.ASCII.GetBytes("data")); 707 btreeDB.Put(key, data); 708 btreeDB.Delete(key); 709 try 710 { 711 btreeDB.Get(key); 712 } 713 catch (NotFoundException) 714 { 715 throw new ExpectedTestException(); 716 } 717 finally 718 { 719 btreeDB.Close(); 720 } 721 } 722 723 [Test] TestDupCompare()724 public void TestDupCompare() 725 { 726 testName = "TestDupCompare"; 727 SetUpTest(true); 728 729 BTreeDatabaseConfig cfg = new BTreeDatabaseConfig(); 730 cfg.Creation = CreatePolicy.IF_NEEDED; 731 cfg.Duplicates = DuplicatesPolicy.UNSORTED; 732 733 // Do not set the duplicate comparison delegate. 734 using (BTreeDatabase db = BTreeDatabase.Open( 735 testHome + "/" + testName + ".db", cfg)) { 736 try { 737 int ret = db.DupCompare( 738 new DatabaseEntry( 739 BitConverter.GetBytes(255)), 740 new DatabaseEntry( 741 BitConverter.GetBytes(257))); 742 throw new TestException(); 743 } catch(NullReferenceException) { 744 } 745 } 746 747 /* 748 * Set the duplicate comparison delegate, and verify 749 * the comparison delegate. 750 */ 751 cfg.DuplicateCompare = 752 new EntryComparisonDelegate(dbIntCompare); 753 using (BTreeDatabase db = BTreeDatabase.Open( 754 testHome + "/" + testName + "1.db", cfg)) { 755 int ret = db.DupCompare( 756 new DatabaseEntry(BitConverter.GetBytes(255)), 757 new DatabaseEntry(BitConverter.GetBytes(257))); 758 Assert.Greater(0, ret); 759 } 760 } 761 762 [Test] TestEncryption()763 public void TestEncryption() { 764 testName = "TestEncryption"; 765 SetUpTest(true); 766 767 BTreeDatabase db1; 768 769 BTreeDatabaseConfig dbCfg = 770 new BTreeDatabaseConfig(); 771 dbCfg.Creation = CreatePolicy.IF_NEEDED; 772 773 // Open an encrypted database. 774 dbCfg.SetEncryption("bdb", EncryptionAlgorithm.AES); 775 using (db1 = BTreeDatabase.Open( 776 testHome + "/" + testName + ".db", dbCfg)) { 777 Assert.IsTrue(db1.Encrypted); 778 for (int i = 0; i < 10; i++) 779 db1.Put(new DatabaseEntry 780 (BitConverter.GetBytes(i)), 781 new DatabaseEntry( 782 BitConverter.GetBytes(i))); 783 } 784 785 // Verify the database is encrypted. 786 BTreeDatabaseConfig verifyDbCfg = 787 new BTreeDatabaseConfig(); 788 verifyDbCfg.Creation = CreatePolicy.IF_NEEDED; 789 verifyDbCfg.SetEncryption( 790 dbCfg.EncryptionPassword, 791 dbCfg.EncryptAlgorithm); 792 verifyDbCfg.Encrypted = true; 793 using (db1 = BTreeDatabase.Open( 794 testHome + "/" + testName + ".db", 795 verifyDbCfg)) { 796 for (int i = 0; i < 10; i++) 797 db1.Get(new DatabaseEntry( 798 BitConverter.GetBytes(i))); 799 }; 800 } 801 802 [Test] TestExist()803 public void TestExist() 804 { 805 testName = "TestExist"; 806 SetUpTest(true); 807 string dbFileName = testHome + "/" + testName + ".db"; 808 809 BTreeDatabaseConfig btreeDBConfig = 810 new BTreeDatabaseConfig(); 811 btreeDBConfig.Creation = CreatePolicy.IF_NEEDED; 812 BTreeDatabase btreeDB; 813 using (btreeDB = BTreeDatabase.Open( 814 dbFileName, btreeDBConfig)) 815 { 816 DatabaseEntry key = new DatabaseEntry( 817 ASCIIEncoding.ASCII.GetBytes("key")); 818 DatabaseEntry data = new DatabaseEntry( 819 ASCIIEncoding.ASCII.GetBytes("data")); 820 821 btreeDB.Put(key, data); 822 Assert.IsTrue(btreeDB.Exists( 823 new DatabaseEntry( 824 ASCIIEncoding.ASCII.GetBytes("key")))); 825 Assert.IsFalse(btreeDB.Exists( 826 new DatabaseEntry( 827 ASCIIEncoding.ASCII.GetBytes("data")))); 828 } 829 } 830 831 [Test] TestExistWithTxn()832 public void TestExistWithTxn() 833 { 834 BTreeDatabase btreeDB; 835 Transaction txn; 836 DatabaseEnvironmentConfig envConfig; 837 DatabaseEnvironment env; 838 DatabaseEntry key, data; 839 840 testName = "TestExistWithTxn"; 841 SetUpTest(true); 842 843 // Open an environment. 844 envConfig = new DatabaseEnvironmentConfig(); 845 envConfig.Create = true; 846 envConfig.UseMPool = true; 847 envConfig.UseTxns = true; 848 env = DatabaseEnvironment.Open(testHome, envConfig); 849 850 // Begin a transaction. 851 txn = env.BeginTransaction(); 852 853 // Open a database. 854 BTreeDatabaseConfig btreeDBConfig = 855 new BTreeDatabaseConfig(); 856 btreeDBConfig.Creation = CreatePolicy.IF_NEEDED; 857 btreeDBConfig.Env = env; 858 btreeDB = BTreeDatabase.Open(testName + ".db", 859 btreeDBConfig, txn); 860 861 // Put key data pair into database. 862 key = new DatabaseEntry( 863 ASCIIEncoding.ASCII.GetBytes("key")); 864 data = new DatabaseEntry( 865 ASCIIEncoding.ASCII.GetBytes("data")); 866 btreeDB.Put(key, data, txn); 867 868 // Confirm that the pair exists in the database. 869 Assert.IsTrue(btreeDB.Exists(new DatabaseEntry( 870 ASCIIEncoding.ASCII.GetBytes("key")), txn)); 871 Assert.IsFalse(btreeDB.Exists(new DatabaseEntry( 872 ASCIIEncoding.ASCII.GetBytes("data")), txn)); 873 874 // Dispose all. 875 btreeDB.Close(); 876 txn.Commit(); 877 env.Close(); 878 } 879 880 [Test] TestExistWithLockingInfo()881 public void TestExistWithLockingInfo() 882 { 883 BTreeDatabase btreeDB; 884 DatabaseEnvironment env; 885 DatabaseEntry key, data; 886 887 testName = "TestExistWithLockingInfo"; 888 SetUpTest(true); 889 890 // Open the environment. 891 DatabaseEnvironmentConfig envCfg = 892 new DatabaseEnvironmentConfig(); 893 envCfg.Create = true; 894 envCfg.FreeThreaded = true; 895 envCfg.UseLocking = true; 896 envCfg.UseLogging = true; 897 envCfg.UseMPool = true; 898 envCfg.UseTxns = true; 899 env = DatabaseEnvironment.Open( 900 testHome, envCfg); 901 902 // Open database in transaction. 903 Transaction openTxn = env.BeginTransaction(); 904 BTreeDatabaseConfig cfg = 905 new BTreeDatabaseConfig(); 906 cfg.Creation = CreatePolicy.ALWAYS; 907 cfg.Env = env; 908 cfg.FreeThreaded = true; 909 cfg.PageSize = 4096; 910 cfg.Duplicates = DuplicatesPolicy.UNSORTED; 911 btreeDB = BTreeDatabase.Open(testName + ".db", 912 cfg, openTxn); 913 openTxn.Commit(); 914 915 // Put key data pair into database. 916 Transaction txn = env.BeginTransaction(); 917 key = new DatabaseEntry( 918 ASCIIEncoding.ASCII.GetBytes("key")); 919 data = new DatabaseEntry( 920 ASCIIEncoding.ASCII.GetBytes("data")); 921 btreeDB.Put(key, data, txn); 922 923 // Confirm that the pair exists in the database with LockingInfo. 924 LockingInfo lockingInfo = new LockingInfo(); 925 lockingInfo.ReadModifyWrite = true; 926 927 // Confirm that the pair exists in the database. 928 Assert.IsTrue(btreeDB.Exists(new DatabaseEntry( 929 ASCIIEncoding.ASCII.GetBytes("key")), txn, lockingInfo)); 930 Assert.IsFalse(btreeDB.Exists(new DatabaseEntry( 931 ASCIIEncoding.ASCII.GetBytes("data")), txn, lockingInfo)); 932 txn.Commit(); 933 934 btreeDB.Close(); 935 env.Close(); 936 } 937 938 [Test] TestGetByKey()939 public void TestGetByKey() 940 { 941 testName = "TestGetByKey"; 942 SetUpTest(true); 943 string btreeDBFileName = testHome + "/" + 944 testName + ".db"; 945 string btreeDBName = 946 Path.GetFileNameWithoutExtension(btreeDBFileName); 947 948 BTreeDatabaseConfig btreeDBConfig = 949 new BTreeDatabaseConfig(); 950 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 951 BTreeDatabase btreeDB = BTreeDatabase.Open( 952 btreeDBFileName, btreeDBName, btreeDBConfig); 953 954 DatabaseEntry key = new DatabaseEntry( 955 ASCIIEncoding.ASCII.GetBytes("key")); 956 DatabaseEntry data = new DatabaseEntry( 957 ASCIIEncoding.ASCII.GetBytes("data")); 958 btreeDB.Put(key, data); 959 960 KeyValuePair<DatabaseEntry, DatabaseEntry> pair = 961 new KeyValuePair<DatabaseEntry, DatabaseEntry>(); 962 pair = btreeDB.Get(key); 963 Assert.AreEqual(pair.Key.Data, key.Data); 964 Assert.AreEqual(pair.Value.Data, data.Data); 965 btreeDB.Close(); 966 } 967 968 [Test] TestGetByRecno()969 public void TestGetByRecno() 970 { 971 testName = "TestGetByRecno"; 972 SetUpTest(true); 973 string btreeDBFileName = testHome + "/" + 974 testName + ".db"; 975 string btreeDBName = 976 Path.GetFileNameWithoutExtension(btreeDBFileName); 977 978 BTreeDatabaseConfig btreeDBConfig = 979 new BTreeDatabaseConfig(); 980 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 981 btreeDBConfig.UseRecordNumbers = true; 982 BTreeDatabase btreeDB = BTreeDatabase.Open( 983 btreeDBFileName, btreeDBName, btreeDBConfig); 984 Assert.IsTrue(btreeDB.RecordNumbers); 985 986 DatabaseEntry key = new DatabaseEntry(); 987 DatabaseEntry data = new DatabaseEntry(); 988 uint recno, count, value; 989 for (recno = 1; recno <= 100; recno++) 990 { 991 value = 200 - recno; 992 Configuration.dbtFromString(key, 993 Convert.ToString(value)); 994 Configuration.dbtFromString(data, 995 Convert.ToString(value)); 996 btreeDB.Put(key, data); 997 } 998 999 KeyValuePair<DatabaseEntry, DatabaseEntry> pair = 1000 new KeyValuePair<DatabaseEntry, DatabaseEntry>(); 1001 1002 for (count = 1; ; count++) 1003 { 1004 try 1005 { 1006 pair = btreeDB.Get(count); 1007 } 1008 catch (NotFoundException) 1009 { 1010 Assert.AreEqual(101, count); 1011 break; 1012 } 1013 value = 299 - 200 + count; 1014 Assert.AreEqual(value.ToString(), 1015 Configuration.strFromDBT(pair.Key)); 1016 } 1017 1018 btreeDB.Close(); 1019 } 1020 1021 [Test, ExpectedException(typeof(NotFoundException))] TestGetBoth()1022 public void TestGetBoth() 1023 { 1024 testName = "TestGetBoth"; 1025 SetUpTest(true); 1026 string btreeDBFileName = testHome + "/" + 1027 testName + ".db"; 1028 string btreeDBName = 1029 Path.GetFileNameWithoutExtension(btreeDBFileName); 1030 1031 BTreeDatabaseConfig btreeDBConfig = 1032 new BTreeDatabaseConfig(); 1033 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 1034 using (BTreeDatabase btreeDB = BTreeDatabase.Open( 1035 btreeDBFileName, btreeDBName, btreeDBConfig)) 1036 { 1037 DatabaseEntry key = new DatabaseEntry(); 1038 DatabaseEntry data = new DatabaseEntry(); 1039 1040 Configuration.dbtFromString(key, "key"); 1041 Configuration.dbtFromString(data, "data"); 1042 btreeDB.Put(key, data); 1043 KeyValuePair<DatabaseEntry, DatabaseEntry> pair = 1044 new KeyValuePair<DatabaseEntry, DatabaseEntry>(); 1045 pair = btreeDB.GetBoth(key, data); 1046 Assert.AreEqual(key.Data, pair.Key.Data); 1047 Assert.AreEqual(data.Data, pair.Value.Data); 1048 1049 Configuration.dbtFromString(key, "key"); 1050 Configuration.dbtFromString(data, "key"); 1051 btreeDB.GetBoth(key, data); 1052 } 1053 } 1054 1055 [Test] TestGetBothMultiple()1056 public void TestGetBothMultiple() 1057 { 1058 testName = "TestGetBothMultiple"; 1059 SetUpTest(true); 1060 string btreeDBFileName = testHome + "/" + 1061 testName + ".db"; 1062 string btreeDBName = testName; 1063 DatabaseEntry key, data; 1064 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> kvp; 1065 int cnt; 1066 1067 BTreeDatabaseConfig btreeDBConfig = 1068 new BTreeDatabaseConfig(); 1069 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 1070 btreeDBConfig.Duplicates = DuplicatesPolicy.UNSORTED; 1071 btreeDBConfig.PageSize = 1024; 1072 using (BTreeDatabase btreeDB = GetMultipleDB( 1073 btreeDBFileName, btreeDBName, btreeDBConfig)) { 1074 key = new DatabaseEntry(BitConverter.GetBytes(100)); 1075 data = new DatabaseEntry(BitConverter.GetBytes(100)); 1076 1077 kvp = btreeDB.GetBothMultiple(key, data); 1078 cnt = 0; 1079 foreach (DatabaseEntry dbt in kvp.Value) 1080 cnt++; 1081 Assert.AreEqual(cnt, 10); 1082 1083 kvp = btreeDB.GetBothMultiple(key, data, 1024); 1084 cnt = 0; 1085 foreach (DatabaseEntry dbt in kvp.Value) 1086 cnt++; 1087 Assert.AreEqual(cnt, 10); 1088 } 1089 } 1090 1091 [Test] TestGetMultiple()1092 public void TestGetMultiple() 1093 { 1094 testName = "TestGetMultiple"; 1095 SetUpTest(true); 1096 string btreeDBFileName = testHome + "/" + 1097 testName + ".db"; 1098 string btreeDBName = testName; 1099 1100 BTreeDatabaseConfig btreeDBConfig = 1101 new BTreeDatabaseConfig(); 1102 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 1103 btreeDBConfig.Duplicates = DuplicatesPolicy.UNSORTED; 1104 btreeDBConfig.PageSize = 512; 1105 1106 using (BTreeDatabase btreeDB = GetMultipleDB( 1107 btreeDBFileName, btreeDBName, btreeDBConfig)) { 1108 DatabaseEntry key = new DatabaseEntry( 1109 BitConverter.GetBytes(10)); 1110 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> kvp = 1111 btreeDB.GetMultiple(key, 1024); 1112 int cnt = 0; 1113 foreach (DatabaseEntry dbt in kvp.Value) 1114 cnt++; 1115 Assert.AreEqual(cnt, 10); 1116 1117 key = new DatabaseEntry( 1118 BitConverter.GetBytes(102)); 1119 kvp = btreeDB.GetMultiple(key, 1024); 1120 cnt = 0; 1121 foreach (DatabaseEntry dbt in kvp.Value) 1122 cnt++; 1123 Assert.AreEqual(cnt, 1); 1124 } 1125 } 1126 1127 [Test] TestGetMultipleByRecno()1128 public void TestGetMultipleByRecno() 1129 { 1130 testName = "TestGetMultipleByRecno"; 1131 SetUpTest(true); 1132 string btreeDBFileName = testHome + "/" + 1133 testName + ".db"; 1134 string btreeDBName = 1135 Path.GetFileNameWithoutExtension(btreeDBFileName); 1136 1137 BTreeDatabaseConfig btreeDBConfig = 1138 new BTreeDatabaseConfig(); 1139 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 1140 btreeDBConfig.Duplicates = DuplicatesPolicy.NONE; 1141 btreeDBConfig.UseRecordNumbers = true; 1142 using (BTreeDatabase btreeDB = GetMultipleDB( 1143 btreeDBFileName, btreeDBName, btreeDBConfig)) { 1144 int recno = 44; 1145 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> kvp = 1146 btreeDB.GetMultiple((uint)recno); 1147 int cnt = 0; 1148 int kdata = BitConverter.ToInt32(kvp.Key.Data, 0); 1149 Assert.AreEqual(kdata, recno); 1150 foreach (DatabaseEntry dbt in kvp.Value) { 1151 cnt++; 1152 int ddata = BitConverter.ToInt32(dbt.Data, 0); 1153 Assert.AreEqual(ddata, recno); 1154 } 1155 Assert.AreEqual(cnt, 1); 1156 } 1157 } 1158 1159 [Test] TestGetMultipleByRecnoInSize()1160 public void TestGetMultipleByRecnoInSize() 1161 { 1162 testName = "TestGetMultipleByRecnoInSize"; 1163 SetUpTest(true); 1164 string btreeDBFileName = testHome + "/" + 1165 testName + ".db"; 1166 string btreeDBName = 1167 Path.GetFileNameWithoutExtension(btreeDBFileName); 1168 1169 BTreeDatabaseConfig btreeDBConfig = 1170 new BTreeDatabaseConfig(); 1171 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 1172 btreeDBConfig.Duplicates = DuplicatesPolicy.NONE; 1173 btreeDBConfig.UseRecordNumbers = true; 1174 btreeDBConfig.PageSize = 512; 1175 using (BTreeDatabase btreeDB = GetMultipleDB( 1176 btreeDBFileName, btreeDBName, btreeDBConfig)) { 1177 int recno = 100; 1178 int bufferSize = 1024; 1179 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> kvp = 1180 btreeDB.GetMultiple((uint)recno, bufferSize); 1181 int cnt = 0; 1182 int kdata = BitConverter.ToInt32(kvp.Key.Data, 0); 1183 Assert.AreEqual(kdata, recno); 1184 foreach (DatabaseEntry dbt in kvp.Value) { 1185 cnt++; 1186 Assert.AreEqual(dbt.Data.Length, 111); 1187 } 1188 Assert.AreEqual(1, cnt); 1189 } 1190 } 1191 1192 [Test] TestGetMultipleInSize()1193 public void TestGetMultipleInSize() 1194 { 1195 testName = "TestGetMultipleInSize"; 1196 SetUpTest(true); 1197 string btreeDBFileName = testHome + "/" + 1198 testName + ".db"; 1199 string btreeDBName = 1200 Path.GetFileNameWithoutExtension(btreeDBFileName); 1201 1202 BTreeDatabaseConfig btreeDBConfig = 1203 new BTreeDatabaseConfig(); 1204 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 1205 btreeDBConfig.Duplicates = DuplicatesPolicy.UNSORTED; 1206 btreeDBConfig.PageSize = 1024; 1207 using (BTreeDatabase btreeDB = GetMultipleDB( 1208 btreeDBFileName, btreeDBName, btreeDBConfig)) { 1209 1210 int num = 101; 1211 DatabaseEntry key = new DatabaseEntry( 1212 BitConverter.GetBytes(num)); 1213 int bufferSize = 10240; 1214 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> kvp = 1215 btreeDB.GetMultiple(key, bufferSize); 1216 int cnt = 0; 1217 foreach (DatabaseEntry dbt in kvp.Value) { 1218 cnt++; 1219 Assert.AreEqual(BitConverter.ToInt32( 1220 dbt.Data, 0), num); 1221 num++; 1222 } 1223 Assert.AreEqual(cnt, 923); 1224 } 1225 } 1226 1227 [Test] TestGetWithTxn()1228 public void TestGetWithTxn() 1229 { 1230 testName = "TestGetWithTxn"; 1231 SetUpTest(true); 1232 1233 DatabaseEnvironmentConfig envConfig = 1234 new DatabaseEnvironmentConfig(); 1235 envConfig.Create = true; 1236 envConfig.UseLogging = true; 1237 envConfig.UseMPool = true; 1238 envConfig.UseTxns = true; 1239 DatabaseEnvironment env = DatabaseEnvironment.Open( 1240 testHome, envConfig); 1241 1242 try 1243 { 1244 Transaction openTxn = env.BeginTransaction(); 1245 BTreeDatabaseConfig dbConfig = 1246 new BTreeDatabaseConfig(); 1247 dbConfig.Env = env; 1248 dbConfig.Creation = CreatePolicy.IF_NEEDED; 1249 BTreeDatabase db = BTreeDatabase.Open( 1250 testName + ".db", dbConfig, openTxn); 1251 openTxn.Commit(); 1252 1253 Transaction putTxn = env.BeginTransaction(); 1254 try 1255 { 1256 for (int i = 0; i < 20; i++) 1257 db.Put(new DatabaseEntry( 1258 BitConverter.GetBytes(i)), 1259 new DatabaseEntry( 1260 BitConverter.GetBytes(i)), putTxn); 1261 putTxn.Commit(); 1262 } 1263 catch (DatabaseException e) 1264 { 1265 putTxn.Abort(); 1266 db.Close(); 1267 throw e; 1268 } 1269 1270 Transaction getTxn = env.BeginTransaction(); 1271 KeyValuePair<DatabaseEntry, DatabaseEntry> pair; 1272 try 1273 { 1274 for (int i = 0; i < 20; i++) 1275 { 1276 pair = db.Get(new DatabaseEntry( 1277 BitConverter.GetBytes(i)), getTxn); 1278 Assert.AreEqual(BitConverter.GetBytes(i), 1279 pair.Key.Data); 1280 } 1281 1282 getTxn.Commit(); 1283 db.Close(); 1284 } 1285 catch (DatabaseException) 1286 { 1287 getTxn.Abort(); 1288 db.Close(); 1289 throw new TestException(); 1290 } 1291 } 1292 catch (DatabaseException) 1293 { 1294 } 1295 finally 1296 { 1297 env.Close(); 1298 } 1299 } 1300 1301 [Test] TestKeyRange()1302 public void TestKeyRange() 1303 { 1304 testName = "TestKeyRange"; 1305 SetUpTest(true); 1306 string btreeDBFileName = testHome + "/" + 1307 testName + ".db"; 1308 string btreeDBName = Path.GetFileNameWithoutExtension( 1309 btreeDBFileName); 1310 1311 BTreeDatabaseConfig btreeDBConfig = 1312 new BTreeDatabaseConfig(); 1313 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 1314 BTreeDatabase btreeDB = BTreeDatabase.Open( 1315 btreeDBFileName, btreeDBName, btreeDBConfig); 1316 1317 DatabaseEntry key = new DatabaseEntry(); 1318 DatabaseEntry data = new DatabaseEntry(); 1319 uint recno; 1320 for (recno = 1; recno <= 10; recno++) 1321 { 1322 Configuration.dbtFromString(key, 1323 Convert.ToString(recno)); 1324 Configuration.dbtFromString(data, 1325 Convert.ToString(recno)); 1326 btreeDB.Put(key, data); 1327 } 1328 1329 Configuration.dbtFromString(key, Convert.ToString(5)); 1330 KeyRange keyRange = btreeDB.KeyRange(key); 1331 Assert.AreEqual(0.5, keyRange.Less); 1332 Assert.AreEqual(0.1, keyRange.Equal); 1333 Assert.AreEqual(0.4, keyRange.Greater); 1334 1335 btreeDB.Close(); 1336 } 1337 1338 [Test] TestMessageCall()1339 public void TestMessageCall() 1340 { 1341 testName = "TestMessageCall"; 1342 SetUpTest(true); 1343 1344 // Configure and open an environment. 1345 DatabaseEnvironmentConfig envConfig = 1346 new DatabaseEnvironmentConfig(); 1347 envConfig.Create = true; 1348 envConfig.UseMPool = true; 1349 DatabaseEnvironment env = DatabaseEnvironment.Open( 1350 testHome, envConfig); 1351 1352 // Configure and open a database. 1353 BTreeDatabaseConfig DBConfig = 1354 new BTreeDatabaseConfig(); 1355 DBConfig.Env = env; 1356 DBConfig.Creation = CreatePolicy.IF_NEEDED; 1357 1358 string DBFileName = testName + ".db"; 1359 BTreeDatabase db = BTreeDatabase.Open(DBFileName, DBConfig); 1360 1361 // Confirm message file does not exist. 1362 string messageCallFile = testHome + "/" + "MessageCallFile"; 1363 Assert.AreEqual(false, File.Exists(messageCallFile)); 1364 1365 string messageInfo = "Message come from db.set_msgcall!"; 1366 1367 // Call set_msgcall() of env. 1368 db.messageFeedback = new MessageFeedbackDelegate(Msgcall_fcn); 1369 db.messageFeedback(null, messageInfo); 1370 1371 // Unconfigures the callback interface. 1372 db.messageFeedback = null; 1373 1374 // Confirm message file exists now. 1375 Assert.AreEqual(true, File.Exists(messageCallFile)); 1376 1377 // Read the first line of message file. 1378 string line = null; 1379 System.IO.StreamReader file = new System.IO.StreamReader(@"" + messageCallFile); 1380 line = file.ReadLine(); 1381 1382 // Confirm the message file is not empty. 1383 Assert.AreEqual(line, messageInfo); 1384 file.Close(); 1385 1386 // Close database and environment. 1387 db.Close(); 1388 env.Close(); 1389 } 1390 Msgcall_fcn(string msgpfx, string message)1391 public void Msgcall_fcn(string msgpfx, string message) 1392 { 1393 string msgfile = testHome + "/" + "MessageCallFile"; 1394 FileStream fs = new FileStream(msgfile, FileMode.OpenOrCreate); 1395 StreamWriter sw = new StreamWriter(fs); 1396 if (msgpfx != null) 1397 sw.Write(msgpfx + ": "); 1398 sw.Write(message); 1399 sw.Flush(); 1400 sw.Close(); 1401 fs.Close(); 1402 } 1403 1404 [Test] TestMessageFile()1405 public void TestMessageFile() 1406 { 1407 testName = "TestMessageFile"; 1408 SetUpTest(true); 1409 1410 // Configure and open an environment. 1411 DatabaseEnvironmentConfig envConfig = 1412 new DatabaseEnvironmentConfig(); 1413 envConfig.Create = true; 1414 envConfig.UseMPool = true; 1415 DatabaseEnvironment env = DatabaseEnvironment.Open( 1416 testHome, envConfig); 1417 1418 // Configure and open a database. 1419 BTreeDatabaseConfig DBConfig = 1420 new BTreeDatabaseConfig(); 1421 DBConfig.Env = env; 1422 DBConfig.Creation = CreatePolicy.IF_NEEDED; 1423 1424 string DBFileName = testName + ".db"; 1425 BTreeDatabase db = BTreeDatabase.Open(DBFileName, DBConfig); 1426 1427 // Confirm message file does not exist. 1428 string messageFile = testHome + "/" + "msgfile"; 1429 Assert.AreEqual(false, File.Exists(messageFile)); 1430 1431 // Call set_msgfile() of db. 1432 db.Msgfile = messageFile; 1433 1434 // Print db statistic to message file. 1435 db.PrintStats(true); 1436 1437 // Confirm message file exists now. 1438 Assert.AreEqual(true, File.Exists(messageFile)); 1439 1440 db.Msgfile = ""; 1441 string line = null; 1442 1443 // Read the third line of message file. 1444 System.IO.StreamReader file = new System.IO.StreamReader(@"" + messageFile); 1445 line = file.ReadLine(); 1446 line = file.ReadLine(); 1447 line = file.ReadLine(); 1448 1449 // Confirm the message file is not empty. 1450 Assert.AreEqual(line, "DB handle information:"); 1451 file.Close(); 1452 1453 // Close database and environment. 1454 db.Close(); 1455 env.Close(); 1456 } 1457 1458 [Test] TestNoWaitDbExclusiveLock()1459 public void TestNoWaitDbExclusiveLock() 1460 { 1461 testName = "TestNoWaitDbExclusiveLock"; 1462 SetUpTest(true); 1463 1464 // Open an environment. 1465 DatabaseEnvironmentConfig envConfig = 1466 new DatabaseEnvironmentConfig(); 1467 envConfig.AutoCommit = true; 1468 envConfig.Create = true; 1469 envConfig.UseMPool = true; 1470 envConfig.UseLocking = true; 1471 envConfig.UseLogging = true; 1472 envConfig.UseTxns = true; 1473 DatabaseEnvironment env = DatabaseEnvironment.Open( 1474 testHome, envConfig); 1475 1476 // Open a database. 1477 BTreeDatabaseConfig btreeDBConfig = 1478 new BTreeDatabaseConfig(); 1479 btreeDBConfig.Env = env; 1480 string btreeDBFileName = testName + ".db"; 1481 BTreeDatabase btreeDB; 1482 1483 btreeDBConfig.Creation = CreatePolicy.IF_NEEDED; 1484 btreeDB = BTreeDatabase.Open( 1485 btreeDBFileName, btreeDBConfig); 1486 Assert.IsNull(btreeDB.NoWaitDbExclusiveLock); 1487 btreeDB.Close(); 1488 1489 btreeDBConfig.NoWaitDbExclusiveLock = false; 1490 btreeDB = BTreeDatabase.Open( 1491 btreeDBFileName, btreeDBConfig); 1492 Assert.AreEqual(btreeDB.NoWaitDbExclusiveLock, false); 1493 btreeDB.Close(); 1494 1495 btreeDBConfig.NoWaitDbExclusiveLock = true; 1496 btreeDB = BTreeDatabase.Open( 1497 btreeDBFileName, btreeDBConfig); 1498 Assert.AreEqual(btreeDB.NoWaitDbExclusiveLock, true); 1499 btreeDB.Close(); 1500 env.Close(); 1501 } 1502 1503 [Test] TestOpenExistingBtreeDB()1504 public void TestOpenExistingBtreeDB() 1505 { 1506 testName = "TestOpenExistingBtreeDB"; 1507 SetUpTest(true); 1508 string btreeDBFileName = testHome + "/" + 1509 testName + ".db"; 1510 1511 BTreeDatabaseConfig btreeConfig = 1512 new BTreeDatabaseConfig(); 1513 btreeConfig.Creation = CreatePolicy.ALWAYS; 1514 BTreeDatabase btreeDB = BTreeDatabase.Open( 1515 btreeDBFileName, btreeConfig); 1516 btreeDB.Close(); 1517 1518 DatabaseConfig dbConfig = new DatabaseConfig(); 1519 Database db = Database.Open(btreeDBFileName, 1520 dbConfig); 1521 Assert.AreEqual(db.Type, DatabaseType.BTREE); 1522 Assert.AreEqual(db.Creation, CreatePolicy.NEVER); 1523 db.Close(); 1524 } 1525 1526 [Test] TestOpenNewBtreeDB()1527 public void TestOpenNewBtreeDB() 1528 { 1529 testName = "TestOpenNewBtreeDB"; 1530 SetUpTest(true); 1531 string btreeDBFileName = testHome + "/" + 1532 testName + ".db"; 1533 1534 XmlElement xmlElem = Configuration.TestSetUp( 1535 testFixtureName, testName); 1536 BTreeDatabaseConfig btreeConfig = 1537 new BTreeDatabaseConfig(); 1538 BTreeDatabaseConfigTest.Config(xmlElem, 1539 ref btreeConfig, true); 1540 BTreeDatabase btreeDB = BTreeDatabase.Open( 1541 btreeDBFileName, btreeConfig); 1542 Confirm(xmlElem, btreeDB, true); 1543 btreeDB.Close(); 1544 } 1545 1546 [Test] TestOpenMulDBInSingleFile()1547 public void TestOpenMulDBInSingleFile() 1548 { 1549 testName = "TestOpenMulDBInSingleFile"; 1550 SetUpTest(true); 1551 string btreeDBFileName = testHome + "/" + 1552 testName + ".db"; 1553 string[] btreeDBArr = new string[4]; 1554 1555 for (int i = 0; i < 4; i++) 1556 btreeDBArr[i] = Path.GetFileNameWithoutExtension( 1557 btreeDBFileName) + i; 1558 1559 Configuration.ClearDir(testHome); 1560 1561 BTreeDatabaseConfig btreeDBConfig = 1562 new BTreeDatabaseConfig(); 1563 btreeDBConfig.Creation = CreatePolicy.IF_NEEDED; 1564 1565 BTreeDatabase btreeDB; 1566 for (int i = 0; i < 4; i++) 1567 { 1568 btreeDB = BTreeDatabase.Open(btreeDBFileName, 1569 btreeDBArr[i], btreeDBConfig); 1570 Assert.AreEqual(CreatePolicy.IF_NEEDED, btreeDB.Creation); 1571 btreeDB.Close(); 1572 } 1573 1574 DatabaseConfig dbConfig = new DatabaseConfig(); 1575 Database db; 1576 for (int i = 0; i < 4; i++) 1577 { 1578 using (db = Database.Open(btreeDBFileName, 1579 btreeDBArr[i], dbConfig)) 1580 { 1581 Assert.AreEqual(btreeDBArr[i], 1582 db.DatabaseName); 1583 Assert.AreEqual(DatabaseType.BTREE, 1584 db.Type); 1585 } 1586 } 1587 } 1588 1589 [Test] TestOpenWithTxn()1590 public void TestOpenWithTxn() 1591 { 1592 testName = "TestOpenWithTxn"; 1593 SetUpTest(true); 1594 string btreeDBName = testName + ".db"; 1595 1596 DatabaseEnvironmentConfig envConfig = 1597 new DatabaseEnvironmentConfig(); 1598 envConfig.Create = true; 1599 envConfig.UseTxns = true; 1600 envConfig.UseMPool = true; 1601 1602 DatabaseEnvironment env = DatabaseEnvironment.Open( 1603 testHome, envConfig); 1604 Transaction txn = env.BeginTransaction( 1605 new TransactionConfig()); 1606 1607 BTreeDatabaseConfig btreeConfig = 1608 new BTreeDatabaseConfig(); 1609 btreeConfig.Creation = CreatePolicy.ALWAYS; 1610 btreeConfig.Env = env; 1611 1612 /* 1613 * If environmnet home is set, the file name in Open() 1614 * is the relative path. 1615 */ 1616 BTreeDatabase btreeDB = BTreeDatabase.Open( 1617 btreeDBName, btreeConfig, txn); 1618 Assert.IsTrue(btreeDB.Transactional); 1619 btreeDB.Close(); 1620 txn.Commit(); 1621 env.Close(); 1622 } 1623 1624 [Test] TestPartialGet()1625 public void TestPartialGet() 1626 { 1627 testName = "TestPartialGet"; 1628 SetUpTest(true); 1629 1630 DatabaseEnvironmentConfig envConfig = 1631 new DatabaseEnvironmentConfig(); 1632 envConfig.Create = true; 1633 envConfig.UseTxns = true; 1634 envConfig.UseMPool = true; 1635 DatabaseEnvironment env = DatabaseEnvironment.Open( 1636 testHome, envConfig); 1637 1638 BTreeDatabase db; 1639 PopulateDb(env, out db); 1640 1641 // Partially get the first byte and verify it is 'h'. 1642 DatabaseEntry key, data; 1643 KeyValuePair<DatabaseEntry, DatabaseEntry> pair; 1644 Transaction txn = env.BeginTransaction(); 1645 for (int i = 0; i < 100; i++) { 1646 key = new DatabaseEntry(BitConverter.GetBytes(i)); 1647 data = new DatabaseEntry(0, 1); 1648 pair = db.Get(key, data, txn); 1649 Assert.AreEqual(1, pair.Value.Data.Length); 1650 Assert.AreEqual((byte)'h', pair.Value.Data[0]); 1651 } 1652 txn.Commit(); 1653 db.Close(); 1654 env.Close(); 1655 1656 /* 1657 * Open the existing database and partially get 1658 * non-existing data. 1659 */ 1660 using (Database edb = Database.Open( 1661 testHome + "/" + testName + ".db", 1662 new DatabaseConfig())) { 1663 key = new DatabaseEntry(BitConverter.GetBytes(0)); 1664 data = new DatabaseEntry(10, 1); 1665 pair = edb.Get(key, data); 1666 Assert.AreEqual(null, pair.Value.Data); 1667 } 1668 } 1669 1670 [Test] TestPartialPut()1671 public void TestPartialPut() 1672 { 1673 testName = "TestPartialPut"; 1674 SetUpTest(true); 1675 1676 BTreeDatabase db; 1677 PopulateDb(null, out db); 1678 1679 // Partially update the records. 1680 DatabaseEntry key, data; 1681 KeyValuePair<DatabaseEntry, DatabaseEntry> pair; 1682 byte[] partialBytes = ASCIIEncoding.ASCII.GetBytes("aa"); 1683 byte[] valueBytes; 1684 for (int i = 0; i < 100; i++) { 1685 key = new DatabaseEntry(BitConverter.GetBytes(i)); 1686 if (i < 50) 1687 data = new DatabaseEntry( 1688 partialBytes, 0, 2); 1689 else { 1690 data = new DatabaseEntry(partialBytes); 1691 data.Partial = true; 1692 data.PartialLen = 2; 1693 data.PartialOffset = 0; 1694 } 1695 Assert.AreEqual(0, data.PartialOffset); 1696 Assert.AreEqual(2, data.PartialLen); 1697 Assert.AreEqual(true, data.Partial); 1698 db.Put(key, data); 1699 } 1700 // Verify that the records have been partially changed. 1701 valueBytes = ASCIIEncoding.ASCII.GetBytes("hello"); 1702 valueBytes[0] = (byte)'a'; 1703 valueBytes[1] = (byte)'a'; 1704 for (int i = 0; i < 100; i++) { 1705 key = new DatabaseEntry(BitConverter.GetBytes(i)); 1706 pair = db.Get(key); 1707 Assert.AreEqual( 1708 BitConverter.GetBytes(i), pair.Key.Data); 1709 Assert.AreEqual(valueBytes, pair.Value.Data); 1710 } 1711 1712 // Partial put from non-existing offset. 1713 key = new DatabaseEntry(BitConverter.GetBytes(0)); 1714 data = new DatabaseEntry(partialBytes, 100, 2); 1715 db.Put(key, data); 1716 1717 // Verify that the records have been partially changed. 1718 pair = db.Get(key); 1719 Assert.AreEqual(102, pair.Value.Data.Length); 1720 Assert.AreEqual(valueBytes[0], 1721 pair.Value.Data[100]); 1722 Assert.AreEqual(valueBytes[0], 1723 pair.Value.Data[101]); 1724 1725 /* 1726 * Reuse the DatabaseEntry for non-partial. The partial 1727 * length and offset should be ignored. 1728 */ 1729 key = new DatabaseEntry(BitConverter.GetBytes(0)); 1730 data.Partial = false; 1731 db.Put(key, data); 1732 pair = db.Get(key); 1733 Assert.AreEqual(2, pair.Value.Data.Length); 1734 1735 db.Close(); 1736 } 1737 PopulateDb(DatabaseEnvironment env, out BTreeDatabase db)1738 private void PopulateDb(DatabaseEnvironment env, 1739 out BTreeDatabase db) 1740 { 1741 DatabaseEntry key, data; 1742 Transaction txn = null; 1743 string dbName; 1744 1745 if (env != null) { 1746 txn = env.BeginTransaction(); 1747 dbName = testName + ".db"; 1748 } else 1749 dbName = testHome + "/" + testName + ".db"; 1750 1751 OpenBtreeDB(env, txn, dbName, out db); 1752 1753 for (int i = 0; i < 100; i++) { 1754 key = new DatabaseEntry( 1755 BitConverter.GetBytes(i)); 1756 data = new DatabaseEntry( 1757 ASCIIEncoding.ASCII.GetBytes("hello")); 1758 db.Put(key, data, txn); 1759 } 1760 1761 if (txn != null) 1762 txn.Commit(); 1763 } 1764 1765 [Test] TestPartition()1766 public void TestPartition() 1767 { 1768 testName = "TestPartition"; 1769 SetUpTest(true); 1770 string btreeDBName = testHome + "/" + testName + ".db"; 1771 1772 BTreeDatabaseConfig cfg = new BTreeDatabaseConfig(); 1773 BTreeDatabase db; 1774 DatabaseEntry[] keys; 1775 DatabaseEntry key, data; 1776 string[] keyData = 1777 { "a", "b", "i", "k", "l", "q", "v", "z" }; 1778 int i; 1779 uint parts; 1780 1781 cfg.Creation = CreatePolicy.ALWAYS; 1782 parts = 3; 1783 keys = new DatabaseEntry[parts - 1]; 1784 keys[0] = new DatabaseEntry( 1785 ASCIIEncoding.ASCII.GetBytes("i")); 1786 keys[1] = new DatabaseEntry( 1787 ASCIIEncoding.ASCII.GetBytes("q")); 1788 1789 /* 1790 * Test that neither key array nor 1791 * partiton callback is set. 1792 */ 1793 Assert.AreEqual(false, cfg.SetPartitionByKeys(null)); 1794 Assert.AreEqual(false, 1795 cfg.SetPartitionByCallback(parts, null)); 1796 1797 /* Test creating the partitioned database by keys. */ 1798 Assert.AreEqual(true, cfg.SetPartitionByKeys(keys)); 1799 db = BTreeDatabase.Open(btreeDBName, cfg); 1800 for (i = 0; i < keyData.Length; i++) 1801 { 1802 key = new DatabaseEntry( 1803 ASCIIEncoding.ASCII.GetBytes(keyData[i])); 1804 data = new DatabaseEntry( 1805 ASCIIEncoding.ASCII.GetBytes(keyData[i])); 1806 db.Put(key, data); 1807 } 1808 Assert.AreEqual(parts, db.NParts); 1809 Assert.AreEqual(parts - 1, db.PartitionKeys.Length); 1810 Assert.AreEqual( 1811 keys[0].Data, db.PartitionKeys[0].Data); 1812 Assert.AreEqual( 1813 keys[1].Data, db.PartitionKeys[1].Data); 1814 Assert.AreEqual(db.Partition, null); 1815 db.Close(); 1816 string[] files = 1817 Directory.GetFiles(testHome, "__dbp.*"); 1818 Assert.AreEqual(parts, files.Length); 1819 1820 /* 1821 * Test creating the partitioned database by callback. 1822 */ 1823 Directory.Delete(testHome, true); 1824 Directory.CreateDirectory(testHome); 1825 Assert.AreEqual(true, 1826 cfg.SetPartitionByCallback(parts, partition)); 1827 db = BTreeDatabase.Open(btreeDBName, cfg); 1828 for (i = 0; i < keyData.Length; i++) 1829 { 1830 key = new DatabaseEntry( 1831 ASCIIEncoding.ASCII.GetBytes(keyData[i])); 1832 data = new DatabaseEntry( 1833 ASCIIEncoding.ASCII.GetBytes(keyData[i])); 1834 db.Put(key, data); 1835 } 1836 Assert.AreEqual(parts, db.NParts); 1837 Assert.AreEqual( 1838 new PartitionDelegate(partition), db.Partition); 1839 db.Close(); 1840 files = Directory.GetFiles(testHome, "__dbp.*"); 1841 Assert.AreEqual(parts, files.Length); 1842 } 1843 partition(DatabaseEntry key)1844 uint partition(DatabaseEntry key) 1845 { 1846 if (String.Compare( 1847 ASCIIEncoding.ASCII.GetString(key.Data), "i") < 0) 1848 return 0; 1849 else if (String.Compare( 1850 ASCIIEncoding.ASCII.GetString(key.Data), "q") < 0) 1851 return 1; 1852 else 1853 return 2; 1854 } 1855 1856 [Test] TestPrefixCompare()1857 public void TestPrefixCompare() 1858 { 1859 testName = "TestPrefixCompare"; 1860 SetUpTest(true); 1861 string btreeDBFileName = testHome + "/" + 1862 testName + ".db"; 1863 1864 BTreeDatabaseConfig dbConfig = 1865 new BTreeDatabaseConfig(); 1866 dbConfig.Creation = CreatePolicy.IF_NEEDED; 1867 dbConfig.Duplicates = DuplicatesPolicy.SORTED; 1868 dbConfig.BTreeCompare = 1869 new EntryComparisonDelegate(dbIntCompare); 1870 dbConfig.BTreePrefixCompare = 1871 new EntryPrefixComparisonDelegate(dbPrefixCompare); 1872 BTreeDatabase db = BTreeDatabase.Open( 1873 btreeDBFileName, dbConfig); 1874 1875 Assert.AreEqual(3, db.PrefixCompare(new DatabaseEntry( 1876 BitConverter.GetBytes((Int16)255)), new DatabaseEntry( 1877 BitConverter.GetBytes((Int32)65791)))); 1878 1879 Assert.AreEqual(1, db.PrefixCompare(new DatabaseEntry( 1880 BitConverter.GetBytes((Int64)255)), new DatabaseEntry( 1881 BitConverter.GetBytes((Int64)4294967552)))); 1882 1883 db.Close(); 1884 } 1885 1886 [Test] TestPutMultiple()1887 public void TestPutMultiple() 1888 { 1889 testName = "TestPutMultiple"; 1890 SetUpTest(true); 1891 1892 PutMultiple(null); 1893 1894 Configuration.ClearDir(testHome); 1895 DatabaseEnvironmentConfig cfg = 1896 new DatabaseEnvironmentConfig(); 1897 cfg.Create = true; 1898 cfg.UseLogging = true; 1899 cfg.UseMPool = true; 1900 cfg.UseTxns = true; 1901 DatabaseEnvironment env = DatabaseEnvironment.Open( 1902 testHome, cfg); 1903 PutMultiple(env); 1904 env.Close(); 1905 } 1906 PutMultiple(DatabaseEnvironment env)1907 private void PutMultiple(DatabaseEnvironment env) 1908 { 1909 List<DatabaseEntry> kList = new List<DatabaseEntry>(); 1910 List<DatabaseEntry> vList = new List<DatabaseEntry>(); 1911 BTreeDatabase db; 1912 DatabaseEntry key, value; 1913 Transaction txn; 1914 string dbFileName = (env == null) ? testHome + 1915 "/" + testName + ".db" : testName + ".db"; 1916 int i; 1917 1918 BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig(); 1919 dbConfig.Creation = CreatePolicy.IF_NEEDED; 1920 if (env != null) { 1921 dbConfig.Env = env; 1922 txn = env.BeginTransaction(); 1923 db = BTreeDatabase.Open( 1924 dbFileName, dbConfig, txn); 1925 txn.Commit(); 1926 } else 1927 db = BTreeDatabase.Open(dbFileName, dbConfig); 1928 1929 for (i = 0; i < 100; i++) { 1930 key = new DatabaseEntry( 1931 BitConverter.GetBytes(i)); 1932 value = new DatabaseEntry( 1933 ASCIIEncoding.ASCII.GetBytes("data" + i + 1934 Configuration.RandomString(512))); 1935 kList.Add(key); 1936 vList.Add(value); 1937 } 1938 1939 // Create bulk buffer for non-recno based keys. 1940 MultipleDatabaseEntry keyBuff = 1941 new MultipleDatabaseEntry(kList, false); 1942 Assert.IsFalse(keyBuff.Recno); 1943 1944 // Create bulk buffer for values. 1945 MultipleDatabaseEntry valBuff = 1946 new MultipleDatabaseEntry(vList, false); 1947 i = 0; 1948 foreach (DatabaseEntry dbt in valBuff) { 1949 Assert.AreEqual(vList[i].Data, dbt.Data); 1950 i++; 1951 } 1952 Assert.AreEqual(100, i); 1953 1954 // Create bulk buffer from another key buffer. 1955 MultipleDatabaseEntry keyBuff1 = 1956 new MultipleDatabaseEntry( 1957 keyBuff.Data, keyBuff.Recno); 1958 i = 0; 1959 foreach (DatabaseEntry dbt in keyBuff1) { 1960 Assert.AreEqual(kList[i].Data, dbt.Data); 1961 i++; 1962 } 1963 Assert.AreEqual(100, i); 1964 1965 if (env != null) { 1966 txn = env.BeginTransaction(); 1967 db.Put(keyBuff, valBuff, txn); 1968 Assert.AreEqual(100, db.Truncate(txn)); 1969 txn.Commit(); 1970 } else { 1971 /* 1972 * Bulk insert to database with key and value 1973 * buffers. 1974 */ 1975 db.Put(keyBuff, valBuff); 1976 1977 // Verify all records exist as expected. 1978 Cursor cursor = db.Cursor(); 1979 i = 99; 1980 Assert.IsTrue(cursor.MoveLast()); 1981 Assert.AreEqual(kList[i].Data, 1982 cursor.Current.Key.Data); 1983 Assert.AreEqual(vList[i].Data, 1984 cursor.Current.Value.Data); 1985 while (cursor.MovePrev()) { 1986 i--; 1987 Assert.AreEqual(kList[i].Data, 1988 cursor.Current.Key.Data); 1989 Assert.AreEqual(vList[i].Data, 1990 cursor.Current.Value.Data); 1991 } 1992 Assert.AreEqual(0, i); 1993 cursor.Close(); 1994 /* 1995 * Dumped all records. The number of records 1996 * should be 100. 1997 */ 1998 Assert.AreEqual(100, db.Truncate()); 1999 2000 /* 2001 * Bulk insert to database with a copied key 2002 * buffer and a value buffer. 2003 */ 2004 db.Put(keyBuff1, valBuff); 2005 cursor = db.Cursor(); 2006 Assert.IsTrue(cursor.MoveLast()); 2007 i = 99; 2008 Assert.AreEqual(kList[i].Data, 2009 cursor.Current.Key.Data); 2010 Assert.AreEqual(vList[i].Data, 2011 cursor.Current.Value.Data); 2012 while (cursor.MovePrev()) { 2013 i--; 2014 Assert.AreEqual(kList[i].Data, 2015 cursor.Current.Key.Data); 2016 Assert.AreEqual(vList[i].Data, 2017 cursor.Current.Value.Data); 2018 } 2019 cursor.Close(); 2020 Assert.AreEqual(0, i); 2021 /* 2022 * Dumped all records. The number of records 2023 * should be 100. 2024 */ 2025 Assert.AreEqual(100, db.Truncate()); 2026 } 2027 2028 db.Close(); 2029 } 2030 2031 [Test] TestPutMultipleKey()2032 public void TestPutMultipleKey() 2033 { 2034 testName = "TestPutMultipleKey"; 2035 SetUpTest(true); 2036 2037 PutMultipleKey(null); 2038 2039 Configuration.ClearDir(testHome); 2040 DatabaseEnvironmentConfig cfg = 2041 new DatabaseEnvironmentConfig(); 2042 cfg.Create = true; 2043 cfg.UseLogging = true; 2044 cfg.UseMPool = true; 2045 cfg.UseTxns = true; 2046 DatabaseEnvironment env = DatabaseEnvironment.Open( 2047 testHome, cfg); 2048 PutMultipleKey(env); 2049 env.Close(); 2050 } 2051 PutMultipleKey(DatabaseEnvironment env)2052 private void PutMultipleKey(DatabaseEnvironment env) 2053 { 2054 List<KeyValuePair<DatabaseEntry, DatabaseEntry>> pList = 2055 new List<KeyValuePair< 2056 DatabaseEntry, DatabaseEntry>>(); 2057 BTreeDatabase db; 2058 DatabaseEntry key, value; 2059 Transaction txn; 2060 string dbFileName = (env == null) ? testHome + 2061 "/" + testName + ".db" : testName + ".db"; 2062 int i; 2063 2064 BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig(); 2065 dbConfig.Creation = CreatePolicy.IF_NEEDED; 2066 if (env != null) { 2067 dbConfig.Env = env; 2068 txn = env.BeginTransaction(); 2069 db = BTreeDatabase.Open( 2070 dbFileName, dbConfig, txn); 2071 txn.Commit(); 2072 } else 2073 db = BTreeDatabase.Open(dbFileName, dbConfig); 2074 2075 for (i = 0; i < 100; i++) { 2076 key = new DatabaseEntry( 2077 BitConverter.GetBytes(i)); 2078 value = new DatabaseEntry( 2079 ASCIIEncoding.ASCII.GetBytes("data" + 2080 i + Configuration.RandomString(512))); 2081 pList.Add(new KeyValuePair< 2082 DatabaseEntry, DatabaseEntry>(key, value)); 2083 } 2084 2085 // Create btree bulk buffer for key/value pairs. 2086 MultipleKeyDatabaseEntry pairBuff = 2087 new MultipleKeyDatabaseEntry(pList, false); 2088 i = 0; 2089 foreach (KeyValuePair<DatabaseEntry, DatabaseEntry> 2090 pair in pairBuff) { 2091 Assert.AreEqual(pList[i].Key.Data, 2092 pair.Key.Data); 2093 Assert.AreEqual(pList[i].Value.Data, 2094 pair.Value.Data); 2095 i++; 2096 } 2097 Assert.AreEqual(100, i); 2098 2099 /* 2100 * Create bulk buffer from another key/value pairs 2101 * bulk buffer. 2102 */ 2103 MultipleKeyDatabaseEntry pairBuff1 = 2104 new MultipleKeyDatabaseEntry( 2105 pairBuff.Data, false); 2106 Assert.AreEqual(false, pairBuff1.Recno); 2107 i = 0; 2108 foreach (KeyValuePair<DatabaseEntry, DatabaseEntry> 2109 pair in pairBuff1) { 2110 Assert.AreEqual(pList[i].Key.Data, 2111 pair.Key.Data); 2112 Assert.AreEqual(pList[i].Value.Data, 2113 pair.Value.Data); 2114 i++; 2115 } 2116 Assert.AreEqual(100, i); 2117 2118 if (env == null) { 2119 // Bulk insert with key/value pair bulk buffer. 2120 db.Put(pairBuff); 2121 Cursor cursor = db.Cursor(); 2122 Assert.IsTrue(cursor.MoveFirst()); 2123 i = 0; 2124 Assert.AreEqual(pList[i].Key.Data, 2125 cursor.Current.Key.Data); 2126 Assert.AreEqual(pList[i].Value.Data, 2127 cursor.Current.Value.Data); 2128 while (cursor.MoveNext()) { 2129 i++; 2130 Assert.AreEqual(pList[i].Key.Data, 2131 cursor.Current.Key.Data); 2132 Assert.AreEqual(pList[i].Value.Data, 2133 cursor.Current.Value.Data); 2134 } 2135 Assert.AreEqual(99, i); 2136 cursor.Close(); 2137 /* 2138 * Dump all records from the database. The 2139 * number of records should be 100. 2140 */ 2141 Assert.AreEqual(100, db.Truncate()); 2142 2143 // Bulk insert with copied key/value pair buffer. 2144 db.Put(pairBuff1); 2145 cursor = db.Cursor(); 2146 Assert.IsTrue(cursor.MoveFirst()); 2147 i = 0; 2148 Assert.AreEqual(pList[i].Key.Data, 2149 cursor.Current.Key.Data); 2150 Assert.AreEqual(pList[i].Value.Data, 2151 cursor.Current.Value.Data); 2152 while (cursor.MoveNext()) { 2153 i++; 2154 Assert.AreEqual(pList[i].Key.Data, 2155 cursor.Current.Key.Data); 2156 Assert.AreEqual(pList[i].Value.Data, 2157 cursor.Current.Value.Data); 2158 } 2159 Assert.AreEqual(99, i); 2160 cursor.Close(); 2161 Assert.AreEqual(100, db.Truncate()); 2162 } else { 2163 txn = env.BeginTransaction(); 2164 db.Put(pairBuff, txn); 2165 Assert.AreEqual(100, db.Truncate(txn)); 2166 txn.Commit(); 2167 } 2168 2169 db.Close(); 2170 } 2171 2172 [Test] TestPutWithoutTxn()2173 public void TestPutWithoutTxn() 2174 { 2175 testName = "TestPutWithoutTxn"; 2176 SetUpTest(true); 2177 string btreeDBFileName = testHome + "/" + 2178 testName + ".db"; 2179 2180 BTreeDatabaseConfig btreeDBConfig = 2181 new BTreeDatabaseConfig(); 2182 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 2183 DatabaseEntry key, data; 2184 KeyValuePair<DatabaseEntry, DatabaseEntry> pair; 2185 using (BTreeDatabase btreeDB = BTreeDatabase.Open( 2186 btreeDBFileName, btreeDBConfig)) 2187 { 2188 // Put integer into database 2189 key = new DatabaseEntry( 2190 BitConverter.GetBytes((int)0)); 2191 data = new DatabaseEntry( 2192 BitConverter.GetBytes((int)0)); 2193 btreeDB.Put(key, data); 2194 pair = btreeDB.Get(key); 2195 Assert.AreEqual(key.Data, pair.Key.Data); 2196 Assert.AreEqual(data.Data, pair.Value.Data); 2197 2198 // Partial put to update the existing pair. 2199 data.Partial = true; 2200 data.PartialLen = 4; 2201 data.PartialOffset = 4; 2202 btreeDB.Put(key, data); 2203 pair = btreeDB.Get(key); 2204 Assert.AreEqual(key.Data, pair.Key.Data); 2205 Assert.AreEqual(8, pair.Value.Data.Length); 2206 } 2207 } 2208 2209 [Test, ExpectedException(typeof(KeyExistException))] TestPutNoOverWrite()2210 public void TestPutNoOverWrite() 2211 { 2212 testName = "TestPutNoOverWrite"; 2213 SetUpTest(true); 2214 string btreeDBFileName = testHome + "/" + 2215 testName + ".db"; 2216 2217 BTreeDatabaseConfig btreeDBConfig = 2218 new BTreeDatabaseConfig(); 2219 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 2220 DatabaseEntry key, data, newData; 2221 using (BTreeDatabase btreeDB = BTreeDatabase.Open( 2222 btreeDBFileName, btreeDBConfig)) 2223 { 2224 key = new DatabaseEntry( 2225 BitConverter.GetBytes((int)0)); 2226 data = new DatabaseEntry( 2227 BitConverter.GetBytes((int)0)); 2228 newData = new DatabaseEntry( 2229 BitConverter.GetBytes((int)1)); 2230 2231 btreeDB.Put(key, data); 2232 btreeDB.PutNoOverwrite(key, newData); 2233 } 2234 } 2235 2236 [Test, ExpectedException(typeof(ExpectedTestException))] TestPutNoDuplicateWithTxn()2237 public void TestPutNoDuplicateWithTxn() 2238 { 2239 testName = "TestPutNoDuplicateWithTxn"; 2240 SetUpTest(true); 2241 2242 DatabaseEnvironmentConfig envConfig = 2243 new DatabaseEnvironmentConfig(); 2244 envConfig.Create = true; 2245 envConfig.UseLogging = true; 2246 envConfig.UseMPool = true; 2247 envConfig.UseTxns = true; 2248 DatabaseEnvironment env = DatabaseEnvironment.Open( 2249 testHome, envConfig); 2250 2251 Transaction txn = env.BeginTransaction(); 2252 BTreeDatabaseConfig btreeDBConfig = 2253 new BTreeDatabaseConfig(); 2254 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 2255 btreeDBConfig.Env = env; 2256 btreeDBConfig.Duplicates = DuplicatesPolicy.SORTED; 2257 2258 DatabaseEntry key, data; 2259 try 2260 { 2261 using (BTreeDatabase btreeDB = 2262 BTreeDatabase.Open( 2263 testName + ".db", btreeDBConfig, txn)) 2264 { 2265 key = new DatabaseEntry( 2266 BitConverter.GetBytes((int)0)); 2267 data = new DatabaseEntry( 2268 BitConverter.GetBytes((int)0)); 2269 2270 btreeDB.Put(key, data, txn); 2271 btreeDB.PutNoDuplicate(key, data, txn); 2272 } 2273 txn.Commit(); 2274 } 2275 catch (KeyExistException) 2276 { 2277 txn.Abort(); 2278 throw new ExpectedTestException(); 2279 } 2280 finally 2281 { 2282 env.Close(); 2283 } 2284 } 2285 2286 [Test, ExpectedException(typeof(ExpectedTestException))] TestRemoveDBFile()2287 public void TestRemoveDBFile() 2288 { 2289 testName = "TestRemoveDBFile"; 2290 SetUpTest(true); 2291 2292 2293 RemoveDBWithoutEnv(testHome, testName, false); 2294 } 2295 2296 [Test, ExpectedException(typeof(ExpectedTestException))] TestRemoveOneDBFromDBFile()2297 public void TestRemoveOneDBFromDBFile() 2298 { 2299 testName = "TestRemoveOneDBFromDBFile"; 2300 SetUpTest(true); 2301 2302 RemoveDBWithoutEnv(testHome, testName, true); 2303 } 2304 RemoveDBWithoutEnv(string home, string dbName, bool ifDBName)2305 public void RemoveDBWithoutEnv(string home, string dbName, bool ifDBName) 2306 { 2307 string dbFileName = home + "/" + dbName + ".db"; 2308 2309 Configuration.ClearDir(home); 2310 2311 BTreeDatabaseConfig btreeDBConfig = 2312 new BTreeDatabaseConfig(); 2313 btreeDBConfig.Creation = CreatePolicy.IF_NEEDED; 2314 2315 BTreeDatabase btreeDB; 2316 if (ifDBName == false) 2317 { 2318 btreeDB = BTreeDatabase.Open(dbFileName, btreeDBConfig); 2319 btreeDB.Close(); 2320 BTreeDatabase.Remove(dbFileName); 2321 throw new ExpectedTestException(); 2322 } 2323 else 2324 { 2325 btreeDB = BTreeDatabase.Open(dbFileName, dbName, btreeDBConfig); 2326 btreeDB.Close(); 2327 BTreeDatabase.Remove(dbFileName, dbName); 2328 Assert.IsTrue(File.Exists(dbFileName)); 2329 try 2330 { 2331 btreeDB = BTreeDatabase.Open(dbFileName, dbName, new BTreeDatabaseConfig()); 2332 btreeDB.Close(); 2333 } 2334 catch (DatabaseException) 2335 { 2336 throw new ExpectedTestException(); 2337 } 2338 } 2339 } 2340 2341 [Test] TestRemoveDBFromFileInEnv()2342 public void TestRemoveDBFromFileInEnv() 2343 { 2344 testName = "TestRemoveDBFromFileInEnv"; 2345 SetUpTest(true); 2346 2347 RemoveDatabase(testHome, testName, true, true); 2348 } 2349 2350 [Test] TestRemoveDBFromEnv()2351 public void TestRemoveDBFromEnv() 2352 { 2353 testName = "TestRemoveDBFromEnv"; 2354 SetUpTest(true); 2355 2356 RemoveDatabase(testHome, testName, true, false); 2357 } 2358 RemoveDatabase(string home, string dbName, bool ifEnv, bool ifDBName)2359 public void RemoveDatabase(string home, string dbName, 2360 bool ifEnv, bool ifDBName) 2361 { 2362 string dbFileName = dbName + ".db"; 2363 2364 Configuration.ClearDir(home); 2365 2366 DatabaseEnvironmentConfig envConfig = 2367 new DatabaseEnvironmentConfig(); 2368 envConfig.Create = true; 2369 envConfig.UseCDB = true; 2370 envConfig.UseMPool = true; 2371 2372 DatabaseEnvironment env; 2373 env = DatabaseEnvironment.Open(home, envConfig); 2374 2375 try 2376 { 2377 BTreeDatabaseConfig btreeDBConfig = 2378 new BTreeDatabaseConfig(); 2379 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 2380 btreeDBConfig.Env = env; 2381 BTreeDatabase btreeDB = BTreeDatabase.Open( 2382 dbFileName, dbName, btreeDBConfig); 2383 btreeDB.Close(); 2384 2385 if (ifEnv == true && ifDBName == true) 2386 BTreeDatabase.Remove(dbFileName, dbName, env); 2387 else if (ifEnv == true) 2388 BTreeDatabase.Remove(dbFileName, env); 2389 } 2390 catch (DatabaseException) 2391 { 2392 throw new TestException(); 2393 } 2394 finally 2395 { 2396 try 2397 { 2398 BTreeDatabaseConfig dbConfig = 2399 new BTreeDatabaseConfig(); 2400 dbConfig.Creation = CreatePolicy.NEVER; 2401 dbConfig.Env = env; 2402 BTreeDatabase db = BTreeDatabase.Open( 2403 dbFileName, dbName, dbConfig); 2404 Assert.AreEqual(db.Creation, CreatePolicy.NEVER); 2405 db.Close(); 2406 throw new TestException(); 2407 } 2408 catch (DatabaseException) 2409 { 2410 } 2411 finally 2412 { 2413 env.Close(); 2414 } 2415 } 2416 } 2417 2418 [Test] TestRenameDB()2419 public void TestRenameDB() 2420 { 2421 testName = "TestRenameDB"; 2422 SetUpTest(true); 2423 string btreeDBFileName = testHome + "/" + testName + ".db"; 2424 string btreeDBName = testName; 2425 string newBtreeDBName = btreeDBName + "1" + ".db"; 2426 2427 try 2428 { 2429 BTreeDatabaseConfig btreeDBConfig = 2430 new BTreeDatabaseConfig(); 2431 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 2432 BTreeDatabase btreeDB = BTreeDatabase.Open( 2433 btreeDBFileName, btreeDBName, btreeDBConfig); 2434 btreeDB.Close(); 2435 BTreeDatabase.Rename(btreeDBFileName, 2436 btreeDBName, newBtreeDBName); 2437 2438 BTreeDatabaseConfig dbConfig = 2439 new BTreeDatabaseConfig(); 2440 dbConfig.Creation = CreatePolicy.NEVER; 2441 BTreeDatabase newDB = BTreeDatabase.Open( 2442 btreeDBFileName, newBtreeDBName, dbConfig); 2443 newDB.Close(); 2444 } 2445 catch (DatabaseException e) 2446 { 2447 throw new TestException(e.Message); 2448 } 2449 finally 2450 { 2451 try 2452 { 2453 BTreeDatabaseConfig dbConfig = 2454 new BTreeDatabaseConfig(); 2455 dbConfig.Creation = CreatePolicy.NEVER; 2456 BTreeDatabase db = BTreeDatabase.Open( 2457 btreeDBFileName, btreeDBName, 2458 dbConfig); 2459 throw new TestException(testName); 2460 } 2461 catch (DatabaseException) 2462 { 2463 } 2464 } 2465 } 2466 2467 [Test] TestRenameDBFile()2468 public void TestRenameDBFile() 2469 { 2470 testName = "TestRenameDB"; 2471 SetUpTest(true); 2472 string btreeDBFileName = testHome + "/" + 2473 testName + ".db"; 2474 string newBtreeDBFileName = testHome + "/" + 2475 testName + "1.db"; 2476 2477 BTreeDatabaseConfig btreeDBConfig = 2478 new BTreeDatabaseConfig(); 2479 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 2480 BTreeDatabase btreeDB = BTreeDatabase.Open( 2481 btreeDBFileName, btreeDBConfig); 2482 btreeDB.Close(); 2483 2484 BTreeDatabase.Rename(btreeDBFileName, 2485 newBtreeDBFileName); 2486 Assert.IsFalse(File.Exists(btreeDBFileName)); 2487 Assert.IsTrue(File.Exists(newBtreeDBFileName)); 2488 } 2489 2490 [Test] TestSync()2491 public void TestSync() 2492 { 2493 testName = "TestSync"; 2494 SetUpTest(true); 2495 string btreeDBName = testName + ".db"; 2496 2497 DatabaseEnvironmentConfig envConfig = 2498 new DatabaseEnvironmentConfig(); 2499 envConfig.Create = true; 2500 envConfig.ForceFlush = true; 2501 envConfig.UseTxns = true; 2502 envConfig.UseMPool = true; 2503 envConfig.UseLogging = true; 2504 envConfig.LogSystemCfg = new LogConfig(); 2505 envConfig.LogSystemCfg.ForceSync = false; 2506 envConfig.LogSystemCfg.AutoRemove = true; 2507 DatabaseEnvironment env = DatabaseEnvironment.Open( 2508 testHome, envConfig); 2509 2510 TransactionConfig txnConfig = new TransactionConfig(); 2511 txnConfig.SyncAction = 2512 TransactionConfig.LogFlush.WRITE_NOSYNC; 2513 Transaction txn = env.BeginTransaction(txnConfig); 2514 2515 BTreeDatabaseConfig btreeConfig = 2516 new BTreeDatabaseConfig(); 2517 btreeConfig.Creation = CreatePolicy.ALWAYS; 2518 btreeConfig.Env = env; 2519 2520 BTreeDatabase btreeDB = BTreeDatabase.Open( 2521 btreeDBName, btreeConfig, txn); 2522 2523 DatabaseEntry key = new DatabaseEntry( 2524 ASCIIEncoding.ASCII.GetBytes("key")); 2525 DatabaseEntry data = new DatabaseEntry( 2526 ASCIIEncoding.ASCII.GetBytes("data")); 2527 Assert.IsFalse(btreeDB.Exists(key, txn)); 2528 btreeDB.Put(key, data, txn); 2529 btreeDB.Sync(); 2530 btreeDB.Close(false); 2531 txn.Commit(); 2532 env.Close(); 2533 2534 BTreeDatabaseConfig dbConfig = 2535 new BTreeDatabaseConfig(); 2536 dbConfig.Creation = CreatePolicy.NEVER; 2537 using (BTreeDatabase db = BTreeDatabase.Open( 2538 testHome + "/" + btreeDBName, dbConfig)) 2539 { 2540 Assert.IsTrue(db.Exists(key)); 2541 } 2542 } 2543 2544 [Test] TestTruncate()2545 public void TestTruncate() 2546 { 2547 testName = "TestTruncate"; 2548 SetUpTest(true); 2549 string btreeDBFileName = testHome + "/" + 2550 testName + ".db"; 2551 2552 BTreeDatabaseConfig btreeDBConfig = 2553 new BTreeDatabaseConfig(); 2554 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 2555 btreeDBConfig.CacheSize = 2556 new CacheInfo(0, 30 * 1024, 1); 2557 BTreeDatabase btreeDB = BTreeDatabase.Open( 2558 btreeDBFileName, btreeDBConfig); 2559 DatabaseEntry key; 2560 DatabaseEntry data; 2561 for (int i = 0; i < 100; i++) 2562 { 2563 key = new DatabaseEntry( 2564 BitConverter.GetBytes(i)); 2565 data = new DatabaseEntry( 2566 BitConverter.GetBytes(i)); 2567 btreeDB.Put(key, data); 2568 } 2569 uint count = btreeDB.Truncate(); 2570 Assert.AreEqual(100, count); 2571 Assert.IsFalse(btreeDB.Exists(new DatabaseEntry( 2572 BitConverter.GetBytes((int)50)))); 2573 btreeDB.Close(); 2574 } 2575 2576 [Test] TestTruncateInTxn()2577 public void TestTruncateInTxn() 2578 { 2579 testName = "TestTruncateInTxn"; 2580 SetUpTest(true); 2581 2582 DatabaseEnvironmentConfig envConfig = 2583 new DatabaseEnvironmentConfig(); 2584 envConfig.Create = true; 2585 envConfig.UseMPool = true; 2586 envConfig.UseTxns = true; 2587 DatabaseEnvironment env = DatabaseEnvironment.Open( 2588 testHome, envConfig); 2589 2590 try 2591 { 2592 Transaction openTxn = env.BeginTransaction(); 2593 BTreeDatabaseConfig dbConfig = 2594 new BTreeDatabaseConfig(); 2595 dbConfig.Creation = CreatePolicy.IF_NEEDED; 2596 dbConfig.Env = env; 2597 BTreeDatabase db = BTreeDatabase.Open( 2598 testName + ".db", dbConfig, openTxn); 2599 openTxn.Commit(); 2600 2601 Transaction putTxn = env.BeginTransaction(); 2602 try 2603 { 2604 DatabaseEntry key, data; 2605 for (int i = 0; i < 10; i++) 2606 { 2607 key = new DatabaseEntry( 2608 BitConverter.GetBytes(i)); 2609 data = new DatabaseEntry( 2610 BitConverter.GetBytes(i)); 2611 db.Put(key, data, putTxn); 2612 } 2613 2614 putTxn.Commit(); 2615 } 2616 catch (DatabaseException e) 2617 { 2618 putTxn.Abort(); 2619 db.Close(); 2620 throw e; 2621 } 2622 2623 Transaction trunTxn = env.BeginTransaction(); 2624 try 2625 { 2626 uint count = db.Truncate(trunTxn); 2627 Assert.AreEqual(10, count); 2628 Assert.IsFalse(db.Exists( 2629 new DatabaseEntry( 2630 BitConverter.GetBytes((int)5)), trunTxn)); 2631 trunTxn.Commit(); 2632 db.Close(); 2633 } 2634 catch (DatabaseException) 2635 { 2636 trunTxn.Abort(); 2637 db.Close(); 2638 throw new TestException(); 2639 } 2640 } 2641 catch (DatabaseException) 2642 { 2643 } 2644 finally 2645 { 2646 env.Close(); 2647 } 2648 } 2649 2650 [Test] TestTruncateUnusedPages()2651 public void TestTruncateUnusedPages() 2652 { 2653 testName = "TestTruncateUnusedPages"; 2654 SetUpTest(true); 2655 string dbFileName = testHome + "/" + testName + ".db"; 2656 2657 BTreeDatabaseConfig dbConfig = 2658 new BTreeDatabaseConfig(); 2659 dbConfig.Creation = CreatePolicy.ALWAYS; 2660 dbConfig.PageSize = 512; 2661 BTreeDatabase db = BTreeDatabase.Open( 2662 dbFileName, dbConfig); 2663 DatabaseEntry key, data; 2664 for (int i = 0; i < 100; i++) 2665 { 2666 key = new DatabaseEntry( 2667 BitConverter.GetBytes(i)); 2668 data = new DatabaseEntry( 2669 BitConverter.GetBytes(i)); 2670 db.Put(key, data); 2671 } 2672 2673 for (int i = 0; i < 80; i++) 2674 db.Delete(new DatabaseEntry( 2675 BitConverter.GetBytes(i))); 2676 2677 uint count = db.TruncateUnusedPages(); 2678 Assert.LessOrEqual(0, count); 2679 2680 db.Close(); 2681 } 2682 2683 [Test] TestTruncateUnusedPagesWithTxn()2684 public void TestTruncateUnusedPagesWithTxn() 2685 { 2686 testName = "TestTruncateUnusedPagesWithTxn"; 2687 SetUpTest(true); 2688 2689 DatabaseEnvironmentConfig envConfig = 2690 new DatabaseEnvironmentConfig(); 2691 envConfig.Create = true; 2692 envConfig.UseMPool = true; 2693 envConfig.UseTxns = true; 2694 DatabaseEnvironment env = DatabaseEnvironment.Open( 2695 testHome, envConfig); 2696 2697 BTreeDatabase db; 2698 try 2699 { 2700 Transaction openTxn = env.BeginTransaction(); 2701 try 2702 { 2703 BTreeDatabaseConfig dbConfig = 2704 new BTreeDatabaseConfig(); 2705 dbConfig.Creation = CreatePolicy.IF_NEEDED; 2706 dbConfig.Env = env; 2707 dbConfig.PageSize = 512; 2708 db = BTreeDatabase.Open( 2709 testName + ".db", dbConfig, openTxn); 2710 openTxn.Commit(); 2711 Assert.AreEqual(512, db.Pagesize); 2712 } 2713 catch (DatabaseException e) 2714 { 2715 openTxn.Abort(); 2716 throw e; 2717 } 2718 2719 Transaction putTxn = env.BeginTransaction(); 2720 try 2721 { 2722 DatabaseEntry key, data; 2723 for (int i = 0; i < 100; i++) 2724 { 2725 key = new DatabaseEntry( 2726 BitConverter.GetBytes(i)); 2727 data = new DatabaseEntry( 2728 BitConverter.GetBytes(i)); 2729 db.Put(key, data, putTxn); 2730 } 2731 2732 putTxn.Commit(); 2733 } 2734 catch (DatabaseException e) 2735 { 2736 putTxn.Abort(); 2737 db.Close(); 2738 throw e; 2739 } 2740 2741 Transaction delTxn = env.BeginTransaction(); 2742 try 2743 { 2744 for (int i = 20; i <= 80; i++) 2745 db.Delete(new DatabaseEntry( 2746 BitConverter.GetBytes(i)), delTxn); 2747 delTxn.Commit(); 2748 } 2749 catch (DatabaseException e) 2750 { 2751 delTxn.Abort(); 2752 db.Close(); 2753 throw e; 2754 } 2755 2756 Transaction trunTxn = env.BeginTransaction(); 2757 try 2758 { 2759 uint trunPages = db.TruncateUnusedPages( 2760 trunTxn); 2761 Assert.LessOrEqual(0, trunPages); 2762 trunTxn.Commit(); 2763 db.Close(); 2764 } 2765 catch (DatabaseException) 2766 { 2767 trunTxn.Abort(); 2768 db.Close(); 2769 throw new Exception(); 2770 } 2771 } 2772 catch (DatabaseException) 2773 { 2774 } 2775 finally 2776 { 2777 env.Close(); 2778 } 2779 } 2780 2781 [Test] TestSalvage()2782 public void TestSalvage() 2783 { 2784 testName = "TestSalvage"; 2785 SetUpTest(true); 2786 string btreeDBFileName = testHome + "/" + 2787 testName + ".db"; 2788 string printableOutPut = testHome + "/" + 2789 "printableOutPut"; 2790 string inprintableOutPut = testHome + "/" + 2791 "inprintableOutPut"; 2792 2793 BTreeDatabaseConfig btreeDBConfig = 2794 new BTreeDatabaseConfig(); 2795 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 2796 BTreeDatabase btreeDB = BTreeDatabase.Open( 2797 btreeDBFileName, btreeDBConfig); 2798 2799 DatabaseEntry key; 2800 DatabaseEntry data; 2801 2802 for (uint i = 0; i < 10; i++) 2803 { 2804 key = new DatabaseEntry( 2805 ASCIIEncoding.ASCII.GetBytes(i.ToString())); 2806 data = new DatabaseEntry( 2807 ASCIIEncoding.ASCII.GetBytes(i.ToString())); 2808 btreeDB.Put(key, data); 2809 } 2810 2811 btreeDB.Close(); 2812 2813 StreamWriter sw1 = new StreamWriter(printableOutPut); 2814 StreamWriter sw2 = new StreamWriter(inprintableOutPut); 2815 BTreeDatabase.Salvage(btreeDBFileName, btreeDBConfig, 2816 true, true, sw1); 2817 BTreeDatabase.Salvage(btreeDBFileName, btreeDBConfig, 2818 false, true, sw2); 2819 sw1.Close(); 2820 sw2.Close(); 2821 2822 FileStream file1 = new FileStream(printableOutPut, 2823 FileMode.Open); 2824 FileStream file2 = new FileStream(inprintableOutPut, 2825 FileMode.Open); 2826 if (file1.Length == file2.Length) 2827 { 2828 int filebyte1 = 0; 2829 int filebyte2 = 0; 2830 do 2831 { 2832 filebyte1 = file1.ReadByte(); 2833 filebyte2 = file2.ReadByte(); 2834 } while ((filebyte1 == filebyte2) && 2835 (filebyte1 != -1)); 2836 Assert.AreNotEqual(filebyte1, filebyte2); 2837 } 2838 2839 file1.Close(); 2840 file2.Close(); 2841 } 2842 2843 [Test] TestUpgrade()2844 public void TestUpgrade() 2845 { 2846 testName = "TestUpgrade"; 2847 SetUpTest(true); 2848 2849 string srcDBFileName = "../../../bdb4.7.db"; 2850 string testDBFileName = testHome + "/bdb4.7.db"; 2851 2852 FileInfo srcDBFileInfo = new FileInfo(srcDBFileName); 2853 2854 //Copy the file. 2855 srcDBFileInfo.CopyTo(testDBFileName); 2856 Assert.IsTrue(File.Exists(testDBFileName)); 2857 2858 BTreeDatabase.Upgrade(testDBFileName, 2859 new DatabaseConfig(), true); 2860 2861 // Open the upgraded database file. 2862 BTreeDatabase db = BTreeDatabase.Open( 2863 testDBFileName, new BTreeDatabaseConfig()); 2864 db.Close(); 2865 } 2866 2867 [Test, ExpectedException(typeof(TestException))] TestVerify()2868 public void TestVerify() 2869 { 2870 testName = "TestVerify"; 2871 SetUpTest(true); 2872 string btreeDBFileName = testHome + "/" + 2873 testName + ".db"; 2874 string btreeDBName = 2875 Path.GetFileNameWithoutExtension(btreeDBFileName); 2876 2877 BTreeDatabaseConfig btreeDBConfig = 2878 new BTreeDatabaseConfig(); 2879 btreeDBConfig.Creation = CreatePolicy.ALWAYS; 2880 BTreeDatabase btreeDB = BTreeDatabase.Open( 2881 btreeDBFileName, btreeDBName, btreeDBConfig); 2882 btreeDB.Close(); 2883 btreeDBConfig.Duplicates = DuplicatesPolicy.SORTED; 2884 BTreeDatabase.Verify(btreeDBFileName, btreeDBConfig, 2885 Database.VerifyOperation.NO_ORDER_CHECK); 2886 try 2887 { 2888 BTreeDatabase.Verify(btreeDBFileName, 2889 btreeDBConfig, 2890 Database.VerifyOperation.ORDER_CHECK_ONLY); 2891 } 2892 catch (DatabaseException) 2893 { 2894 throw new TestException(testName); 2895 } 2896 finally 2897 { 2898 BTreeDatabase.Verify(btreeDBFileName, 2899 btreeDBName, btreeDBConfig, 2900 Database.VerifyOperation.ORDER_CHECK_ONLY); 2901 } 2902 2903 } 2904 2905 [Test] TestStats()2906 public void TestStats() 2907 { 2908 testName = "TestStats"; 2909 SetUpTest(true); 2910 string dbFileName = testHome + "/" + 2911 testName + ".db"; 2912 2913 BTreeDatabaseConfig dbConfig = 2914 new BTreeDatabaseConfig(); 2915 ConfigCase1(dbConfig); 2916 BTreeDatabase db = BTreeDatabase.Open(dbFileName, 2917 dbConfig); 2918 2919 BTreeStats stats = db.Stats(); 2920 ConfirmStatsPart1Case1(stats); 2921 2922 // Put 500 records into the database. 2923 PutRecordCase1(db, null); 2924 2925 stats = db.Stats(); 2926 ConfirmStatsPart2Case1(stats); 2927 2928 // Delete some data to get some free pages. 2929 byte[] bigArray = new byte[10240]; 2930 db.Delete(new DatabaseEntry(bigArray)); 2931 2932 db.Msgfile = testHome + "/" + testName+ ".log"; 2933 db.PrintStats(); 2934 db.PrintFastStats(); 2935 2936 db.Close(); 2937 } 2938 2939 [Test] TestStatsInTxn()2940 public void TestStatsInTxn() 2941 { 2942 testName = "TestStatsInTxn"; 2943 SetUpTest(true); 2944 2945 StatsInTxn(testHome, testName, false); 2946 } 2947 2948 [Test] TestStatsWithIsolation()2949 public void TestStatsWithIsolation() 2950 { 2951 testName = "TestStatsWithIsolation"; 2952 SetUpTest(true); 2953 2954 StatsInTxn(testHome, testName, true); 2955 } 2956 2957 [Test] TestMultipleDBSingleFile()2958 public void TestMultipleDBSingleFile() 2959 { 2960 testName = "TestMultipleDBSingleFile"; 2961 SetUpTest(true); 2962 string btreeDBName = testHome + "/" + testName + ".db"; 2963 2964 string dbName = "test"; 2965 2966 /* Create and initialize database object, open the database. */ 2967 BTreeDatabaseConfig btreeDBconfig = new BTreeDatabaseConfig(); 2968 btreeDBconfig.Creation = CreatePolicy.IF_NEEDED; 2969 btreeDBconfig.ErrorPrefix = testName; 2970 btreeDBconfig.UseRecordNumbers = true; 2971 2972 BTreeDatabase btreeDB = BTreeDatabase.Open(btreeDBName, dbName, 2973 btreeDBconfig); 2974 btreeDB.Close(); 2975 btreeDB = BTreeDatabase.Open(btreeDBName, dbName + "2", 2976 btreeDBconfig); 2977 btreeDB.Close(); 2978 2979 BTreeDatabaseConfig dbcfg = new BTreeDatabaseConfig(); 2980 dbcfg.ReadOnly = true; 2981 BTreeDatabase newDb = BTreeDatabase.Open(btreeDBName, dbcfg); 2982 Boolean val = newDb.HasMultiple; 2983 Assert.IsTrue(val); 2984 newDb.Close(); 2985 } 2986 StatsInTxn(string home, string name, bool ifIsolation)2987 public void StatsInTxn(string home, string name, bool ifIsolation) 2988 { 2989 DatabaseEnvironmentConfig envConfig = 2990 new DatabaseEnvironmentConfig(); 2991 EnvConfigCase1(envConfig); 2992 DatabaseEnvironment env = DatabaseEnvironment.Open( 2993 home, envConfig); 2994 2995 Transaction openTxn = env.BeginTransaction(); 2996 BTreeDatabaseConfig dbConfig = 2997 new BTreeDatabaseConfig(); 2998 ConfigCase1(dbConfig); 2999 dbConfig.Env = env; 3000 BTreeDatabase db = BTreeDatabase.Open(name + ".db", 3001 dbConfig, openTxn); 3002 openTxn.Commit(); 3003 3004 Transaction statsTxn = env.BeginTransaction(); 3005 BTreeStats stats; 3006 BTreeStats fastStats; 3007 if (ifIsolation == false) 3008 { 3009 stats = db.Stats(statsTxn); 3010 fastStats = db.FastStats(statsTxn); 3011 } 3012 else 3013 { 3014 stats = db.Stats(statsTxn, Isolation.DEGREE_ONE); 3015 fastStats = db.FastStats(statsTxn, 3016 Isolation.DEGREE_ONE); 3017 } 3018 ConfirmStatsPart1Case1(stats); 3019 3020 // Put 500 records into the database. 3021 PutRecordCase1(db, statsTxn); 3022 3023 if (ifIsolation == false) 3024 stats = db.Stats(statsTxn); 3025 else 3026 stats = db.Stats(statsTxn, Isolation.DEGREE_TWO); 3027 ConfirmStatsPart2Case1(stats); 3028 3029 // Delete some data to get some free pages. 3030 byte[] bigArray = new byte[10240]; 3031 db.Delete(new DatabaseEntry(bigArray), statsTxn); 3032 if (ifIsolation == false) 3033 stats = db.Stats(statsTxn); 3034 else 3035 stats = db.Stats(statsTxn, Isolation.DEGREE_THREE); 3036 ConfirmStatsPart3Case1(stats); 3037 3038 db.Msgfile = home + "/" + name+ ".log"; 3039 db.PrintStats(true); 3040 Assert.AreEqual(0, stats.EmptyPages); 3041 3042 statsTxn.Commit(); 3043 db.Close(); 3044 env.Close(); 3045 } 3046 EnvConfigCase1(DatabaseEnvironmentConfig cfg)3047 public void EnvConfigCase1(DatabaseEnvironmentConfig cfg) 3048 { 3049 cfg.Create = true; 3050 cfg.UseTxns = true; 3051 cfg.UseMPool = true; 3052 cfg.UseLogging = true; 3053 } 3054 ConfigCase1(BTreeDatabaseConfig dbConfig)3055 public void ConfigCase1(BTreeDatabaseConfig dbConfig) 3056 { 3057 dbConfig.Creation = CreatePolicy.IF_NEEDED; 3058 dbConfig.Duplicates = DuplicatesPolicy.UNSORTED; 3059 dbConfig.PageSize = 4096; 3060 dbConfig.MinKeysPerPage = 10; 3061 } 3062 PutRecordCase1(BTreeDatabase db, Transaction txn)3063 public void PutRecordCase1(BTreeDatabase db, Transaction txn) 3064 { 3065 byte[] bigArray = new byte[10240]; 3066 for (int i = 0; i < 100; i++) 3067 { 3068 if (txn == null) 3069 db.Put(new DatabaseEntry(BitConverter.GetBytes(i)), 3070 new DatabaseEntry(BitConverter.GetBytes(i))); 3071 else 3072 db.Put(new DatabaseEntry(BitConverter.GetBytes(i)), 3073 new DatabaseEntry(BitConverter.GetBytes(i)), txn); 3074 } 3075 for (int i = 100; i < 500; i++) 3076 { 3077 if (txn == null) 3078 db.Put(new DatabaseEntry(bigArray), 3079 new DatabaseEntry(bigArray)); 3080 else 3081 db.Put(new DatabaseEntry(bigArray), 3082 new DatabaseEntry(bigArray), txn); 3083 } 3084 } 3085 ConfirmStatsPart1Case1(BTreeStats stats)3086 public void ConfirmStatsPart1Case1(BTreeStats stats) 3087 { 3088 Assert.AreEqual(1, stats.EmptyPages); 3089 Assert.AreNotEqual(0, stats.LeafPagesFreeBytes); 3090 Assert.AreEqual(1, stats.Levels); 3091 Assert.AreNotEqual(0, stats.MagicNumber); 3092 Assert.AreEqual(1, stats.MetadataFlags); 3093 Assert.AreEqual(10, stats.MinKey); 3094 Assert.AreEqual(2, stats.nPages); 3095 Assert.AreEqual(4096, stats.PageSize); 3096 Assert.AreEqual(10, stats.Version); 3097 } 3098 ConfirmStatsPart2Case1(BTreeStats stats)3099 public void ConfirmStatsPart2Case1(BTreeStats stats) 3100 { 3101 Assert.AreNotEqual(0, stats.DuplicatePages); 3102 Assert.AreNotEqual(0, stats.DuplicatePagesFreeBytes); 3103 Assert.AreNotEqual(0, stats.InternalPages); 3104 Assert.AreNotEqual(0, stats.InternalPagesFreeBytes); 3105 Assert.AreNotEqual(0, stats.LeafPages); 3106 Assert.AreEqual(500, stats.nData); 3107 Assert.AreEqual(101, stats.nKeys); 3108 Assert.AreNotEqual(0, stats.OverflowPages); 3109 Assert.AreNotEqual(0, stats.OverflowPagesFreeBytes); 3110 } 3111 ConfirmStatsPart3Case1(BTreeStats stats)3112 public void ConfirmStatsPart3Case1(BTreeStats stats) 3113 { 3114 Assert.AreNotEqual(0, stats.FreePages); 3115 } 3116 dbIntCompare(DatabaseEntry dbt1, DatabaseEntry dbt2)3117 private int dbIntCompare(DatabaseEntry dbt1, 3118 DatabaseEntry dbt2) 3119 { 3120 int a, b; 3121 a = BitConverter.ToInt32(dbt1.Data, 0); 3122 b = BitConverter.ToInt32(dbt2.Data, 0); 3123 return a - b; 3124 } 3125 dbPrefixCompare(DatabaseEntry dbt1, DatabaseEntry dbt2)3126 private uint dbPrefixCompare(DatabaseEntry dbt1, 3127 DatabaseEntry dbt2) 3128 { 3129 uint cnt, len; 3130 3131 len = Math.Min((uint)dbt1.Data.Length, (uint)dbt2.Data.Length); 3132 for (cnt = 0; cnt < len; cnt++) 3133 { 3134 if (dbt1.Data[cnt] != dbt2.Data[cnt]) 3135 return cnt + 1; 3136 } 3137 if (dbt1.Data.Length > dbt2.Data.Length) 3138 return (uint)dbt2.Data.Length + 1; 3139 else if (dbt1.Data.Length < dbt2.Data.Length) 3140 return (uint)dbt1.Data.Length + 1; 3141 else 3142 return (uint)dbt1.Data.Length; 3143 } 3144 SetUpEnvAndTxn(string home, out DatabaseEnvironment env, out Transaction txn)3145 public void SetUpEnvAndTxn(string home, 3146 out DatabaseEnvironment env, out Transaction txn) 3147 { 3148 DatabaseEnvironmentConfig envConfig = 3149 new DatabaseEnvironmentConfig(); 3150 envConfig.Create = true; 3151 envConfig.UseTxns = true; 3152 envConfig.UseMPool = true; 3153 env = DatabaseEnvironment.Open(home, envConfig); 3154 txn = env.BeginTransaction(); 3155 } 3156 OpenBtreeDB(DatabaseEnvironment env, Transaction txn, string dbFileName, out BTreeDatabase db)3157 public void OpenBtreeDB(DatabaseEnvironment env, 3158 Transaction txn, string dbFileName, 3159 out BTreeDatabase db) 3160 { 3161 BTreeDatabaseConfig dbConfig = 3162 new BTreeDatabaseConfig(); 3163 dbConfig.Creation = CreatePolicy.IF_NEEDED; 3164 if (env != null) 3165 { 3166 dbConfig.Env = env; 3167 dbConfig.NoMMap = false; 3168 db = BTreeDatabase.Open(dbFileName, dbConfig, txn); 3169 } 3170 else 3171 { 3172 db = BTreeDatabase.Open(dbFileName, dbConfig); 3173 } 3174 } 3175 GetMultipleDB( string filename, string dbname, BTreeDatabaseConfig cfg)3176 private BTreeDatabase GetMultipleDB( 3177 string filename, string dbname, BTreeDatabaseConfig cfg) { 3178 BTreeDatabase ret; 3179 DatabaseEntry data, key; 3180 3181 ret = BTreeDatabase.Open(filename, dbname, cfg); 3182 key = null; 3183 if (cfg.UseRecordNumbers) { 3184 /* 3185 * Dups aren't allowed with record numbers, so 3186 * we have to put different data. Also, record 3187 * numbers start at 1, so we do too, which makes 3188 * checking results easier. 3189 */ 3190 for (int i = 1; i < 100; i++) { 3191 key = new DatabaseEntry( 3192 BitConverter.GetBytes(i)); 3193 data = new DatabaseEntry( 3194 BitConverter.GetBytes(i)); 3195 ret.Put(key, data); 3196 } 3197 3198 key = new DatabaseEntry( 3199 BitConverter.GetBytes(100)); 3200 data = new DatabaseEntry(); 3201 data.Data = new byte[111]; 3202 for (int i = 0; i < 111; i++) 3203 data.Data[i] = (byte)i; 3204 ret.Put(key, data); 3205 } else { 3206 for (int i = 0; i < 100; i++) { 3207 if (i % 10 == 0) 3208 key = new DatabaseEntry( 3209 BitConverter.GetBytes(i)); 3210 data = new DatabaseEntry( 3211 BitConverter.GetBytes(i)); 3212 /* Don't put nulls into the db. */ 3213 Assert.IsFalse(key == null); 3214 Assert.IsFalse(data == null); 3215 ret.Put(key, data); 3216 } 3217 3218 if (cfg.Duplicates == DuplicatesPolicy.UNSORTED) { 3219 /* Add in duplicates to check GetBothMultiple */ 3220 key = new DatabaseEntry( 3221 BitConverter.GetBytes(100)); 3222 data = new DatabaseEntry( 3223 BitConverter.GetBytes(100)); 3224 for (int i = 0; i < 10; i++) 3225 ret.Put(key, data); 3226 3227 /* 3228 * Add duplicates to check GetMultiple 3229 * with given buffer size. 3230 */ 3231 for (int i = 101; i < 1024; i++) { 3232 key = new DatabaseEntry( 3233 BitConverter.GetBytes(101)); 3234 data = new DatabaseEntry( 3235 BitConverter.GetBytes(i)); 3236 ret.Put(key, data); 3237 } 3238 3239 key = new DatabaseEntry( 3240 BitConverter.GetBytes(102)); 3241 data = new DatabaseEntry(); 3242 data.Data = new byte[112]; 3243 for (int i = 0; i < 112; i++) 3244 data.Data[i] = (byte)i; 3245 ret.Put(key, data); 3246 } 3247 } 3248 return ret; 3249 } 3250 Confirm(XmlElement xmlElem, BTreeDatabase btreeDB, bool compulsory)3251 public static void Confirm(XmlElement xmlElem, 3252 BTreeDatabase btreeDB, bool compulsory) 3253 { 3254 DatabaseTest.Confirm(xmlElem, btreeDB, compulsory); 3255 Configuration.ConfirmDuplicatesPolicy(xmlElem, 3256 "Duplicates", btreeDB.Duplicates, compulsory); 3257 Configuration.ConfirmUint(xmlElem, "MinKeysPerPage", 3258 btreeDB.MinKeysPerPage, compulsory); 3259 /* 3260 * BTreeDatabase.RecordNumbers is the value of 3261 * BTreeDatabaseConfig.UseRecordNumbers. 3262 */ 3263 Configuration.ConfirmBool(xmlElem, "UseRecordNumbers", 3264 btreeDB.RecordNumbers, compulsory); 3265 /* 3266 * BTreeDatabase.ReverseSplit is the value of 3267 * BTreeDatabaseConfig.NoReverseSplitting. 3268 */ 3269 Configuration.ConfirmBool(xmlElem, "NoReverseSplitting", 3270 btreeDB.ReverseSplit, compulsory); 3271 Assert.AreEqual(DatabaseType.BTREE, btreeDB.Type); 3272 string type = btreeDB.ToString(); 3273 Assert.IsNotNull(type); 3274 } 3275 } 3276 } 3277 3278