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