Opera 12.15 Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SingleBTree.h 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* -*- Mode: c++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
  2. **
  3. ** Copyright (C) 1995-2011 Opera Software ASA. All rights reserved.
  4. **
  5. ** This file is part of the Opera web browser.
  6. ** It may not be distributed under any circumstances.
  7. */
  8. #ifndef SINGLEBTREE_H
  9. #define SINGLEBTREE_H
  10. #include "modules/search_engine/BTree.h"
  11. #define SBTREE_MAX_CACHE_BRANCHES 50
  12. /**
  13. * @brief BTree stored in a file.
  14. * @author Pavel Studeny <pavels@opera.com>
  15. *
  16. * SingleBTree is a BTree stored on disk.
  17. * Unlike DiskBTree, you can use it directly, since there is only one BTree in the file.
  18. */
  19. template <typename KEY> class SingleBTree :
  20. public TBTree<KEY>,
  21. public TPool<KEY>
  22. {
  23. public:
  24. SingleBTree(int max_cache_branches = SBTREE_MAX_CACHE_BRANCHES) : TBTree<KEY>(this, 0), TPool<KEY>(max_cache_branches) {}
  25. SingleBTree(TypeDescriptor::ComparePtr compare, int max_cache_branches = SBTREE_MAX_CACHE_BRANCHES) :
  26. TBTree<KEY>(this, 0, compare), TPool<KEY>(compare, max_cache_branches) {}
  27. /**
  28. * SingleBTree must be opened before you call any other method
  29. * @param path file storing the data; file is always created if it doesn't exist
  30. * @param mode Read/ReadWrite mode
  31. * @param blocksize one block consists of 12 B of internal BlockStorage data, 4 B rightmost pointer and the rest is divided into (sizeof(data) + 4 B pointer) chunks
  32. * @param folder might be one of predefind folders
  33. */
  34. CHECK_RESULT(OP_STATUS Open(const uni_char* path, BlockStorage::OpenMode mode, int blocksize = 512, OpFileFolder folder = OPFILE_ABSOLUTE_FOLDER))
  35. {
  36. RETURN_IF_ERROR((TPool<KEY>::Open(path, mode, blocksize, folder)));
  37. if (this->m_storage.GetFileSize() > (OpFileLength)this->m_storage.GetBlockSize() * 2)
  38. this->m_root = 2;
  39. return OpStatus::OK;
  40. }
  41. /** Recovery function for corrupted SingleBTree
  42. * SingleBTree must be closed before you call this function
  43. * @param path file name of the original SingleBTree
  44. * @param blocksize blocksize of original SingleBTree
  45. * @param folder might be one of predefind folders
  46. */
  47. CHECK_RESULT(OP_STATUS Recover(const uni_char* path, int blocksize = 512, OpFileFolder folder = OPFILE_ABSOLUTE_FOLDER))
  48. {
  49. OpString temp_filename;
  50. RETURN_IF_ERROR(temp_filename.AppendFormat(UNI_L("%s.temp"),path));
  51. SingleBTree<KEY> temp_tree;
  52. // Open new btree
  53. RETURN_IF_ERROR(temp_tree.Open(temp_filename.CStr(), BlockStorage::OpenReadWrite, blocksize, folder));
  54. // Open old btree
  55. RETURN_IF_ERROR(Open(path, BlockStorage::OpenRead, blocksize, folder));
  56. OpAutoPtr<SearchIterator<KEY> > tree_iterator(this->SearchFirst());
  57. if (!tree_iterator.get())
  58. return OpStatus::ERR_NO_MEMORY;
  59. if (!tree_iterator->Empty())
  60. {
  61. // loop through the old tree and add stuff as we find them
  62. do
  63. {
  64. RETURN_IF_ERROR(temp_tree.Insert(KEY(tree_iterator->Get())));
  65. }
  66. while (tree_iterator->Next());
  67. }
  68. // open iterators need to be closed before closing the tree
  69. tree_iterator.reset();
  70. RETURN_IF_ERROR(this->Close());
  71. RETURN_IF_ERROR(temp_tree.Close());
  72. // Delete the old tree and move new tree to the correct location
  73. RETURN_IF_ERROR(BlockStorage::DeleteFile(path, folder));
  74. return BlockStorage::RenameFile(temp_filename.CStr(), path, folder);
  75. }
  76. protected:
  77. CHECK_RESULT(virtual OP_STATUS NewBranch(BTreeBase::BTreeBranch **branch, BTreeBase::BTreeBranch *parent))
  78. {
  79. if (this->m_root == 0 && this->m_head != NULL)
  80. RETURN_IF_ERROR(this->Flush());
  81. RETURN_IF_ERROR(TBTree<KEY>::NewBranch(branch, parent));
  82. if (this->m_root < 0 && this->m_root == (*branch)->disk_id)
  83. TBTree<KEY>::SafePointer(*branch); // SafePointer will set this->m_root
  84. return OpStatus::OK;
  85. }
  86. };
  87. #endif // SINGLEBTREE_H