Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
dat.hpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2 -*- */
2 /* Copyright(C) 2011 Brazil
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License version 2.1 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Lesser General Public License for more details.
12 
13  You should have received a copy of the GNU Lesser General Public
14  License along with this library; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef GRN_DAT_COMMON_HPP_
19 #define GRN_DAT_COMMON_HPP_
20 
21 #ifndef _MSC_VER
22 # include <stddef.h>
23 # include <stdint.h>
24 #endif // _MSC_VER
25 
26 #include <cstddef>
27 #include <exception>
28 
29 #ifdef _DEBUG
30 # include <iostream>
31 #endif // _DEBUG
32 
33 #ifndef GRN_DAT_API
34 # ifdef WIN32
35 # ifdef GRN_DAT_EXPORT
36 # define GRN_DAT_API __declspec(dllexport)
37 # else // GRN_DAT_EXPORT
38 # define GRN_DAT_API __declspec(dllimport)
39 # endif // GRN_DAT_EXPORT
40 # else // WIN32
41 # define GRN_DAT_API
42 # endif // WIN32
43 #endif // GRN_DAT_API
44 
45 namespace grn {
46 namespace dat {
47 
48 #ifdef _MSC_VER
49 typedef unsigned __int8 UInt8;
50 typedef unsigned __int16 UInt16;
51 typedef unsigned __int32 UInt32;
52 typedef unsigned __int64 UInt64;
53 #else // _MSC_VER
54 typedef ::uint8_t UInt8;
55 typedef ::uint16_t UInt16;
56 typedef ::uint32_t UInt32;
57 typedef ::uint64_t UInt64;
58 #endif // _MSC_VER
59 
60 const UInt8 MAX_UINT8 = static_cast<UInt8>(0xFFU);
61 const UInt16 MAX_UINT16 = static_cast<UInt16>(0xFFFFU);
62 const UInt32 MAX_UINT32 = static_cast<UInt32>(0xFFFFFFFFU);
63 const UInt64 MAX_UINT64 = static_cast<UInt64>(0xFFFFFFFFFFFFFFFFULL);
64 
65 // If a key is a prefix of another key, such a key is associated with a special
66 // terminal node which has TERMINAL_LABEL.
67 const UInt16 TERMINAL_LABEL = 0x100;
68 const UInt16 MIN_LABEL = '\0';
70 const UInt32 INVALID_LABEL = 0x1FF;
71 const UInt32 LABEL_MASK = 0x1FF;
72 
73 // The MSB of BASE is used to represent whether the node is a linker node or
74 // not and the other 31 bits represent the offset to its child nodes. So, the
75 // number of nodes is limited to 2^31.
76 const UInt32 ROOT_NODE_ID = 0;
77 const UInt32 MAX_NODE_ID = 0x7FFFFFFF;
80 
81 // 0 is reserved for non-linker leaf nodes. For example, the root node of an
82 // initial double-array is a non-linker leaf node.
85 
86 // Phantom nodes are managed in each block because siblings are always put in
87 // the same block.
88 const UInt32 BLOCK_SIZE = 0x200;
89 const UInt32 BLOCK_MASK = 0x1FF;
92 
93 // Blocks are divided by their levels, which indicate how easily update
94 // operations can find a good offset in them. The level of a block rises when
95 // find_offset() fails in that block many times. MAX_FAILURE_COUNT is the
96 // threshold. Also, in order to limit the time cost, find_offset() scans at
97 // most MAX_BLOCK_COUNT blocks.
98 // Larger parameters bring more chances of finding good offsets but it leads to
99 // more node renumberings, which are costly operations, and thus results in
100 // a degradation of space/time efficiencies.
104 
105 // Blocks in the same level compose a doubly linked list. The entry block of
106 // a linked list is called a leader. INVALID_LEADER means that a linked list is
107 // empty and there exists no leader.
108 const UInt32 INVALID_LEADER = 0x7FFFFFFF;
109 
110 const UInt32 MIN_KEY_ID = 1;
113 
114 // A key length is represented as a 12-bit unsigned integer in Key.
115 // A key ID is represented as a 28-bit unsigned integer in Key.
116 const UInt32 MAX_KEY_LENGTH = (1U << 12) - 1;
117 const UInt32 MAX_NUM_KEYS = (1U << 28) - 1;
118 
119 const UInt64 MIN_FILE_SIZE = 1 << 16;
120 const UInt64 DEFAULT_FILE_SIZE = 1 << 20;
121 const UInt64 MAX_FILE_SIZE = (UInt64)1 << 40;
122 const double DEFAULT_NUM_NODES_PER_KEY = 4.0;
123 const double DEFAULT_AVERAGE_KEY_LENGTH = 16.0;
124 const UInt32 MAX_KEY_BUF_SIZE = 0x80000000U;
125 const UInt32 MAX_TOTAL_KEY_LENGTH = 0xFFFFFFFFU;
126 
127 const UInt32 ID_RANGE_CURSOR = 0x00001;
128 const UInt32 KEY_RANGE_CURSOR = 0x00002;
129 const UInt32 PREFIX_CURSOR = 0x00004;
130 const UInt32 PREDICTIVE_CURSOR = 0x00008;
131 const UInt32 CURSOR_TYPE_MASK = 0x000FF;
132 
133 const UInt32 ASCENDING_CURSOR = 0x00100;
134 const UInt32 DESCENDING_CURSOR = 0x00200;
135 const UInt32 CURSOR_ORDER_MASK = 0x00F00;
136 
137 const UInt32 EXCEPT_LOWER_BOUND = 0x01000;
138 const UInt32 EXCEPT_UPPER_BOUND = 0x02000;
139 const UInt32 EXCEPT_EXACT_MATCH = 0x04000;
140 const UInt32 CURSOR_OPTIONS_MASK = 0xFF000;
141 
142 const UInt32 REMOVING_FLAG = 1U << 0;
143 const UInt32 INSERTING_FLAG = 1U << 1;
144 const UInt32 UPDATING_FLAG = 1U << 2;
146 
148 
149 enum ErrorCode {
151  IO_ERROR = -2,
157 };
158 
159 class Exception : public std::exception {
160  public:
161  Exception() throw()
162  : std::exception(),
163  file_(""),
164  line_(-1),
165  what_("") {}
166  Exception(const char *file, int line, const char *what) throw()
167  : std::exception(),
168  file_(file),
169  line_(line),
170  what_((what != NULL) ? what : "") {}
171  Exception(const Exception &ex) throw()
172  : std::exception(ex),
173  file_(ex.file_),
174  line_(ex.line_),
175  what_(ex.what_) {}
176  virtual ~Exception() throw() {}
177 
178  virtual Exception &operator=(const Exception &ex) throw() {
179  file_ = ex.file_;
180  line_ = ex.line_;
181  what_ = ex.what_;
182  return *this;
183  }
184 
185  virtual ErrorCode code() const throw() = 0;
186  virtual const char *file() const throw() {
187  return file_;
188  }
189  virtual int line() const throw() {
190  return line_;
191  }
192  virtual const char *what() const throw() {
193  return what_;
194  }
195 
196  private:
197  const char *file_;
198  int line_;
199  const char *what_;
200 };
201 
202 template <ErrorCode T>
203 class Error : public Exception {
204  public:
205  Error() throw()
206  : Exception() {}
207  Error(const char *file, int line, const char *what) throw()
208  : Exception(file, line, what) {}
209  Error(const Error &ex) throw()
210  : Exception(ex) {}
211  virtual ~Error() throw() {}
212 
213  virtual Error &operator=(const Error &ex) throw() {
214  *static_cast<Exception *>(this) = ex;
215  return *this;
216  }
217 
218  virtual ErrorCode code() const throw() {
219  return T;
220  }
221 };
222 
230 
231 #define GRN_DAT_INT_TO_STR(value) #value
232 #define GRN_DAT_LINE_TO_STR(line) GRN_DAT_INT_TO_STR(line)
233 #define GRN_DAT_LINE_STR GRN_DAT_LINE_TO_STR(__LINE__)
234 
235 #define GRN_DAT_THROW(code, msg)\
236  (throw grn::dat::Error<code>(__FILE__, __LINE__,\
237  __FILE__ ":" GRN_DAT_LINE_STR ": " #code ": " msg))
238 #define GRN_DAT_THROW_IF(code, cond)\
239  (void)((!(cond)) || (GRN_DAT_THROW(code, #cond), 0))
240 
241 #ifdef _DEBUG
242  #define GRN_DAT_DEBUG_THROW_IF(cond)\
243  GRN_DAT_THROW_IF(grn::dat::UNEXPECTED_ERROR, cond)
244  #define GRN_DAT_DEBUG_LOG(var)\
245  (std::clog << __FILE__ ":" GRN_DAT_LINE_STR ": " #var ": "\
246  << (var) << std::endl)
247 #else // _DEBUG
248  #define GRN_DAT_DEBUG_THROW_IF(cond)
249  #define GRN_DAT_DEBUG_LOG(var)
250 #endif // _DEBUG
251 
252 } // namespace dat
253 } // namespace grn
254 
255 #endif // GRN_DAT_COMMON_HPP_