PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/src/kangmodb/chunkList.h

#
C Header | 227 lines | 157 code | 23 blank | 47 comment | 28 complexity | e5b963839e623ad337c1be9535de4bac MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*
  2. * chunkList.h
  3. * kangmodb
  4. *
  5. * Created by 강모 김 on 11. 5. 1..
  6. * Copyright 2011 강모소프트. All rights reserved.
  7. *
  8. */
  9. #ifndef _KD_CHUNK_LIST_H_
  10. #define _KD_CHUNK_LIST_H_ (1)
  11. #include "list.h"
  12. /** @brief The header stored in the root chunk in the chunk list. Root chunk is the first chunk in the list.
  13. */
  14. typedef struct stgRootChunkHeader
  15. {
  16. /** @brief Keeps head/tail link of the double linked list.
  17. */
  18. list_t chunkList;
  19. } stgRootChunkHeader;
  20. /** @brief The header stored in chunks in the chunk list.
  21. */
  22. typedef struct stgChunkHeader
  23. {
  24. /** @brief Keeps prev/next link of the double linked list.
  25. */
  26. list_node_t nodeLinks;
  27. } stgChunkHeader;
  28. /** @brief Maintain a double linked list that keeps track of multiple memory chunks.
  29. *
  30. * - stgTransLogBuffer uses stgChunkList to keep multiple log chunks for a transaction.
  31. * - stgTable uses stgChunkList to keep multiple memory chunks to keep (key, data) pairs.
  32. */
  33. class stgChunkList
  34. {
  35. private :
  36. /** @brief The first chunk in this chunk list. It has head/tail of the chunk list.
  37. */
  38. stgRootChunkHeader * rootChunk_;
  39. /** @brief The next chunk to iterate. Used by both iterate and reverseIterate.
  40. */
  41. mutable void * nextIterationChunk_;
  42. public :
  43. /** @brief The size of unusable memory at the beginning of added chunk.
  44. */
  45. static const int CHUNK_UNUSABLE_SIZE = MAX(sizeof(stgRootChunkHeader), sizeof(stgChunkHeader));
  46. stgChunkList()
  47. {
  48. rootChunk_ = NULL;
  49. nextIterationChunk_ = NULL;
  50. }
  51. ~stgChunkList()
  52. {
  53. }
  54. /** @brief See if the chunk list is empty.
  55. */
  56. bool empty() const
  57. {
  58. // If the root chunk(the first chunk) is NULL, it means the list is empty.
  59. return rootChunk_ == NULL;
  60. }
  61. /** @brief Add a chunk to the chunk list.
  62. */
  63. KD_VOID addChunk( const void * chunkAddress )
  64. {
  65. KD_TRY
  66. {
  67. if (rootChunk_ == NULL ) // No root chunk. Set the chunk as the root chunk
  68. {
  69. rootChunk_ = (stgRootChunkHeader*) chunkAddress;
  70. (void) list_init( &rootChunk_->chunkList );
  71. }
  72. else
  73. {
  74. stgChunkHeader * chunkHeader = (stgChunkHeader*) chunkAddress;
  75. (void) list_add_tail( &rootChunk_->chunkList, &chunkHeader->nodeLinks);
  76. }
  77. }
  78. KD_CATCH
  79. KD_FINALLY
  80. KD_END
  81. }
  82. /** @brief Remove a chunk from the list.
  83. */
  84. KD_VOID removeChunk( const void * chunkAddress )
  85. {
  86. KD_ASSERT( rootChunk_ != NULL );
  87. KD_TRY
  88. {
  89. // If the root chunk is removed, all chunks in the list are removed as well. This is by design.
  90. if (chunkAddress == rootChunk_ )
  91. {
  92. rootChunk_ = NULL;
  93. }
  94. else // Not a root chunk, remove from the list
  95. {
  96. stgChunkHeader * chunkHeader = (stgChunkHeader*) chunkAddress;
  97. (void) list_remove( &rootChunk_->chunkList, &chunkHeader->nodeLinks );
  98. }
  99. }
  100. KD_CATCH
  101. KD_FINALLY
  102. KD_END
  103. }
  104. /** @brief Initialize iterations.
  105. */
  106. KD_VOID initIteration() const
  107. {
  108. KD_TRY
  109. {
  110. nextIterationChunk_ = rootChunk_;
  111. }
  112. KD_CATCH
  113. KD_FINALLY
  114. KD_END
  115. }
  116. /** @brief Iterate a chunk. If no more chunk, *chunkAddress is set to NULL.
  117. */
  118. KD_VOID iterate( void ** chunkAddress ) const
  119. {
  120. KD_DASSERT( chunkAddress != NULL );
  121. KD_TRY
  122. {
  123. if (nextIterationChunk_ == NULL) // End of iteration
  124. {
  125. *chunkAddress = NULL;
  126. }
  127. else
  128. {
  129. *chunkAddress = nextIterationChunk_ ;
  130. if ( nextIterationChunk_ == rootChunk_ )
  131. {
  132. // Root chunk was the first one to iterate chunks. Next chunk to iterate is the one in head in the list.
  133. nextIterationChunk_ = rootChunk_->chunkList.head;
  134. }
  135. else
  136. {
  137. nextIterationChunk_ = ((stgChunkHeader*) nextIterationChunk_)->nodeLinks.next;
  138. }
  139. if ( nextIterationChunk_ == LIST_NODE_NULL( & rootChunk_->chunkList ) ) // Reached at the end of iteration?
  140. {
  141. nextIterationChunk_ = NULL;
  142. }
  143. }
  144. }
  145. KD_CATCH
  146. KD_FINALLY
  147. KD_END
  148. }
  149. /** @brief Initialize iterations in reverse order.
  150. */
  151. KD_VOID initReverseIteration() const
  152. {
  153. KD_TRY
  154. {
  155. if ( rootChunk_ == NULL ) // No chunk is added yet.
  156. {
  157. nextIterationChunk_ = NULL; // Nothing to iterate.
  158. }
  159. else
  160. {
  161. // Start the reverse iteration from the tail of the list.
  162. nextIterationChunk_ = rootChunk_->chunkList.tail;
  163. }
  164. }
  165. KD_CATCH
  166. KD_FINALLY
  167. KD_END
  168. }
  169. /** @brief Iterate a chunk in reverse order. If no more chunk, *chunkAddress is set to NULL.
  170. */
  171. KD_VOID reverseIterate( void ** chunkAddress ) const
  172. {
  173. KD_DASSERT( chunkAddress != NULL );
  174. KD_TRY
  175. {
  176. if (nextIterationChunk_ == NULL) // End of iteration
  177. {
  178. *chunkAddress = NULL;
  179. }
  180. else
  181. {
  182. *chunkAddress = nextIterationChunk_ ;
  183. if ( nextIterationChunk_ == rootChunk_ )
  184. {
  185. // Root chunk was the last one to iterate chunks in reverse order.
  186. nextIterationChunk_ = NULL;
  187. }
  188. else
  189. {
  190. nextIterationChunk_ = ((stgChunkHeader*) nextIterationChunk_)->nodeLinks.prev;
  191. }
  192. if ( nextIterationChunk_ == LIST_NODE_NULL( & rootChunk_->chunkList ) ) // Reached at the end of the list?
  193. {
  194. // We need to iterate the root chunk, which is the last one to iterate in reverse order.
  195. nextIterationChunk_ = rootChunk_;
  196. }
  197. }
  198. }
  199. KD_CATCH
  200. KD_FINALLY
  201. KD_END
  202. }
  203. };
  204. #endif /* _KD_CHUNK_LIST_H_ */