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 MASSTREE_PRINT_HH
17 #define MASSTREE_PRINT_HH
18 #include "masstree_struct.hh"
26 static void print(T value, FILE* f, const char* prefix,
27 int indent, Str key, kvtimestamp_t initial_timestamp,
29 value->print(f, prefix, indent, key, initial_timestamp, suffix);
34 class value_print<unsigned char*> {
36 static void print(unsigned char* value, FILE* f, const char* prefix,
37 int indent, Str key, kvtimestamp_t,
39 fprintf(f, "%s%*s%.*s = %p%s\n",
40 prefix, indent, "", key.len, key.s, value, suffix);
45 void node_base<P>::print(FILE *f, const char *prefix, int indent, int kdepth)
48 ((leaf<P> *) this)->print(f, prefix, indent, kdepth);
50 ((internode<P> *) this)->print(f, prefix, indent, kdepth);
54 void leaf<P>::print(FILE *f, const char *prefix, int indent, int kdepth)
57 prefix = prefix ? prefix : "";
58 typename node_base<P>::nodeversion_type v;
64 } while (this->has_changed(v));
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",
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);
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));
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());
91 for (int idx = 0; idx < perm.size(); ++idx) {
93 if (P::printable_keys)
94 l = this->get_key(p).unparse_printable(keybuf, sizeof(keybuf));
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, "");
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);
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);
115 fprintf(f, "%s%*s[DELETED]\n", prefix, indent + 2, "");
118 template <typename P>
119 void internode<P>::print(FILE *f, const char *prefix, int indent, int kdepth)
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(©, this, sizeof(copy));
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));
136 for (int p = 0; p < copy.size(); ++p) {
138 copy.child_[p]->print(f, prefix, indent + 4, kdepth);
140 fprintf(f, "%s%*s[]\n", prefix, indent + 4, "");
142 if (P::printable_keys)
143 l = copy.get_key(p).unparse_printable(keybuf, sizeof(keybuf));
145 l = copy.get_key(p).unparse(keybuf, sizeof(keybuf));
146 fprintf(f, "%s%*s%.*s\n", prefix, indent + 2, "", l, keybuf);
148 if (copy.child_[copy.size()])
149 copy.child_[copy.size()]->print(f, prefix, indent + 4, kdepth);
151 fprintf(f, "%s%*s[]\n", prefix, indent + 4, "");
154 template <typename P>
155 void basic_table<P>::print(FILE *f, int indent) const {
156 root_->print(f ? f : stdout, "", indent, 0);
159 } // namespace Masstree