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.

BTree.h 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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 BTREE_H
  9. #define BTREE_H
  10. #include "modules/search_engine/BTreeBase.h"
  11. #include "modules/search_engine/ResultBase.h"
  12. /**
  13. * @brief B-tree - easy searching and indexing data of the same size on disk.
  14. * @author Pavel Studeny <pavels@opera.com>
  15. *
  16. * This is a thin template based on BTreeBase. Methods Empty, GetId and Clear don't need to be specialized.
  17. */
  18. template <typename KEY> class TBTree : public BTreeBase
  19. {
  20. public:
  21. /** constructor is not supposed to be called directly, use TPool::GetTree/CreateTree instead */
  22. TBTree(PoolBase *cache, BSCache::Item::DiskId root) : BTreeBase(DefDescriptor<KEY>(), cache, root) {}
  23. /** constructor is not supposed to be called directly, use TPool::GetTree/CreateTree instead */
  24. TBTree(PoolBase *cache, BSCache::Item::DiskId root, TypeDescriptor::ComparePtr compare) :
  25. BTreeBase(TypeDescriptor(sizeof(KEY), &DefDescriptor<KEY>::Assign, compare, &DefDescriptor<KEY>::Destruct
  26. #ifdef ESTIMATE_MEMORY_USED_AVAILABLE
  27. , &DefDescriptor<KEY>::EstimateMemoryUsed
  28. #endif
  29. ), cache, root) {}
  30. /**
  31. * insert a single item into the BTree
  32. * @param item KEY to insert
  33. * @param overwrite_existing makes sense only if KEY contains some data not included in comparison
  34. */
  35. CHECK_RESULT(OP_STATUS Insert(const KEY &item, BOOL overwrite_existing = FALSE)) {return BTreeBase::Insert(&item, overwrite_existing);}
  36. CHECK_RESULT(OP_STATUS Insert(SearchIterator<KEY> *iterator, BOOL overwrite_existing = FALSE))
  37. {
  38. // this is a temporary stuff, will be optimized
  39. if (iterator->Empty())
  40. return OpStatus::OK;
  41. do {
  42. RETURN_IF_ERROR(Insert(iterator->Get(), overwrite_existing));
  43. } while (iterator->Next());
  44. return OpStatus::OK;
  45. }
  46. /**
  47. * delete a single item from the BTree
  48. * @param item KEY to delete
  49. * @return OpBoolean::IS_FALSE if the item wasn't found
  50. */
  51. CHECK_RESULT(OP_BOOLEAN Delete(const KEY &item)) {return BTreeBase::Delete(&item);}
  52. /**
  53. * delete a range of items
  54. * @param iterator MUST NOT be obtained from searching from the same B-tree
  55. */
  56. CHECK_RESULT(OP_STATUS Delete(SearchIterator<KEY> *iterator))
  57. {
  58. // this is a temporary stuff, will be optimized
  59. if (iterator->Empty())
  60. return OpStatus::OK;
  61. do {
  62. RETURN_IF_ERROR(Delete(iterator->Get()));
  63. } while (iterator->Next());
  64. return OpStatus::OK;
  65. }
  66. /**
  67. * delete a range of items
  68. * @param first item to delete from
  69. * @param o1 operatorGE: delete including first, operatorGT: delete after first, other: delete from the beginning
  70. * @param last item to delete until
  71. * @param o2 operatorLE: delete including last, operatorLT: delete before last, other: delete until the end
  72. */
  73. CHECK_RESULT(OP_STATUS Delete(const KEY &first, SearchOperator o1, const KEY &last, SearchOperator o2)) {return BTreeBase::Delete(&first, o1, &last, o2);}
  74. /**
  75. * search for the given item
  76. * @param item contains an item to search for on input and the found item on output, if found
  77. * @return OpBoolean::IS_FALSE if BTree is empty, OpStatus::OK if the item wasn't found and OpBoolean::IS_TRUE if the item was found
  78. */
  79. CHECK_RESULT(OP_BOOLEAN Search(KEY &item)) {return BTreeBase::Search(&item);}
  80. /**
  81. * look up the first item
  82. * @param item contains the found item on output, if found
  83. * @return OpBoolean::IS_TRUE if the item was found, OpBoolean::IS_FALSE if BTree is empty
  84. */
  85. CHECK_RESULT(OP_BOOLEAN GetFirst(KEY &item)) {return BTreeBase::GetFirst(&item);}
  86. /**
  87. * look up the last item
  88. * @param item contains the found item on output, if found
  89. * @return OpBoolean::IS_TRUE if the item was found, OpBoolean::IS_FALSE if BTree is empty
  90. */
  91. CHECK_RESULT(OP_BOOLEAN GetLast(KEY &item)) {return BTreeBase::GetLast(&item);}
  92. /**
  93. * find all elements for which (element oper item) is TRUE
  94. * @param item a key to compare
  95. * @param oper operator to perform, one of operatorLT, operatorLE, operatorEQ, operatorGE, operatorGT
  96. * @return NULL on error
  97. */
  98. SearchIterator<KEY> *Search(const KEY &item, SearchOperator oper) {return (SearchIterator<KEY> *)BTreeBase::Search(&item, oper);}
  99. /**
  100. * @return all items in the B-tree beginning with the first one
  101. */
  102. SearchIterator<KEY> *SearchFirst(void) {return (SearchIterator<KEY> *)BTreeBase::SearchFirst();}
  103. /**
  104. * @return all items in the B-tree beginning with the last one
  105. */
  106. SearchIterator<KEY> *SearchLast(void) {return (SearchIterator<KEY> *)BTreeBase::SearchLast();}
  107. protected:
  108. class TResult : public SearchIterator<KEY>, public BTreeBase::Result
  109. {
  110. public:
  111. TResult() {}
  112. ~TResult(void) {Free(); OP_DELETE(this->m_btree);}
  113. virtual BOOL Next(void) {return _Next();}
  114. virtual BOOL Prev(void) {return _Prev();}
  115. CHECK_RESULT(virtual OP_STATUS Error(void) const) {return m_last_error;}
  116. virtual int Count(void) const {return _Count();}
  117. virtual BOOL End(void) const {return _End();}
  118. virtual BOOL Beginning(void) const {return _Beginning();}
  119. virtual const KEY &Get(void) {return *(KEY *)_Get();}
  120. };
  121. virtual IteratorBase *NewResult(BTreeBase::BTreeBranch *current, int pos, SearchOperator oper, const void *key)
  122. {
  123. BTreeBase *bt;
  124. TResult *rv;
  125. if ((bt = OP_NEW(TBTree<KEY>, (*this))) == NULL)
  126. return NULL;
  127. if ((rv = OP_NEW(TResult, ())) == NULL)
  128. {
  129. OP_DELETE(bt);
  130. return NULL;
  131. }
  132. if (OpStatus::IsError(rv->Init(bt, current, pos, oper, key)))
  133. {
  134. OP_DELETE(bt);
  135. OP_DELETE(rv);
  136. return NULL;
  137. }
  138. return rv;
  139. }
  140. };
  141. /**
  142. * @brief cache holding several B-trees in a file
  143. * @author Pavel Studeny <pavels@opera.com>
  144. *
  145. * This is a thin template based on BTreeBase. Methods Open, Close, Abort and Commit don't need to be specialized.
  146. */
  147. template <typename KEY> class TPool : public PoolBase
  148. {
  149. public:
  150. /**
  151. * @param max_cache_branches max. number of branches kept in memory, it is a memory/performance trade-off
  152. */
  153. TPool(int max_cache_branches = BTREE_MAX_CACHE_BRANCHES) : PoolBase(max_cache_branches, DefDescriptor<KEY>()) {}
  154. /**
  155. * @param compare comparison of the items kept in the B-trees; assignment and destruction are not expected to be needed here
  156. * @param max_cache_branches max. number of branches kept in memory, it is a memory/performance trade-off
  157. */
  158. TPool(TypeDescriptor::ComparePtr compare, int max_cache_branches = BTREE_MAX_CACHE_BRANCHES) :
  159. PoolBase(max_cache_branches, TypeDescriptor(sizeof(KEY), DefDescriptor<KEY>::Assign, compare, DefDescriptor<KEY>::Destruct
  160. #ifdef ESTIMATE_MEMORY_USED_AVAILABLE
  161. , DefDescriptor<KEY>::EstimateMemoryUsed
  162. #endif
  163. )) {}
  164. /**
  165. * @param root valid root position returned by DiskBTree::GetId()
  166. * @return valid DiskBTree or NULL on out of memory
  167. */
  168. TBTree<KEY> *GetTree(BSCache::Item::DiskId root)
  169. {
  170. return OP_NEW(TBTree<KEY>, (this, root, m_allocator.Compare));
  171. }
  172. /**
  173. * @return a new empty DiskBTree
  174. */
  175. TBTree<KEY> *CreateTree(void)
  176. {
  177. return OP_NEW(TBTree<KEY>, (this, 0, m_allocator.Compare));
  178. }
  179. };
  180. #endif // BTREE_H