benchmark silo added
[c11concurrency-benchmarks.git] / silo / masstree / masstree_print.hh
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 #ifndef MASSTREE_PRINT_HH
17 #define MASSTREE_PRINT_HH
18 #include "masstree_struct.hh"
19 #include <stdio.h>
20
21 namespace Masstree {
22
23 template <typename T>
24 class value_print {
25   public:
26     static void print(T value, FILE* f, const char* prefix,
27                       int indent, Str key, kvtimestamp_t initial_timestamp,
28                       char* suffix) {
29         value->print(f, prefix, indent, key, initial_timestamp, suffix);
30     }
31 };
32
33 template <>
34 class value_print<unsigned char*> {
35   public:
36     static void print(unsigned char* value, FILE* f, const char* prefix,
37                       int indent, Str key, kvtimestamp_t,
38                       char* suffix) {
39         fprintf(f, "%s%*s%.*s = %p%s\n",
40                 prefix, indent, "", key.len, key.s, value, suffix);
41     }
42 };
43
44 template <typename P>
45 void node_base<P>::print(FILE *f, const char *prefix, int indent, int kdepth)
46 {
47     if (this->isleaf())
48         ((leaf<P> *) this)->print(f, prefix, indent, kdepth);
49     else
50         ((internode<P> *) this)->print(f, prefix, indent, kdepth);
51 }
52
53 template <typename P>
54 void leaf<P>::print(FILE *f, const char *prefix, int indent, int kdepth)
55 {
56     f = f ? f : stderr;
57     prefix = prefix ? prefix : "";
58     typename node_base<P>::nodeversion_type v;
59     permuter_type perm;
60     do {
61         v = *this;
62         fence();
63         perm = permutation_;
64     } while (this->has_changed(v));
65
66     static const char* modstates[] = {"", "-", "D"};
67     char keybuf[MASSTREE_MAXKEYLEN];
68     fprintf(f, "%s%*sleaf %p: %d %s, version %x%s, permutation %s, ",
69             prefix, indent, "", this,
70             perm.size(), perm.size() == 1 ? "key" : "keys",
71             v.version_value(),
72             modstate_ <= 2 ? modstates[modstate_] : "??",
73             perm.unparse().c_str());
74     fprintf(f, "parent %p, prev %p, next %p ", parent_, prev_, next_.ptr);
75     if (ksuf_ && extrasize64_ < -1)
76         fprintf(f, "[ksuf i%dx%d] ", -extrasize64_ - 1, (int) ksuf_->capacity() / 64);
77     else if (ksuf_)
78         fprintf(f, "[ksuf x%d] ", (int) ksuf_->capacity() / 64);
79     else if (extrasize64_)
80         fprintf(f, "[ksuf i%d] ", extrasize64_);
81     if (P::debug_level > 0) {
82         kvtimestamp_t cts = timestamp_sub(created_at_[0], initial_timestamp);
83         fprintf(f, "@" PRIKVTSPARTS, KVTS_HIGHPART(cts), KVTS_LOWPART(cts));
84     }
85     fputc('\n', f);
86
87     if (v.deleted() || (perm[0] != 0 && prev_))
88         fprintf(f, "%s%*s%s = [] #0\n", prefix, indent + 2, "", key_type(ikey_bound()).unparse().c_str());
89
90     char xbuf[15];
91     for (int idx = 0; idx < perm.size(); ++idx) {
92         int p = perm[idx], l;
93         if (P::printable_keys)
94             l = this->get_key(p).unparse_printable(keybuf, sizeof(keybuf));
95         else
96             l = this->get_key(p).unparse(keybuf, sizeof(keybuf));
97         sprintf(xbuf, " #%x/%d", p, keylenx_[p]);
98         leafvalue_type lv = lv_[p];
99         if (this->has_changed(v)) {
100             fprintf(f, "%s%*s[NODE CHANGED]\n", prefix, indent + 2, "");
101             break;
102         } else if (!lv)
103             fprintf(f, "%s%*s%.*s = []%s\n", prefix, indent + 2, "", l, keybuf, xbuf);
104         else if (is_layer(p)) {
105             fprintf(f, "%s%*s%.*s = SUBTREE%s\n", prefix, indent + 2, "", l, keybuf, xbuf);
106             node_base<P> *n = lv.layer()->unsplit_ancestor();
107             n->print(f, prefix, indent + 4, kdepth + key_type::ikey_size);
108         } else {
109             typename P::value_type tvx = lv.value();
110             P::value_print_type::print(tvx, f, prefix, indent + 2, Str(keybuf, l), initial_timestamp, xbuf);
111         }
112     }
113
114     if (v.deleted())
115         fprintf(f, "%s%*s[DELETED]\n", prefix, indent + 2, "");
116 }
117
118 template <typename P>
119 void internode<P>::print(FILE *f, const char *prefix, int indent, int kdepth)
120 {
121     f = f ? f : stderr;
122     prefix = prefix ? prefix : "";
123     internode<P> copy(*this);
124     for (int i = 0; i < 100 && (copy.has_changed(*this) || this->inserting() || this->splitting()); ++i)
125         memcpy(&copy, this, sizeof(copy));
126
127     char keybuf[MASSTREE_MAXKEYLEN];
128     fprintf(f, "%s%*sinternode %p%s: %d keys, version %x, parent %p",
129             prefix, indent, "", this, this->deleted() ? " [DELETED]" : "",
130             copy.size(), copy.version_value(), copy.parent_);
131     if (P::debug_level > 0) {
132         kvtimestamp_t cts = timestamp_sub(created_at_[0], initial_timestamp);
133         fprintf(f, " @" PRIKVTSPARTS, KVTS_HIGHPART(cts), KVTS_LOWPART(cts));
134     }
135     fputc('\n', f);
136     for (int p = 0; p < copy.size(); ++p) {
137         if (copy.child_[p])
138             copy.child_[p]->print(f, prefix, indent + 4, kdepth);
139         else
140             fprintf(f, "%s%*s[]\n", prefix, indent + 4, "");
141         int l;
142         if (P::printable_keys)
143             l = copy.get_key(p).unparse_printable(keybuf, sizeof(keybuf));
144         else
145             l = copy.get_key(p).unparse(keybuf, sizeof(keybuf));
146         fprintf(f, "%s%*s%.*s\n", prefix, indent + 2, "", l, keybuf);
147     }
148     if (copy.child_[copy.size()])
149         copy.child_[copy.size()]->print(f, prefix, indent + 4, kdepth);
150     else
151         fprintf(f, "%s%*s[]\n", prefix, indent + 4, "");
152 }
153
154 template <typename P>
155 void basic_table<P>::print(FILE *f, int indent) const {
156     root_->print(f ? f : stdout, "", indent, 0);
157 }
158
159 } // namespace Masstree
160 #endif