benchmark silo added
[c11concurrency-benchmarks.git] / silo / masstree / value_versioned_array.cc
1 /* Masstree
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
5  *
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
14  * is legally binding.
15  */
16 #include "kvrow.hh"
17 #include "value_versioned_array.hh"
18 #include <string.h>
19
20 value_versioned_array* value_versioned_array::make_sized_row(int ncol, kvtimestamp_t ts, threadinfo& ti) {
21     value_versioned_array* row = (value_versioned_array*) ti.allocate(shallow_size(ncol), memtag_value);
22     row->ts_ = ts;
23     row->ver_ = rowversion();
24     row->ncol_ = row->ncol_cap_ = ncol;
25     memset(row->cols_, 0, sizeof(row->cols_[0]) * ncol);
26     return row;
27 }
28
29 void value_versioned_array::snapshot(value_versioned_array*& storage,
30                                      const std::vector<index_type>& f, threadinfo& ti) const {
31     if (!storage || storage->ncol_cap_ < ncol_) {
32         if (storage)
33             storage->deallocate(ti);
34         storage = make_sized_row(ncol_, ts_, ti);
35     }
36     storage->ncol_ = ncol_;
37     rowversion v1 = ver_.stable();
38     while (1) {
39         if (f.size() == 1)
40             storage->cols_[f[0]] = cols_[f[0]];
41         else
42             memcpy(storage->cols_, cols_, sizeof(cols_[0]) * storage->ncol_);
43         rowversion v2 = ver_.stable();
44         if (!v1.has_changed(v2))
45             break;
46         v1 = v2;
47     }
48 }
49
50 value_versioned_array*
51 value_versioned_array::update(const Json* first, const Json* last,
52                               kvtimestamp_t ts, threadinfo& ti,
53                               bool always_copy) {
54     int ncol = last[-2].as_u() + 1;
55     value_versioned_array* row;
56     if (ncol > ncol_cap_ || always_copy) {
57         row = (value_versioned_array*) ti.allocate(shallow_size(ncol), memtag_value);
58         row->ts_ = ts;
59         row->ver_ = rowversion();
60         row->ncol_ = row->ncol_cap_ = ncol;
61         memcpy(row->cols_, cols_, sizeof(cols_[0]) * ncol_);
62     } else
63         row = this;
64     if (ncol > ncol_)
65         memset(row->cols_ + ncol_, 0, sizeof(cols_[0]) * (ncol - ncol_));
66
67     if (row == this) {
68         ver_.setdirty();
69         fence();
70     }
71     if (row->ncol_ < ncol)
72         row->ncol_ = ncol;
73
74     for (; first != last; first += 2) {
75         unsigned idx = first[0].as_u();
76         value_array::deallocate_column_rcu(row->cols_[idx], ti);
77         row->cols_[idx] = value_array::make_column(first[1].as_s(), ti);
78     }
79
80     if (row == this) {
81         fence();
82         ver_.clearandbump();
83     }
84     return row;
85 }
86
87 void value_versioned_array::deallocate(threadinfo &ti) {
88     for (short i = 0; i < ncol_; ++i)
89         value_array::deallocate_column(cols_[i], ti);
90     ti.deallocate(this, shallow_size(), memtag_value);
91 }
92
93 void value_versioned_array::deallocate_rcu(threadinfo &ti) {
94     for (short i = 0; i < ncol_; ++i)
95         value_array::deallocate_column_rcu(cols_[i], ti);
96     ti.deallocate_rcu(this, shallow_size(), memtag_value);
97 }