Zero  0.1.0
w_key.h
Go to the documentation of this file.
1 #ifndef __W_KEY_H
2 #define __W_KEY_H
3 
4 #include <cassert>
5 #include <cstring>
6 #include <string>
7 #include <ostream>
8 #include <iostream> // for cout
9 #include <cstdint>
10 #include "w_endian.h"
11 
12 class w_keystr_t_test;
13 class cvec_t;
14 
15 // for now, let's use 'weird' sign bytes which is good for debugging.
16 // later, just use 0, 1,.. for better compression.
17 const unsigned char SIGN_NEGINF = 42;
18 
19 const unsigned char SIGN_REGULAR = 43;
20 
21 const unsigned char SIGN_POSINF = 44;
22 
23 typedef uint32_t w_keystr_len_t;
24 
47 class w_keystr_t {
48  friend class w_keystr_t_test;
49 
50  friend std::ostream& operator<<(std::ostream&, const w_keystr_t& v);
51 
52 public:
60  w_keystr_t();
61 
62  w_keystr_t(const w_keystr_t& r);
63 
64  w_keystr_t& operator=(const w_keystr_t& r);
65 
66  ~w_keystr_t();
67 
84  bool construct_regularkey(const void* nonkeystr, w_keystr_len_t length);
85 
87  bool construct_neginfkey();
88 
90  bool construct_posinfkey();
91 
98  bool construct_from_keystr(const void* keystr, w_keystr_len_t length);
99 
101  bool construct_from_keystr(const void* keystr_prefix, w_keystr_len_t prefix_length,
102  const void* keystr_suffix, w_keystr_len_t suffix_length);
103 
111  const void* keystr_prefix, w_keystr_len_t prefix_length,
112  w_keystr_len_t total_suffix_length, uint16_t poormkey,
113  const void* keystr_suffix);
114  // add 32 version if needed
115 
120  bool construct_from_vec(const cvec_t& vect);
121 
126  bool copy_from_vec(const cvec_t& vect);
127 
133  bool is_constructed() const;
134 
136  bool is_neginf() const;
137 
139  bool is_posinf() const;
140 
142  bool is_regular() const;
143 
146 
148  w_keystr_len_t common_leading_bytes(const unsigned char* str, w_keystr_len_t len) const;
149 
151  static w_keystr_len_t common_leading_bytes(const unsigned char* str1, w_keystr_len_t len1,
152  const unsigned char* str2, w_keystr_len_t len2);
153 
158  static int compare_bin_str(const void* str1, int len1, const void* str2, int len2);
159 
165  int compare(const w_keystr_t& r) const;
166 
174  int compare_keystr(const void* keystr, w_keystr_len_t length) const;
175 
184  int compare_nonkeystr(const void* nonkeystr, w_keystr_len_t length) const;
185 
187  inline bool operator==(const w_keystr_t& r) const;
188 
189  inline bool operator!=(const w_keystr_t& r) const;
190 
191  inline bool operator<(const w_keystr_t& r) const;
192 
193  inline bool operator>(const w_keystr_t& r) const;
194 
195  inline bool operator<=(const w_keystr_t& r) const;
196 
197  inline bool operator>=(const w_keystr_t& r) const;
198 
202  void serialize_as_nonkeystr(void* buffer) const;
203 
205  std::basic_string<unsigned char> serialize_as_nonkeystr() const;
206 
209 
213  void serialize_as_keystr(void* buffer) const;
214 
216  const void* buffer_as_keystr() const;
217 
220 
222  void clear();
223 
224 private:
226  unsigned char* _data;
227 
229  uint32_t _strlen;
230 
232  uint32_t _memlen;
233 
235  void _assure(w_keystr_len_t required_len);
236 };
237 
238 inline void w_keystr_t::_assure(w_keystr_len_t required_len) {
239  if (_memlen >= required_len) {
240  return;
241  }
242  if (_data != nullptr) {
243  delete[] _data;
244  }
245  _data = new unsigned char[required_len];
246  if (_data != nullptr) {
247  _memlen = required_len;
248  } else {
249  _memlen = 0;
250  }
251 }
252 
253 inline w_keystr_t::w_keystr_t() : _data(nullptr),
254  _strlen(0),
255  _memlen(0) {}
256 
257 inline w_keystr_t::w_keystr_t(const w_keystr_t& r) : _data(nullptr),
258  _strlen(r._strlen),
259  _memlen(0) {
260  assert (r._strlen == 0 || r.is_neginf() || r.is_regular() || r.is_posinf());
261  if (r._data != nullptr) {
262  _assure(_strlen);
263  if (_data != nullptr) {
264  ::memcpy(_data, r._data, _strlen);
265  }
266  }
267 }
268 
270  assert (r._strlen == 0 || r.is_neginf() || r.is_regular() || r.is_posinf());
271  _strlen = r._strlen;
272  if (r._data != nullptr) {
273  _assure(_strlen);
274  if (_data != nullptr) {
275  ::memcpy(_data, r._data, _strlen);
276  }
277  }
278  return *this;
279 }
280 
281 inline bool w_keystr_t::construct_regularkey(const void* nonkeystr, w_keystr_len_t length) {
282  assert (nonkeystr != nullptr);
283  _strlen = length + 1;
284  _assure(_strlen);
285  if (_data == nullptr) {
286  return false;
287  }
288  _data[0] = SIGN_REGULAR;
289  ::memcpy(_data + 1, nonkeystr, length);
290  return true;
291 }
292 
294  _strlen = 1;
295  _assure(_strlen);
296  if (_data == nullptr) {
297  return false;
298  }
299  _data[0] = SIGN_NEGINF;
300  return true;
301 }
302 
304  _strlen = 1;
305  _assure(_strlen);
306  if (_data == nullptr) {
307  return false;
308  }
309  _data[0] = SIGN_POSINF;
310  return true;
311 }
312 
313 // used only for asserts
314 inline bool _valid_signbyte(const void* keystr) {
315  return ((const unsigned char*)keystr)[0] == SIGN_NEGINF // *
316  || ((const unsigned char*)keystr)[0] == SIGN_REGULAR // +
317  || ((const unsigned char*)keystr)[0] == SIGN_POSINF; // ,
318 }
319 
320 inline bool w_keystr_t::construct_from_keystr(const void* keystr, w_keystr_len_t length) {
321  assert (length == 0 || keystr != nullptr);
322  assert (length == 0 || _valid_signbyte(keystr));
323  _strlen = length;
324  _assure(_strlen);
325  if (_data == nullptr) {
326  return false;
327  }
328  ::memcpy(_data, keystr, length);
329  return true;
330 }
331 
332 inline bool w_keystr_t::construct_from_keystr(const void* keystr_prefix, w_keystr_len_t prefix_length,
333  const void* keystr_suffix, w_keystr_len_t suffix_length) {
334  assert (keystr_prefix != nullptr);
335  assert ((prefix_length == 0 && _valid_signbyte(keystr_suffix))
336  || _valid_signbyte(keystr_prefix));
337  assert (keystr_suffix != nullptr);
338  _strlen = prefix_length + suffix_length;
339  _assure(_strlen);
340  if (_data == nullptr) {
341  return false;
342  }
343  ::memcpy(_data, keystr_prefix, prefix_length);
344  ::memcpy(_data + prefix_length, keystr_suffix, suffix_length);
345  return true;
346 }
347 
349  const void* keystr_prefix, w_keystr_len_t prefix_length,
350  w_keystr_len_t total_suffix_length, uint16_t poormkey,
351  const void* keystr_suffix) {
352  assert (keystr_prefix != nullptr);
353  _strlen = prefix_length + total_suffix_length;
354  _assure(_strlen);
355  if (_data == nullptr) {
356  return false;
357  }
358  ::memcpy(_data, keystr_prefix, prefix_length);
359  if (total_suffix_length > 0) {
360  if (total_suffix_length < sizeof(poormkey)) {
361  uint16_t tmp;
362  serialize16_be(&tmp, poormkey);
363  _data[prefix_length] = *reinterpret_cast<unsigned char*>(&tmp);
364  assert (reinterpret_cast<unsigned char*>(&tmp)[1] == 0);
365  } else {
366  serialize16_be(_data + prefix_length, poormkey);
367  if (total_suffix_length > sizeof(poormkey)) {
368  assert (keystr_suffix != nullptr);
369  ::memcpy(_data + prefix_length + sizeof(poormkey), keystr_suffix,
370  total_suffix_length - sizeof(poormkey));
371  }
372  }
373  }
374  assert (_valid_signbyte(_data));
375  return true;
376 }
377 
379  clear();
380 }
381 
382 inline bool w_keystr_t::is_constructed() const {
383  return _data != nullptr;
384 }
385 
386 inline int w_keystr_t::compare_bin_str(const void* str1, int len1, const void* str2, int len2) {
387  int d = ::memcmp(str1, str2, (len1 <= len2 ? len1 : len2));
388  // if strings are same, compare the length
389  if (d == 0) {
390  d = (int)len1 - (int)len2;
391  }
392  return d;
393 }
394 
395 inline int w_keystr_t::compare(const w_keystr_t& r) const {
396  return compare_keystr(r._data, r._strlen);
397 }
398 
400  assert (_data != nullptr);
401  assert (r._data != nullptr);
402  assert (_valid_signbyte(_data));
403  assert (_valid_signbyte(r._data));
405 }
406 
407 inline w_keystr_len_t w_keystr_t::common_leading_bytes(const unsigned char* str, w_keystr_len_t len) const {
408  assert (_data != nullptr);
409  assert (str != nullptr);
410  assert (_valid_signbyte(_data));
411  assert (_valid_signbyte(str));
412  return common_leading_bytes(_data, _strlen, str, len);
413 }
414 
415 inline w_keystr_len_t w_keystr_t::common_leading_bytes(const unsigned char* str1, w_keystr_len_t len1,
416  const unsigned char* str2, w_keystr_len_t len2) {
417  assert (str1 != nullptr);
418  assert (str2 != nullptr);
419  w_keystr_len_t cmp_len = (len1 <= len2) ? len1 : len2;
420  for (w_keystr_len_t i = 0; i < cmp_len; ++i) {
421  if (str1[i] != str2[i]) {
422  return i;
423  }
424  }
425  return cmp_len;
426 }
427 
428 inline int w_keystr_t::compare_keystr(const void* keystr, w_keystr_len_t length) const {
429  assert (_data != nullptr);
430  assert (keystr != nullptr);
431  assert (_valid_signbyte(keystr));
432  return compare_bin_str(_data, _strlen, keystr, length);
433 }
434 
435 inline int w_keystr_t::compare_nonkeystr(const void* nonkeystr, w_keystr_len_t length) const {
436  assert (_data != nullptr);
437  assert (nonkeystr != nullptr);
438  if (is_neginf()) {
439  return -1;
440  }
441  if (is_posinf()) {
442  return 1;
443  }
444  return compare_bin_str(_data + 1, _strlen - 1, nonkeystr, length);
445 }
446 
447 inline void w_keystr_t::clear() {
448  delete[] _data; // this is okay with _data==nullptr
449  _data = nullptr;
450  _strlen = 0;
451  _memlen = 0;
452 }
453 
454 inline bool w_keystr_t::is_neginf() const {
455  if (_strlen == 0) {
456  return false;
457  }
458  assert (is_constructed());
459  return ((const char*)_data)[0] == SIGN_NEGINF;
460 }
461 
462 inline bool w_keystr_t::is_posinf() const {
463  if (_strlen == 0) {
464  return false;
465  }
466  assert (is_constructed());
467  return ((const char*)_data)[0] == SIGN_POSINF;
468 }
469 
470 inline bool w_keystr_t::is_regular() const {
471  if (_strlen == 0) {
472  return false;
473  }
474  assert (is_constructed());
475  return ((const char*)_data)[0] == SIGN_REGULAR;
476 }
477 
478 inline void w_keystr_t::serialize_as_nonkeystr(void* buffer) const {
479  assert (buffer != nullptr);
480  assert (is_constructed());
481  assert (!is_neginf() && !is_posinf()); // these can't be serialized as non-key
482  ::memcpy(buffer, _data + 1, _strlen - 1);
483 }
484 
485 inline std::basic_string<unsigned char> w_keystr_t::serialize_as_nonkeystr() const {
486  assert (is_constructed());
487  assert (!is_neginf() && !is_posinf()); // these can't be serialized as non-key
488  return std::basic_string<unsigned char>(_data + 1, _strlen - 1);
489 }
490 
492  return _strlen - 1;
493 }
494 
495 inline void w_keystr_t::serialize_as_keystr(void* buffer) const {
496  if (_strlen == 0) {
497  return;
498  }
499  assert (buffer != nullptr);
500  assert (is_constructed());
501  ::memcpy(buffer, _data, _strlen);
502 }
503 
504 inline const void* w_keystr_t::buffer_as_keystr() const {
505  return _data;
506 }
507 
509  return _strlen;
510 }
511 
512 inline std::ostream& operator<<(std::ostream& o, const w_keystr_t& v) {
513  if (!v.is_constructed()) {
514  o << "<Not constructed>";
515  } else if (v.is_neginf()) {
516  o << "<Negative Infinity>";
517  } else if (v.is_posinf()) {
518  o << "<Positive Infinity>";
519  } else {
520  o << std::string(reinterpret_cast<const char*>(v._data),
521  v._strlen); // this will not show >127 correctly, but this is just a debug function
522  }
523  return o;
524 }
525 
526 inline bool w_keystr_t::operator==(const w_keystr_t& r) const {
527  return compare(r) == 0;
528 }
529 
530 inline bool w_keystr_t::operator!=(const w_keystr_t& r) const {
531  return compare(r) != 0;
532 }
533 
534 inline bool w_keystr_t::operator<(const w_keystr_t& r) const {
535  return compare(r) < 0;
536 }
537 
538 inline bool w_keystr_t::operator>(const w_keystr_t& r) const {
539  return compare(r) > 0;
540 }
541 
542 inline bool w_keystr_t::operator<=(const w_keystr_t& r) const {
543  return compare(r) <= 0;
544 }
545 
546 inline bool w_keystr_t::operator>=(const w_keystr_t& r) const {
547  return compare(r) >= 0;
548 }
549 
550 #endif // __W_KEY_H
w_keystr_len_t common_leading_bytes(const w_keystr_t &r) const
Definition: w_key.h:399
void _assure(w_keystr_len_t required_len)
Definition: w_key.h:238
bool construct_regularkey(const void *nonkeystr, w_keystr_len_t length)
Definition: w_key.h:281
bool construct_from_vec(const cvec_t &vect)
const unsigned char SIGN_POSINF
Definition: w_key.h:21
bool operator>=(const w_keystr_t &r) const
Definition: w_key.h:546
bool copy_from_vec(const cvec_t &vect)
int compare_nonkeystr(const void *nonkeystr, w_keystr_len_t length) const
Definition: w_key.h:435
bool construct_from_keystr_poormkey_16(const void *keystr_prefix, w_keystr_len_t prefix_length, w_keystr_len_t total_suffix_length, uint16_t poormkey, const void *keystr_suffix)
Definition: w_key.h:348
Key string class which can represent a few special values.
Definition: w_key.h:47
unsigned char * _data
Definition: w_key.h:226
void clear()
Definition: w_key.h:447
static int compare_bin_str(const void *str1, int len1, const void *str2, int len2)
Definition: w_key.h:386
A constant vec_t (meaning things pointed to cannot be changed).
Definition: vec_t.h:95
bool construct_from_keystr(const void *keystr, w_keystr_len_t length)
Definition: w_key.h:320
bool is_posinf() const
Definition: w_key.h:462
bool construct_posinfkey()
Definition: w_key.h:303
void serialize_as_keystr(void *buffer) const
Definition: w_key.h:495
const unsigned char SIGN_REGULAR
Definition: w_key.h:19
uint32_t _memlen
Definition: w_key.h:232
bool _valid_signbyte(const void *keystr)
Definition: w_key.h:314
bool is_constructed() const
Definition: w_key.h:382
void serialize16_be(void *dest, uint16_t value)
Definition: w_endian.h:41
int compare_keystr(const void *keystr, w_keystr_len_t length) const
Definition: w_key.h:428
w_keystr_len_t get_length_as_nonkeystr() const
Definition: w_key.h:491
~w_keystr_t()
Definition: w_key.h:378
int compare(const w_keystr_t &r) const
Definition: w_key.h:395
w_keystr_len_t get_length_as_keystr() const
Definition: w_key.h:508
uint32_t _strlen
Definition: w_key.h:229
w_keystr_t & operator=(const w_keystr_t &r)
Definition: w_key.h:269
const unsigned char SIGN_NEGINF
Definition: w_key.h:17
bool construct_neginfkey()
Definition: w_key.h:293
bool operator<(const w_keystr_t &r) const
Definition: w_key.h:534
bool operator==(const w_keystr_t &r) const
Definition: w_key.h:526
friend class w_keystr_t_test
Definition: w_key.h:48
bool operator!=(const w_keystr_t &r) const
Definition: w_key.h:530
const void * buffer_as_keystr() const
Definition: w_key.h:504
bool operator<=(const w_keystr_t &r) const
Definition: w_key.h:542
bool is_neginf() const
Definition: w_key.h:454
bool operator>(const w_keystr_t &r) const
Definition: w_key.h:538
uint32_t w_keystr_len_t
Definition: w_key.h:23
bool is_regular() const
Definition: w_key.h:470
friend std::ostream & operator<<(std::ostream &, const w_keystr_t &v)
Definition: w_key.h:512
w_keystr_t()
Definition: w_key.h:253
std::basic_string< unsigned char > serialize_as_nonkeystr() const
Definition: w_key.h:485