0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Key.cc
Go to the documentation of this file.
1 
22 #include "Common/Compat.h"
23 #include <cassert>
24 #include <iostream>
25 
26 #include "Key.h"
27 
28 using namespace Hypertable;
29 using namespace std;
30 
31 
32 namespace {
33  const char end_row_chars[3] = { (char)0xff, (char)0xff, 0 };
34  const char end_root_row_chars[7] = { '0', '/', '0', ':', (char)0xff, (char)0xff, 0 };
35 
36  size_t
37  write_key(uint8_t *buf, uint8_t control, uint8_t flag, const char *row, uint32_t row_len,
38  uint8_t column_family_code, const char *column_qualifier, uint32_t column_qualifier_len) {
39  uint8_t *ptr = buf;
40  *ptr++ = control;
41  strcpy((char *)ptr, row);
42  ptr += row_len + 1;
43  *ptr++ = column_family_code;
44  if (column_qualifier) {
45  strcpy((char *)ptr, column_qualifier);
46  ptr += column_qualifier_len + 1;
47  }
48  else
49  *ptr++ = 0;
50  *ptr++ = flag;
51  return ptr-buf;
52  }
53 
54  void
55  create_key_and_append(DynamicBuffer &dst_buf, uint8_t flag, const char *row,
56  uint32_t row_len, uint8_t column_family_code, const char *column_qualifier,
57  uint32_t column_qualifier_len, int64_t timestamp, int64_t revision,
58  bool time_order_asc) {
59  size_t len = 1 + row_len + 4 + column_qualifier_len;
60  uint8_t control = 0;
61 
62  if (timestamp == AUTO_ASSIGN)
63  control = Key::AUTO_TIMESTAMP;
64  else if (timestamp != TIMESTAMP_NULL) {
65  len += 8;
66  control = Key::HAVE_TIMESTAMP;
67  if (timestamp == revision)
68  control |= Key::REV_IS_TS;
69  }
70 
71  if (!time_order_asc)
72  control |= Key::TS_CHRONOLOGICAL;
73 
74  if (revision != AUTO_ASSIGN) {
75  if (!(control & Key::REV_IS_TS))
76  len += 8;
77  control |= Key::HAVE_REVISION;
78  }
79 
80  if (dst_buf.remaining() < len + 6)
81  dst_buf.grow(dst_buf.fill() + len + 6);
82  Serialization::encode_vi32(&dst_buf.ptr, len);
83  dst_buf.ptr += write_key(dst_buf.ptr, control, flag, row, row_len,
84  column_family_code, column_qualifier, column_qualifier_len);
85 
86  if (control & Key::HAVE_TIMESTAMP)
87  Key::encode_ts64(&dst_buf.ptr, timestamp, time_order_asc);
88 
89  if ((control & Key::HAVE_REVISION)
90  && !(control & Key::REV_IS_TS))
91  Key::encode_ts64(&dst_buf.ptr, revision);
92 
93  assert(dst_buf.fill() <= dst_buf.size);
94 
95  }
96 }
97 
98 
99 namespace Hypertable {
100 
101  const char *Key::END_ROW_MARKER = (const char *)end_row_chars;
102  const char *Key::END_ROOT_ROW = (const char *)end_root_row_chars;
103 
104  void
105  create_key_and_append(DynamicBuffer &dst_buf, const Key& key, bool time_order_asc) {
107  dst_buf,
108  key.flag,
109  key.row,
110  key.row_len,
111  key.column_family_code,
112  key.column_qualifier,
114  key.timestamp,
115  AUTO_ASSIGN,//key.revision,
116  time_order_asc);
117  }
118 
119  void
120  create_key_and_append(DynamicBuffer &dst_buf, uint8_t flag, const char *row,
121  uint8_t column_family_code, const char *column_qualifier,
122  int64_t timestamp, int64_t revision, bool time_order_asc) {
124  dst_buf,
125  flag,
126  row,
127  strlen(row),
128  column_family_code,
129  column_qualifier,
130  column_qualifier && *column_qualifier ? strlen(column_qualifier) : 0,
131  timestamp,
132  revision,
133  time_order_asc);
134  }
135 
136  void create_key_and_append(DynamicBuffer &dst_buf, const char *row, bool time_order_asc) {
137  uint8_t control = Key::HAVE_REVISION
138  | Key::HAVE_TIMESTAMP | Key::REV_IS_TS;
139  if (!time_order_asc)
140  control |= Key::TS_CHRONOLOGICAL;
141  size_t row_len = strlen(row);
142  size_t len = 13 + row_len;
143  if (dst_buf.remaining() < len + 6)
144  dst_buf.grow(dst_buf.fill() + len + 6);
145  Serialization::encode_vi32(&dst_buf.ptr, len);
146  dst_buf.ptr += write_key(dst_buf.ptr, control, 0, row, row_len, 0, 0, 0);
147  Key::encode_ts64(&dst_buf.ptr, 0);
148  assert(dst_buf.fill() <= dst_buf.size);
149  }
150 
151  Key::Key(const SerializedKey& key) {
152  HT_EXPECT(load(key), Error::BAD_KEY);
153  }
154 
158  bool Key::load(const SerializedKey& key) {
159  serial = key;
160  const uint8_t* ptr = serial.ptr;
161  size_t len = Serialization::decode_vi32(&ptr);
162 
163  length = len + (ptr - serial.ptr);
164 
165  const uint8_t *end_ptr = ptr + len;
166 
167  control = *ptr++;
168  row = (const char *)ptr;
169 
170  while (ptr < end_ptr && *ptr != 0)
171  ptr++;
172 
173  row_len = ptr - (uint8_t *)row;
174  assert(strlen(row) == row_len);
175  ptr++;
176 
177  if (ptr >= end_ptr) {
178  cerr << "row decode overrun" << endl;
179  return false;
180  }
181 
182  column_family_code = *ptr++;
183  column_qualifier = (const char *)ptr;
184 
185  while (ptr < end_ptr && *ptr != 0)
186  ptr++;
187 
188  column_qualifier_len = ptr - (uint8_t *)column_qualifier;
189  assert(strlen(column_qualifier) == column_qualifier_len);
190  ptr++;
191 
192  if (ptr >= end_ptr) {
193  cerr << "qualifier decode overrun" << endl;
194  return false;
195  }
196 
197  flag_ptr = ptr;
198  flag = *ptr++;
199 
200  if (control & HAVE_TIMESTAMP) {
201  timestamp = decode_ts64((const uint8_t **)&ptr,
202  (control&TS_CHRONOLOGICAL) == 0);
203  if (control & REV_IS_TS) {
204  revision = timestamp;
205  assert(ptr == end_ptr);
206  return true;
207  }
208  }
209  else {
210  if (control & AUTO_TIMESTAMP)
211  timestamp = AUTO_ASSIGN;
212  else
213  timestamp = TIMESTAMP_NULL;
214  }
215 
216  if (control & HAVE_REVISION)
217  revision = decode_ts64((const uint8_t **)&ptr,
218  (control&TS_CHRONOLOGICAL) == 0);
219  else
220  revision = AUTO_ASSIGN;
221 
222  assert(ptr == end_ptr);
223 
224  return true;
225  }
226 
227 
228  std::ostream &operator<<(std::ostream &os, const Key &key) {
229  bool got = false;
230  os << "control=(";
231  if (key.control & Key::HAVE_REVISION) {
232  os << "REV";
233  got = true;
234  }
235  if (key.control & Key::HAVE_TIMESTAMP) {
236  os << ((got) ? "|TS" : "TS");
237  got = true;
238  }
239  if (key.control & Key::AUTO_TIMESTAMP) {
240  os << ((got) ? "|AUTO" : "AUTO");
241  got = true;
242  }
243  if (key.control & Key::REV_IS_TS) {
244  os << ((got) ? "|SHARED" : "SHARED");
245  got = true;
246  }
247  os << ") row='" << key.row << "' ";
248  if (key.flag == FLAG_DELETE_ROW)
249  os << "ts=" << key.timestamp << " rev=" << key.revision << " DELETE_ROW";
250  else {
251  os << "family=" << (int)key.column_family_code;
252  if (key.column_qualifier)
253  os << " qualifier='" << key.column_qualifier << "'";
254  os << " ts=" << key.timestamp;
255  os << " rev=" << key.revision;
256 
257  if (key.flag == FLAG_DELETE_ROW)
258  os << " DELETE_ROW";
259  else if (key.flag == FLAG_DELETE_COLUMN_FAMILY)
260  os << " DELETE_COLUMN_FAMILY";
261  else if (key.flag == FLAG_DELETE_CELL)
262  os << " DELETE_CELL";
263  else if (key.flag == FLAG_DELETE_CELL_VERSION)
264  os << " DELETE_CELL_VERSION";
265  else if (key.flag == FLAG_INSERT)
266  os << " INSERT";
267  else
268  os << key.flag << "(unrecognized flag)";
269  }
270  return os;
271  }
272 }
int64_t timestamp
Definition: Key.h:134
const char * row
Definition: Key.h:129
uint8_t control
Definition: Key.h:126
static const uint32_t FLAG_DELETE_ROW
Definition: KeySpec.h:40
static const uint32_t FLAG_INSERT
Definition: KeySpec.h:47
static const uint8_t HAVE_REVISION
Definition: Key.h:43
static const uint32_t FLAG_DELETE_CELL
Definition: KeySpec.h:42
STL namespace.
uint8_t * ptr
Pointer to the end of the used part of the buffer.
A dynamic, resizable and reference counted memory buffer.
Definition: DynamicBuffer.h:42
static const uint32_t FLAG_DELETE_COLUMN_FAMILY
Definition: KeySpec.h:41
#define HT_EXPECT(_e_, _code_)
Definition: Logger.h:388
uint32_t row_len
Definition: Key.h:131
void grow(size_t new_size, bool nocopy=false)
Grows the buffer and copies the data unless nocopy is true.
Key()
Constructor (for implicit construction).
Definition: Key.h:93
uint32_t size
The size of the allocated memory buffer (base)
Compatibility Macros for C/C++.
static const uint8_t HAVE_TIMESTAMP
Definition: Key.h:44
std::ostream & operator<<(std::ostream &os, const crontab_entry &entry)
Helper function to write crontab_entry to an ostream.
Definition: Crontab.cc:301
bool load(const SerializedKey &key)
Parses the opaque key and loads the components into the member variables.
Definition: Key.cc:158
static const int64_t TIMESTAMP_NULL
Definition: KeySpec.h:36
static const uint8_t TS_CHRONOLOGICAL
Definition: Key.h:47
const uint8_t * ptr
The pointer to the serialized data.
Definition: ByteString.h:121
Hypertable definitions
void encode_vi32(uint8_t **bufp, uint32_t val)
Encode a integer (up to 32-bit) in variable length encoding.
static const uint8_t AUTO_TIMESTAMP
Definition: Key.h:45
void create_key_and_append(DynamicBuffer &dst_buf, const Key &key, bool time_order_asc)
Definition: Key.cc:105
Provides access to internal components of opaque key.
Definition: Key.h:40
uint32_t column_qualifier_len
Definition: Key.h:132
size_t fill() const
Returns the size of the used portion.
Definition: DynamicBuffer.h:70
static void encode_ts64(uint8_t **bufp, int64_t val, bool ascending=true)
Definition: Key.h:52
static const char * END_ROOT_ROW
Definition: Key.h:50
int64_t revision
Definition: Key.h:135
uint8_t column_family_code
Definition: Key.h:127
static const int64_t AUTO_ASSIGN
Definition: KeySpec.h:38
uint8_t flag
Definition: Key.h:125
const char * column_qualifier
Definition: Key.h:130
static const char * END_ROW_MARKER
Definition: Key.h:49
static const uint32_t FLAG_DELETE_CELL_VERSION
Definition: KeySpec.h:43
uint32_t decode_vi32(const uint8_t **bufp, size_t *remainp)
Decode a variable length encoded integer up to 32-bit.
size_t remaining() const
Returns the size of the unused portion.
Definition: DynamicBuffer.h:67
static const uint8_t REV_IS_TS
Definition: Key.h:46