2 * Eddie Kohler, Yandong Mao, Robert Morris
3 * Copyright (c) 2012-2014 President and Fellows of Harvard College
4 * Copyright (c) 2012-2014 Massachusetts Institute of Technology
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, subject to the conditions
9 * listed in the Masstree LICENSE file. These conditions include: you must
10 * preserve this copyright notice, and you cannot mention the copyright
11 * holders in advertising related to the Software without their permission.
12 * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
13 * notice is a summary of the Masstree LICENSE file; the license in that file
16 #ifndef VALUE_ARRAY_HH
17 #define VALUE_ARRAY_HH
18 #include "compiler.hh"
23 typedef short index_type;
24 static const char *name() { return "Array"; }
26 typedef lcdf::Json Json;
30 inline kvtimestamp_t timestamp() const;
31 inline int ncol() const;
32 inline Str col(int i) const;
34 void deallocate(threadinfo &ti);
35 void deallocate_rcu(threadinfo &ti);
37 value_array* update(const Json* first, const Json* last, kvtimestamp_t ts, threadinfo& ti) const;
38 static value_array* create(const Json* first, const Json* last, kvtimestamp_t ts, threadinfo& ti);
39 static inline value_array* create1(Str value, kvtimestamp_t ts, threadinfo& ti);
40 void deallocate_rcu_after_update(const Json* first, const Json* last, threadinfo& ti);
41 void deallocate_after_failed_update(const Json* first, const Json* last, threadinfo& ti);
43 template <typename PARSER>
44 static value_array* checkpoint_read(PARSER& par, kvtimestamp_t ts,
46 template <typename UNPARSER>
47 void checkpoint_write(UNPARSER& unpar) const;
49 void print(FILE* f, const char* prefix, int indent, Str key,
50 kvtimestamp_t initial_ts, const char* suffix = "") {
51 kvtimestamp_t adj_ts = timestamp_sub(ts_, initial_ts);
52 fprintf(f, "%s%*s%.*s = ### @" PRIKVTSPARTS "%s\n", prefix, indent, "",
53 key.len, key.s, KVTS_HIGHPART(adj_ts), KVTS_LOWPART(adj_ts), suffix);
56 static inline lcdf::inline_string* make_column(Str str, threadinfo& ti);
57 static void deallocate_column(lcdf::inline_string* col, threadinfo& ti);
58 static void deallocate_column_rcu(lcdf::inline_string* col, threadinfo& ti);
63 lcdf::inline_string* cols_[0];
65 static inline size_t shallow_size(int ncol);
66 inline size_t shallow_size() const;
67 static value_array* make_sized_row(int ncol, kvtimestamp_t ts, threadinfo& ti);
70 inline value_array::value_array()
74 inline kvtimestamp_t value_array::timestamp() const {
78 inline int value_array::ncol() const {
82 inline Str value_array::col(int i) const {
83 if (unsigned(i) < unsigned(ncol_) && cols_[i])
84 return Str(cols_[i]->s, cols_[i]->len);
89 inline size_t value_array::shallow_size(int ncol) {
90 return sizeof(value_array) + sizeof(lcdf::inline_string*) * ncol;
93 inline size_t value_array::shallow_size() const {
94 return shallow_size(ncol_);
97 inline lcdf::inline_string* value_array::make_column(Str str, threadinfo& ti) {
98 using lcdf::inline_string;
100 inline_string* col = (inline_string*) ti.allocate(inline_string::size(str.length()), memtag_value);
101 col->len = str.length();
102 memcpy(col->s, str.data(), str.length());
108 inline void value_array::deallocate_column(lcdf::inline_string* col,
111 ti.deallocate(col, col->size(), memtag_value);
114 inline void value_array::deallocate_column_rcu(lcdf::inline_string* col,
117 ti.deallocate_rcu(col, col->size(), memtag_value);
120 inline value_array* value_array::create(const Json* first, const Json* last,
121 kvtimestamp_t ts, threadinfo& ti) {
123 return empty.update(first, last, ts, ti);
126 inline value_array* value_array::create1(Str value, kvtimestamp_t ts, threadinfo& ti) {
127 value_array* row = (value_array*) ti.allocate(shallow_size(1), memtag_value);
130 row->cols_[0] = make_column(value, ti);
134 template <typename PARSER>
135 value_array* value_array::checkpoint_read(PARSER& par, kvtimestamp_t ts,
138 par.read_array_header(ncol);
139 value_array* row = make_sized_row(ncol, ts, ti);
141 for (unsigned i = 0; i != ncol; i++) {
144 row->cols_[i] = make_column(col, ti);
149 template <typename UNPARSER>
150 void value_array::checkpoint_write(UNPARSER& unpar) const {
151 unpar.write_array_header(ncol_);
152 for (short i = 0; i != ncol_; i++)