benchmark silo added
authorahmad <ahmad@dw-10.eecs.uci.edu>
Thu, 7 Feb 2019 23:22:50 +0000 (15:22 -0800)
committerahmad <ahmad@dw-10.eecs.uci.edu>
Thu, 7 Feb 2019 23:22:50 +0000 (15:22 -0800)
291 files changed:
README.md
silo/AUTHORS [new file with mode: 0644]
silo/BUILD [new file with mode: 0644]
silo/LICENSE [new file with mode: 0644]
silo/Makefile [new file with mode: 0644]
silo/README.md [new file with mode: 0644]
silo/allocator.cc [new file with mode: 0644]
silo/allocator.h [new file with mode: 0644]
silo/amd64.h [new file with mode: 0644]
silo/base_txn_btree.h [new file with mode: 0644]
silo/benchmarks/abstract_db.h [new file with mode: 0644]
silo/benchmarks/abstract_ordered_index.h [new file with mode: 0644]
silo/benchmarks/bdb_wrapper.cc [new file with mode: 0644]
silo/benchmarks/bdb_wrapper.h [new file with mode: 0644]
silo/benchmarks/bench.cc [new file with mode: 0644]
silo/benchmarks/bench.h [new file with mode: 0644]
silo/benchmarks/bid.cc [new file with mode: 0644]
silo/benchmarks/dbtest.cc [new file with mode: 0644]
silo/benchmarks/encstress.cc [new file with mode: 0644]
silo/benchmarks/gc_runner.sh [new file with mode: 0755]
silo/benchmarks/kvdb_wrapper.h [new file with mode: 0644]
silo/benchmarks/kvdb_wrapper_impl.h [new file with mode: 0644]
silo/benchmarks/masstree/README [new file with mode: 0644]
silo/benchmarks/masstree/kvrandom.cc [new file with mode: 0644]
silo/benchmarks/masstree/kvrandom.hh [new file with mode: 0644]
silo/benchmarks/masstree/kvtest.cc [new file with mode: 0644]
silo/benchmarks/mysql_wrapper.cc [new file with mode: 0644]
silo/benchmarks/mysql_wrapper.h [new file with mode: 0644]
silo/benchmarks/ndb_wrapper.h [new file with mode: 0644]
silo/benchmarks/ndb_wrapper_impl.h [new file with mode: 0644]
silo/benchmarks/plotter.py [new file with mode: 0644]
silo/benchmarks/queue.cc [new file with mode: 0644]
silo/benchmarks/results/NOTES.txt [new file with mode: 0644]
silo/benchmarks/results/ben-3-8-13.py [new file with mode: 0644]
silo/benchmarks/results/ben-4-10-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-3-13-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-3-14-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-3-16-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-3-18-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-3-21-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-3-22-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-3-23-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-3-26-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-4-10-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-5-18-13-tpcc-chains.txt [new file with mode: 0644]
silo/benchmarks/results/istc11-5-18-13-ycsb-chains.txt [new file with mode: 0644]
silo/benchmarks/results/istc11-5-18-13.py [new file with mode: 0644]
silo/benchmarks/results/istc11-8-28-13_cameraready.py [new file with mode: 0644]
silo/benchmarks/results/istc12-8-30-13_cameraready.py [new file with mode: 0644]
silo/benchmarks/results/istc3-10-23-13.py [new file with mode: 0644]
silo/benchmarks/results/istc3-7-27-13.py [new file with mode: 0644]
silo/benchmarks/results/istc3-7-31-13.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-1-13.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-1-13_compress.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-1-13_fake_compress.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-1-13_fake_writes.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-1-13_fake_writes_stride.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-1-13_fake_writes_stride1.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-1-13_log_reduce_size.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-1-13_log_reduce_size_1.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-1-13_log_reduce_size_nofsync.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-1-13_newbench.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-12-13.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-16-13_multipart_skew.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-19-13_cameraready.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-21-13_cameraready-1.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-21-13_cameraready.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-22-13_cameraready.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-22-13_cameraready_2.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-23-13_cameraready.py [new file with mode: 0644]
silo/benchmarks/results/istc3-8-24-13_cameraready.py [new file with mode: 0644]
silo/benchmarks/results/istc3-9-6-13.py [new file with mode: 0644]
silo/benchmarks/results/istc3-9-8-13.py [new file with mode: 0644]
silo/benchmarks/results/make_graphs-2.py [new file with mode: 0755]
silo/benchmarks/results/make_graphs-3.py [new file with mode: 0755]
silo/benchmarks/results/make_graphs-4.py [new file with mode: 0644]
silo/benchmarks/results/make_graphs-5.py [new file with mode: 0644]
silo/benchmarks/results/make_graphs-6.py [new file with mode: 0644]
silo/benchmarks/results/make_graphs.py [new file with mode: 0755]
silo/benchmarks/results/tom-1-22-13.py [new file with mode: 0644]
silo/benchmarks/results/tom-2-13-13.py [new file with mode: 0644]
silo/benchmarks/results/tom-2-6-13.py [new file with mode: 0644]
silo/benchmarks/runner.py [new file with mode: 0644]
silo/benchmarks/stats_runner.py [new file with mode: 0644]
silo/benchmarks/tpcc.cc [new file with mode: 0644]
silo/benchmarks/tpcc.h [new file with mode: 0644]
silo/benchmarks/ycsb.cc [new file with mode: 0644]
silo/btree.cc [new file with mode: 0644]
silo/btree.h [new file with mode: 0644]
silo/btree_choice.h [new file with mode: 0644]
silo/btree_impl.h [new file with mode: 0644]
silo/circbuf.h [new file with mode: 0644]
silo/compile.sh [new file with mode: 0755]
silo/config/config-backoff.h [new file with mode: 0644]
silo/config/config-factor-fake-compression.h [new file with mode: 0644]
silo/config/config-factor-gc-nowriteinplace.h [new file with mode: 0644]
silo/config/config-factor-gc.h [new file with mode: 0644]
silo/config/config-perf.h [new file with mode: 0644]
silo/config/config-sandbox.h [new file with mode: 0644]
silo/core.cc [new file with mode: 0644]
silo/core.h [new file with mode: 0644]
silo/counter.cc [new file with mode: 0644]
silo/counter.h [new file with mode: 0644]
silo/fileutils.h [new file with mode: 0644]
silo/imstring.h [new file with mode: 0644]
silo/lockguard.h [new file with mode: 0644]
silo/log2.hh [new file with mode: 0644]
silo/macros.h [new file with mode: 0644]
silo/marked_ptr.h [new file with mode: 0644]
silo/masstree/AUTHORS [new file with mode: 0644]
silo/masstree/GNUmakefile [new file with mode: 0644]
silo/masstree/GNUmakefile.in [new file with mode: 0644]
silo/masstree/LICENSE [new file with mode: 0644]
silo/masstree/README.md [new file with mode: 0644]
silo/masstree/_masstree_config.d [new file with mode: 0644]
silo/masstree/autom4te.cache/output.0 [new file with mode: 0644]
silo/masstree/autom4te.cache/output.1 [new file with mode: 0644]
silo/masstree/autom4te.cache/requests [new file with mode: 0644]
silo/masstree/autom4te.cache/traces.0 [new file with mode: 0644]
silo/masstree/autom4te.cache/traces.1 [new file with mode: 0644]
silo/masstree/btree_leaflink.hh [new file with mode: 0644]
silo/masstree/checkpoint.cc [new file with mode: 0644]
silo/masstree/checkpoint.hh [new file with mode: 0644]
silo/masstree/circular_int.hh [new file with mode: 0644]
silo/masstree/clp.c [new file with mode: 0644]
silo/masstree/clp.h [new file with mode: 0644]
silo/masstree/compiler.cc [new file with mode: 0644]
silo/masstree/compiler.hh [new file with mode: 0644]
silo/masstree/config.h [new file with mode: 0644]
silo/masstree/config.h.in [new file with mode: 0644]
silo/masstree/config.log [new file with mode: 0644]
silo/masstree/config.status [new file with mode: 0755]
silo/masstree/configure [new file with mode: 0755]
silo/masstree/configure.ac [new file with mode: 0644]
silo/masstree/doc/.gitignore [new file with mode: 0644]
silo/masstree/doc/GNUmakefile [new file with mode: 0644]
silo/masstree/doc/elements.mp [new file with mode: 0644]
silo/masstree/doc/elemfig.sty [new file with mode: 0644]
silo/masstree/doc/examples.mp [new file with mode: 0644]
silo/masstree/doc/insert1.mp [new file with mode: 0644]
silo/masstree/doc/masstree.mp [new file with mode: 0644]
silo/masstree/doc/patches.mp [new file with mode: 0644]
silo/masstree/doc/remove1.mp [new file with mode: 0644]
silo/masstree/doc/remove2.mp [new file with mode: 0644]
silo/masstree/doc/spec.tex [new file with mode: 0644]
silo/masstree/file.cc [new file with mode: 0644]
silo/masstree/file.hh [new file with mode: 0644]
silo/masstree/hashcode.hh [new file with mode: 0644]
silo/masstree/json.cc [new file with mode: 0644]
silo/masstree/json.hh [new file with mode: 0644]
silo/masstree/jsontest.cc [new file with mode: 0644]
silo/masstree/kpermuter.hh [new file with mode: 0644]
silo/masstree/ksearch.hh [new file with mode: 0644]
silo/masstree/kvio.cc [new file with mode: 0644]
silo/masstree/kvio.hh [new file with mode: 0644]
silo/masstree/kvproto.hh [new file with mode: 0644]
silo/masstree/kvrandom.cc [new file with mode: 0644]
silo/masstree/kvrandom.hh [new file with mode: 0644]
silo/masstree/kvrow.hh [new file with mode: 0644]
silo/masstree/kvstats.hh [new file with mode: 0644]
silo/masstree/kvtest.hh [new file with mode: 0644]
silo/masstree/kvthread.cc [new file with mode: 0644]
silo/masstree/kvthread.hh [new file with mode: 0644]
silo/masstree/local_vector.hh [new file with mode: 0644]
silo/masstree/log.cc [new file with mode: 0644]
silo/masstree/log.hh [new file with mode: 0644]
silo/masstree/masstree.hh [new file with mode: 0644]
silo/masstree/masstree_get.hh [new file with mode: 0644]
silo/masstree/masstree_insert.hh [new file with mode: 0644]
silo/masstree/masstree_key.hh [new file with mode: 0644]
silo/masstree/masstree_print.hh [new file with mode: 0644]
silo/masstree/masstree_remove.hh [new file with mode: 0644]
silo/masstree/masstree_scan.hh [new file with mode: 0644]
silo/masstree/masstree_split.hh [new file with mode: 0644]
silo/masstree/masstree_struct.hh [new file with mode: 0644]
silo/masstree/masstree_tcursor.hh [new file with mode: 0644]
silo/masstree/misc.cc [new file with mode: 0644]
silo/masstree/misc.hh [new file with mode: 0644]
silo/masstree/msgpack.cc [new file with mode: 0644]
silo/masstree/msgpack.hh [new file with mode: 0644]
silo/masstree/msgpacktest.cc [new file with mode: 0644]
silo/masstree/mtclient.cc [new file with mode: 0644]
silo/masstree/mtclient.hh [new file with mode: 0644]
silo/masstree/mtcounters.hh [new file with mode: 0644]
silo/masstree/mtd.cc [new file with mode: 0644]
silo/masstree/mttest.cc [new file with mode: 0644]
silo/masstree/nodeversion.hh [new file with mode: 0644]
silo/masstree/perfstat.cc [new file with mode: 0644]
silo/masstree/perfstat.hh [new file with mode: 0644]
silo/masstree/query_masstree.cc [new file with mode: 0644]
silo/masstree/query_masstree.hh [new file with mode: 0644]
silo/masstree/str.cc [new file with mode: 0644]
silo/masstree/str.hh [new file with mode: 0644]
silo/masstree/straccum.cc [new file with mode: 0644]
silo/masstree/straccum.hh [new file with mode: 0644]
silo/masstree/string.cc [new file with mode: 0644]
silo/masstree/string.hh [new file with mode: 0644]
silo/masstree/string_base.hh [new file with mode: 0644]
silo/masstree/string_slice.cc [new file with mode: 0644]
silo/masstree/string_slice.hh [new file with mode: 0644]
silo/masstree/stringbag.hh [new file with mode: 0644]
silo/masstree/test_atomics.cc [new file with mode: 0644]
silo/masstree/test_string.cc [new file with mode: 0644]
silo/masstree/testrunner.cc [new file with mode: 0644]
silo/masstree/testrunner.hh [new file with mode: 0644]
silo/masstree/timestamp.hh [new file with mode: 0644]
silo/masstree/value_array.cc [new file with mode: 0644]
silo/masstree/value_array.hh [new file with mode: 0644]
silo/masstree/value_bag.hh [new file with mode: 0644]
silo/masstree/value_string.cc [new file with mode: 0644]
silo/masstree/value_string.hh [new file with mode: 0644]
silo/masstree/value_versioned_array.cc [new file with mode: 0644]
silo/masstree/value_versioned_array.hh [new file with mode: 0644]
silo/masstree_btree.h [new file with mode: 0644]
silo/memory.cc [new file with mode: 0644]
silo/ndb_type_traits.h [new file with mode: 0644]
silo/new-benchmarks/abstract_db.h [new file with mode: 0644]
silo/new-benchmarks/abstract_ordered_index.h [new file with mode: 0644]
silo/new-benchmarks/bench.cc [new file with mode: 0644]
silo/new-benchmarks/bench.h [new file with mode: 0644]
silo/new-benchmarks/dbtest.cc [new file with mode: 0644]
silo/new-benchmarks/kvdb_database.h [new file with mode: 0644]
silo/new-benchmarks/ndb_database.h [new file with mode: 0644]
silo/new-benchmarks/tpcc.cc [new file with mode: 0644]
silo/new-benchmarks/tpcc.h [new file with mode: 0644]
silo/ownership_checker.h [new file with mode: 0644]
silo/persist_test.cc [new file with mode: 0644]
silo/prefetch.h [new file with mode: 0644]
silo/pxqueue.h [new file with mode: 0644]
silo/rcu.cc [new file with mode: 0644]
silo/rcu.h [new file with mode: 0644]
silo/record/cursor.h [new file with mode: 0644]
silo/record/encoder.h [new file with mode: 0644]
silo/record/inline_str.h [new file with mode: 0644]
silo/record/serializer.h [new file with mode: 0644]
silo/run.sh [new file with mode: 0755]
silo/scopedperf.hh [new file with mode: 0644]
silo/scripts/tester.py [new file with mode: 0755]
silo/scripts/tester.sh [new file with mode: 0755]
silo/small_unordered_map.h [new file with mode: 0644]
silo/small_vector.h [new file with mode: 0644]
silo/spinbarrier.h [new file with mode: 0644]
silo/spinlock.h [new file with mode: 0644]
silo/static_unordered_map.h [new file with mode: 0644]
silo/static_vector.h [new file with mode: 0644]
silo/stats_client.cc [new file with mode: 0644]
silo/stats_common.h [new file with mode: 0644]
silo/stats_server.cc [new file with mode: 0644]
silo/stats_server.h [new file with mode: 0644]
silo/str_arena.h [new file with mode: 0644]
silo/test.cc [new file with mode: 0644]
silo/third-party/lz4/LZ4 Streaming Format.odt [new file with mode: 0644]
silo/third-party/lz4/Makefile [new file with mode: 0644]
silo/third-party/lz4/bench.c [new file with mode: 0644]
silo/third-party/lz4/bench.h [new file with mode: 0644]
silo/third-party/lz4/cmake/CMakeLists.txt [new file with mode: 0644]
silo/third-party/lz4/cmake/pack/CMakeLists.txt [new file with mode: 0644]
silo/third-party/lz4/cmake/pack/release_COPYING.txt [new file with mode: 0644]
silo/third-party/lz4/fullbench.c [new file with mode: 0644]
silo/third-party/lz4/fuzzer.c [new file with mode: 0644]
silo/third-party/lz4/liblz4.so [new file with mode: 0755]
silo/third-party/lz4/lz4.c [new file with mode: 0644]
silo/third-party/lz4/lz4.h [new file with mode: 0644]
silo/third-party/lz4/lz4.o [new file with mode: 0644]
silo/third-party/lz4/lz4_encoder.h [new file with mode: 0644]
silo/third-party/lz4/lz4_format_description.txt [new file with mode: 0644]
silo/third-party/lz4/lz4c.c [new file with mode: 0644]
silo/third-party/lz4/lz4hc.c [new file with mode: 0644]
silo/third-party/lz4/lz4hc.h [new file with mode: 0644]
silo/third-party/lz4/lz4hc_encoder.h [new file with mode: 0644]
silo/third-party/lz4/xxhash.c [new file with mode: 0644]
silo/third-party/lz4/xxhash.h [new file with mode: 0644]
silo/third-party/lz4/xxhash.o [new file with mode: 0644]
silo/thread.cc [new file with mode: 0644]
silo/thread.h [new file with mode: 0644]
silo/ticker.cc [new file with mode: 0644]
silo/ticker.h [new file with mode: 0644]
silo/tuple.cc [new file with mode: 0644]
silo/tuple.h [new file with mode: 0644]
silo/txn.cc [new file with mode: 0644]
silo/txn.h [new file with mode: 0644]
silo/txn_btree.cc [new file with mode: 0644]
silo/txn_btree.h [new file with mode: 0644]
silo/txn_impl.h [new file with mode: 0644]
silo/txn_proto2_impl.cc [new file with mode: 0644]
silo/txn_proto2_impl.h [new file with mode: 0644]
silo/typed_txn_btree.h [new file with mode: 0644]
silo/util.h [new file with mode: 0644]
silo/varint.cc [new file with mode: 0644]
silo/varint.h [new file with mode: 0644]
silo/varkey.h [new file with mode: 0644]

index f06a376..15958b3 100644 (file)
--- a/README.md
+++ b/README.md
@@ -12,3 +12,9 @@ Corresponding command for Ubuntu is included for convenience.
 
 4. g++ Compiler that supports C++11
 -- sudo apt-get install g++
+
+5. packages for Silo
+
+sudo apt-get install libdb++-dev
+sudo apt-get install libaio-dev
+sudo apt-get install libjemalloc-dev
diff --git a/silo/AUTHORS b/silo/AUTHORS
new file mode 100644 (file)
index 0000000..e04ebfa
--- /dev/null
@@ -0,0 +1,8 @@
+Stephen Tu
+stephentu@csail.mit.edu
+
+Wenting Zheng
+wzheng@mit.edu
+
+Eddie Kohler
+kohler@seas.harvard.edu
diff --git a/silo/BUILD b/silo/BUILD
new file mode 100644 (file)
index 0000000..719a9d0
--- /dev/null
@@ -0,0 +1,18 @@
+Baseline:
+
+$ sudo apt-get install libnuma-dev
+
+To use with jemalloc:
+
+$ sudo apt-get install libjemalloc-dev
+
+Note that jemalloc2 has a bug which shows up in tests- make sure
+to use jemalloc3
+
+To use with tcmalloc:
+
+$ sudo apt-get install libgoogle-perftools-dev
+
+For benchmarks:
+
+$ sudo apt-get install libdb5.3++-dev libmysqld-dev libaio-dev
diff --git a/silo/LICENSE b/silo/LICENSE
new file mode 100644 (file)
index 0000000..dc1d496
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (C) 2013 Stephen Tu and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/silo/Makefile b/silo/Makefile
new file mode 100644 (file)
index 0000000..682b4cb
--- /dev/null
@@ -0,0 +1,279 @@
+-include config.mk
+
+### Options ###
+
+DEBUG ?= 0
+CHECK_INVARIANTS ?= 0
+
+# 0 = libc malloc
+# 1 = jemalloc
+# 2 = tcmalloc
+# 3 = flow
+USE_MALLOC_MODE ?= 1
+
+MYSQL ?= 1
+MYSQL_SHARE_DIR ?= /x/stephentu/mysql-5.5.29/build/sql/share
+
+# Available modes
+#   * perf
+#   * backoff
+#   * factor-gc
+#   * factor-gc-nowriteinplace
+#   * factor-fake-compression
+#   * sandbox
+MODE ?= perf
+
+# run with 'MASSTREE=0' to turn off masstree
+MASSTREE ?= 1
+
+###############
+
+DEBUG_S=$(strip $(DEBUG))
+CHECK_INVARIANTS_S=$(strip $(CHECK_INVARIANTS))
+EVENT_COUNTERS_S=$(strip $(EVENT_COUNTERS))
+USE_MALLOC_MODE_S=$(strip $(USE_MALLOC_MODE))
+MODE_S=$(strip $(MODE))
+MASSTREE_S=$(strip $(MASSTREE))
+MASSTREE_CONFIG:=--enable-max-key-len=1024
+
+ifeq ($(DEBUG_S),1)
+       OSUFFIX_D=.debug
+       MASSTREE_CONFIG+=--enable-assertions
+else
+       MASSTREE_CONFIG+=--disable-assertions
+endif
+ifeq ($(CHECK_INVARIANTS_S),1)
+       OSUFFIX_S=.check
+       MASSTREE_CONFIG+=--enable-invariants --enable-preconditions
+else
+       MASSTREE_CONFIG+=--disable-invariants --disable-preconditions
+endif
+ifeq ($(EVENT_COUNTERS_S),1)
+       OSUFFIX_E=.ectrs
+endif
+OSUFFIX=$(OSUFFIX_D)$(OSUFFIX_S)$(OSUFFIX_E)
+
+ifeq ($(MODE_S),perf)
+       O := out-perf$(OSUFFIX)
+       CONFIG_H = config/config-perf.h
+else ifeq ($(MODE_S),backoff)
+       O := out-backoff$(OSUFFIX)
+       CONFIG_H = config/config-backoff.h
+else ifeq ($(MODE_S),factor-gc)
+       O := out-factor-gc$(OSUFFIX)
+       CONFIG_H = config/config-factor-gc.h
+else ifeq ($(MODE_S),factor-gc-nowriteinplace)
+       O := out-factor-gc-nowriteinplace$(OSUFFIX)
+       CONFIG_H = config/config-factor-gc-nowriteinplace.h
+else ifeq ($(MODE_S),factor-fake-compression)
+       O := out-factor-fake-compression$(OSUFFIX)
+       CONFIG_H = config/config-factor-fake-compression.h
+else ifeq ($(MODE_S),sandbox)
+       O := out-sandbox$(OSUFFIX)
+       CONFIG_H = config/config-sandbox.h
+else
+       $(error invalid mode)
+endif
+
+CXXFLAGS := -g -Wall -std=c++0x
+CXXFLAGS += -MD -Ithird-party/lz4 -DCONFIG_H=\"$(CONFIG_H)\"
+ifeq ($(DEBUG_S),1)
+        CXXFLAGS += -fno-omit-frame-pointer -DDEBUG
+else
+        CXXFLAGS += -Werror -O2 -funroll-loops -fno-omit-frame-pointer
+endif
+ifeq ($(CHECK_INVARIANTS_S),1)
+       CXXFLAGS += -DCHECK_INVARIANTS
+endif
+ifeq ($(EVENT_COUNTERS_S),1)
+       CXXFLAGS += -DENABLE_EVENT_COUNTERS
+endif
+ifeq ($(MASSTREE_S),1)
+       CXXFLAGS += -DNDB_MASSTREE -include masstree/config.h
+       OBJDEP += masstree/config.h
+       O := $(O).masstree
+else
+       O := $(O).silotree
+endif
+
+TOP     := $(shell echo $${PWD-`pwd`})
+LDFLAGS := -lpthread -lnuma -lrt
+
+LZ4LDFLAGS := -Lthird-party/lz4 -llz4 -Wl,-rpath,$(TOP)/third-party/lz4
+
+ifeq ($(USE_MALLOC_MODE_S),1)
+        CXXFLAGS+=-DUSE_JEMALLOC
+        LDFLAGS+=-ljemalloc
+       MASSTREE_CONFIG+=--with-malloc=jemalloc
+else ifeq ($(USE_MALLOC_MODE_S),2)
+        CXXFLAGS+=-DUSE_TCMALLOC
+        LDFLAGS+=-ltcmalloc
+       MASSTREE_CONFIG+=--with-malloc=tcmalloc
+else ifeq ($(USE_MALLOC_MODE_S),3)
+        CXXFLAGS+=-DUSE_FLOW
+        LDFLAGS+=-lflow
+       MASSTREE_CONFIG+=--with-malloc=flow
+else
+       MASSTREE_CONFIG+=--with-malloc=malloc
+endif
+
+ifneq ($(strip $(CUSTOM_LDPATH)), )
+        LDFLAGS+=$(CUSTOM_LDPATH)
+endif
+
+SRCFILES = allocator.cc \
+       btree.cc \
+       core.cc \
+       counter.cc \
+       memory.cc \
+       rcu.cc \
+       stats_server.cc \
+       thread.cc \
+       ticker.cc \
+       tuple.cc \
+       txn_btree.cc \
+       txn.cc \
+       txn_proto2_impl.cc \
+       varint.cc
+
+ifeq ($(MASSTREE_S),1)
+MASSTREE_SRCFILES = masstree/compiler.cc \
+       masstree/str.cc \
+       masstree/string.cc \
+       masstree/straccum.cc \
+       masstree/json.cc
+endif
+
+OBJFILES := $(patsubst %.cc, $(O)/%.o, $(SRCFILES))
+
+MASSTREE_OBJFILES := $(patsubst masstree/%.cc, $(O)/%.o, $(MASSTREE_SRCFILES))
+
+BENCH_CXXFLAGS := $(CXXFLAGS)
+BENCH_LDFLAGS := $(LDFLAGS) -ldb_cxx -lz -lrt -lcrypt -laio -ldl -lssl -lcrypto
+
+BENCH_SRCFILES = benchmarks/bdb_wrapper.cc \
+       benchmarks/bench.cc \
+       benchmarks/encstress.cc \
+       benchmarks/bid.cc \
+       benchmarks/masstree/kvrandom.cc \
+       benchmarks/queue.cc \
+       benchmarks/tpcc.cc \
+       benchmarks/ycsb.cc
+
+ifeq ($(MYSQL_S),1)
+BENCH_CXXFLAGS += -DMYSQL_SHARE_DIR=\"$(MYSQL_SHARE_DIR)\"
+BENCH_LDFLAGS := -L/usr/lib/mysql -lmysqld $(BENCH_LDFLAGS)
+BENCH_SRCFILES += benchmarks/mysql_wrapper.cc
+else
+BENCH_CXXFLAGS += -DNO_MYSQL
+endif
+
+BENCH_OBJFILES := $(patsubst %.cc, $(O)/%.o, $(BENCH_SRCFILES))
+
+NEWBENCH_SRCFILES = new-benchmarks/bench.cc \
+       new-benchmarks/tpcc.cc
+
+NEWBENCH_OBJFILES := $(patsubst %.cc, $(O)/%.o, $(NEWBENCH_SRCFILES))
+
+all: $(O)/test
+
+$(O)/benchmarks/%.o: benchmarks/%.cc $(O)/buildstamp $(O)/buildstamp.bench $(OBJDEP)
+       @mkdir -p $(@D)
+       $(CXX) $(BENCH_CXXFLAGS) -c $< -o $@
+
+$(O)/benchmarks/masstree/%.o: benchmarks/masstree/%.cc $(O)/buildstamp $(O)/buildstamp.bench $(OBJDEP)
+       @mkdir -p $(@D)
+       $(CXX) $(BENCH_CXXFLAGS) -c $< -o $@
+
+$(O)/new-benchmarks/%.o: new-benchmarks/%.cc $(O)/buildstamp $(O)/buildstamp.bench $(OBJDEP)
+       @mkdir -p $(@D)
+       $(CXX) $(CXXFLAGS) -c $< -o $@
+
+$(O)/%.o: %.cc $(O)/buildstamp $(OBJDEP)
+       @mkdir -p $(@D)
+       $(CXX) $(CXXFLAGS) -c $< -o $@
+
+$(MASSTREE_OBJFILES) : $(O)/%.o: masstree/%.cc masstree/config.h
+       @mkdir -p $(@D)
+       $(CXX) $(CXXFLAGS) -include masstree/config.h -c $< -o $@
+
+third-party/lz4/liblz4.so:
+       make -C third-party/lz4 library
+
+.PHONY: test
+test: $(O)/test
+
+$(O)/test: $(O)/test.o $(OBJFILES) $(MASSTREE_OBJFILES) third-party/lz4/liblz4.so
+       $(CXX) -o $(O)/test $^ $(LDFLAGS) $(LZ4LDFLAGS)
+
+.PHONY: persist_test
+persist_test: $(O)/persist_test
+
+$(O)/persist_test: $(O)/persist_test.o third-party/lz4/liblz4.so
+       $(CXX) -o $(O)/persist_test $(O)/persist_test.o $(LDFLAGS) $(LZ4LDFLAGS)
+
+.PHONY: stats_client
+stats_client: $(O)/stats_client
+
+$(O)/stats_client: $(O)/stats_client.o
+       $(CXX) -o $(O)/stats_client $(O)/stats_client.o $(LDFLAGS)
+
+masstree/config.h: $(O)/buildstamp.masstree masstree/configure masstree/config.h.in
+       rm -f $@
+       cd masstree; ./configure $(MASSTREE_CONFIG)
+       if test -f $@; then touch $@; fi
+
+masstree/configure masstree/config.h.in: masstree/configure.ac
+       cd masstree && autoreconf -i && touch configure config.h.in
+
+.PHONY: dbtest
+dbtest: $(O)/benchmarks/dbtest
+
+$(O)/benchmarks/dbtest: $(O)/benchmarks/dbtest.o $(OBJFILES) $(MASSTREE_OBJFILES) $(BENCH_OBJFILES) third-party/lz4/liblz4.so
+       $(CXX) -o $(O)/benchmarks/dbtest $^ $(BENCH_LDFLAGS) $(LZ4LDFLAGS)
+
+.PHONY: kvtest
+kvtest: $(O)/benchmarks/masstree/kvtest
+
+$(O)/benchmarks/masstree/kvtest: $(O)/benchmarks/masstree/kvtest.o $(OBJFILES) $(BENCH_OBJFILES)
+       $(CXX) -o $(O)/benchmarks/masstree/kvtest $^ $(BENCH_LDFLAGS)
+
+.PHONY: newdbtest
+newdbtest: $(O)/new-benchmarks/dbtest
+
+$(O)/new-benchmarks/dbtest: $(O)/new-benchmarks/dbtest.o $(OBJFILES) $(MASSTREE_OBJFILES) $(NEWBENCH_OBJFILES) third-party/lz4/liblz4.so
+       $(CXX) -o $(O)/new-benchmarks/dbtest $^ $(LDFLAGS) $(LZ4LDFLAGS)
+
+DEPFILES := $(wildcard $(O)/*.d $(O)/*/*.d $(O)/*/*/*.d masstree/_masstree_config.d)
+ifneq ($(DEPFILES),)
+-include $(DEPFILES)
+endif
+
+ifeq ($(wildcard masstree/GNUmakefile.in),)
+INSTALL_MASSTREE := $(shell git submodule init; git submodule update)
+endif
+
+ifeq ($(MASSTREE_S),1)
+UPDATE_MASSTREE := $(shell cd ./`git rev-parse --show-cdup` && cur=`git submodule status --cached masstree | head -c 41 | tail -c +2` && if test -z `cd masstree; git rev-list -n1 $$cur^..HEAD 2>/dev/null`; then (echo Updating masstree... 1>&2; cd masstree; git checkout -f master >/dev/null; git pull; cd ..; git submodule update masstree); fi)
+endif
+
+ifneq ($(strip $(DEBUG_S).$(CHECK_INVARIANTS_S).$(EVENT_COUNTERS_S)),$(strip $(DEP_MAIN_CONFIG)))
+DEP_MAIN_CONFIG := $(shell mkdir -p $(O); echo >$(O)/buildstamp; echo "DEP_MAIN_CONFIG:=$(DEBUG_S).$(CHECK_INVARIANTS_S).$(EVENT_COUNTERS_S)" >$(O)/_main_config.d)
+endif
+
+ifneq ($(strip $(MYSQL_S)),$(strip $(DEP_BENCH_CONFIG)))
+DEP_BENCH_CONFIG := $(shell mkdir -p $(O); echo >$(O)/buildstamp.bench; echo "DEP_BENCH_CONFIG:=$(MYSQL_S)" >$(O)/_bench_config.d)
+endif
+
+ifneq ($(strip $(MASSTREE_CONFIG)),$(strip $(DEP_MASSTREE_CONFIG)))
+DEP_MASSTREE_CONFIG := $(shell mkdir -p $(O); echo >$(O)/buildstamp.masstree; echo "DEP_MASSTREE_CONFIG:=$(MASSTREE_CONFIG)" >masstree/_masstree_config.d)
+endif
+
+$(O)/buildstamp $(O)/buildstamp.bench $(O)/buildstamp.masstree:
+       @mkdir -p $(@D)
+       @echo >$@
+
+.PHONY: clean
+clean:
+       rm -rf out-*
+       make -C third-party/lz4 clean
diff --git a/silo/README.md b/silo/README.md
new file mode 100644 (file)
index 0000000..04a68c9
--- /dev/null
@@ -0,0 +1,58 @@
+Silo
+=====
+
+This project contains the prototype of the database system described in 
+
+    Speedy Transactions in Multicore In-Memory Databases 
+    Stephen Tu, Wenting Zheng, Eddie Kohler, Barbara Liskov, Samuel Madden 
+    SOSP 2013. 
+    http://people.csail.mit.edu/stephentu/papers/silo.pdf
+
+This code is an ongoing work in progress.
+
+Build
+-----
+
+There are several options to build. `MODE` is an important variable
+governing the type of build. The default is `MODE=perf`, see the
+Makefile for more options. `DEBUG=1` triggers a debug build (off by
+default). `CHECK_INVARIANTS=1` enables invariant checking. There are
+two targets: the default target which builds the test suite, and
+`dbtest` which builds the benchmark suite. Examples:
+
+    MODE=perf DEBUG=1 CHECK_INVARIANTS=1 make -j
+    MODE=perf make -j dbtest
+
+Each different combination of `MODE`, `DEBUG`, and `CHECK_INVARIANTS` triggers
+a unique output directory; for example, the first command above builds to
+`out-perf.debug.check.masstree`.
+
+Silo now uses [Masstree](https://github.com/kohler/masstree-beta) by default as
+the default index tree. To use the old tree, set `MASSTREE=0`.
+
+Running
+-------
+
+To run the tests, simply invoke `<outdir>/test` with no arguments. To run the
+benchmark suite, invoke `<outdir>/benchmarks/dbtest`. For now, look in
+`benchmarks/dbtest.cc` for documentation on the command line arguments. An
+example invocation for TPC-C is:
+
+    <outdir>/benchmarks/dbtest \
+        --verbose \
+        --bench tpcc \
+        --num-threads 28 \
+        --scale-factor 28 \
+        --runtime 30 \
+        --numa-memory 112G 
+
+Benchmarks
+----------
+
+To reproduce the graphs from the paper:
+
+    $ cd benchmarks
+    $ python runner.py /unused-dir <results-file-prefix>
+
+If you set `DRYRUN=True` in `runner.py`, then you get to see all the
+commands that would be issued by the benchmark script.
diff --git a/silo/allocator.cc b/silo/allocator.cc
new file mode 100644 (file)
index 0000000..6c3067a
--- /dev/null
@@ -0,0 +1,376 @@
+#include <sys/mman.h>
+#include <unistd.h>
+#include <map>
+#include <iostream>
+#include <cstring>
+#include <numa.h>
+
+#include "allocator.h"
+#include "spinlock.h"
+#include "lockguard.h"
+#include "static_vector.h"
+#include "counter.h"
+
+using namespace util;
+
+static event_counter evt_allocator_total_region_usage(
+    "allocator_total_region_usage_bytes");
+
+// page+alloc routines taken from masstree
+
+#ifdef MEMCHECK_MAGIC
+const allocator::pgmetadata *
+allocator::PointerToPgMetadata(const void *p)
+{
+  static const size_t hugepgsize = GetHugepageSize();
+  if (unlikely(!ManagesPointer(p)))
+    return nullptr;
+  const size_t cpu = PointerToCpu(p);
+  const regionctx &pc = g_regions[cpu];
+  if (p >= pc.region_begin)
+    return nullptr;
+  // round pg down to page
+  p = (const void *) ((uintptr_t)p & ~(hugepgsize-1));
+  const pgmetadata *pmd = (const pgmetadata *) p;
+  ALWAYS_ASSERT((pmd->unit_ % AllocAlignment) == 0);
+  ALWAYS_ASSERT((MAX_ARENAS * AllocAlignment) >= pmd->unit_);
+  return pmd;
+}
+#endif
+
+size_t
+allocator::GetHugepageSizeImpl()
+{
+  FILE *f = fopen("/proc/meminfo", "r");
+  assert(f);
+  char *linep = NULL;
+  size_t n = 0;
+  static const char *key = "Hugepagesize:";
+  static const int keylen = strlen(key);
+  size_t size = 0;
+  while (getline(&linep, &n, f) > 0) {
+    if (strstr(linep, key) != linep)
+      continue;
+    size = atol(linep + keylen) * 1024;
+    break;
+  }
+  fclose(f);
+  assert(size);
+  return size;
+}
+
+size_t
+allocator::GetPageSizeImpl()
+{
+  return sysconf(_SC_PAGESIZE);
+}
+
+bool
+allocator::UseMAdvWillNeed()
+{
+  static const char *px = getenv("DISABLE_MADV_WILLNEED");
+  static const std::string s = px ? to_lower(px) : "";
+  static const bool use_madv = !(s == "1" || s == "true");
+  return use_madv;
+}
+
+void
+allocator::Initialize(size_t ncpus, size_t maxpercore)
+{
+  static spinlock s_lock;
+  static bool s_init = false;
+  if (likely(s_init))
+    return;
+  lock_guard<spinlock> l(s_lock);
+  if (s_init)
+    return;
+  ALWAYS_ASSERT(!g_memstart);
+  ALWAYS_ASSERT(!g_memend);
+  ALWAYS_ASSERT(!g_ncpus);
+  ALWAYS_ASSERT(!g_maxpercore);
+
+  static const size_t hugepgsize = GetHugepageSize();
+
+  // round maxpercore to the nearest hugepagesize
+  maxpercore = slow_round_up(maxpercore, hugepgsize);
+
+  g_ncpus = ncpus;
+  g_maxpercore = maxpercore;
+
+  // mmap() the entire region for now, but just as a marker
+  // (this does not actually cause physical pages to be allocated)
+  // note: we allocate an extra hugepgsize so we can guarantee alignment
+  // of g_memstart to a huge page boundary
+
+  void * const x = mmap(nullptr, g_ncpus * g_maxpercore + hugepgsize,
+      PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (x == MAP_FAILED) {
+    perror("mmap");
+    ALWAYS_ASSERT(false);
+  }
+
+  void * const endpx = (void *) ((uintptr_t)x + g_ncpus * g_maxpercore + hugepgsize);
+  std::cerr << "allocator::Initialize()" << std::endl
+            << "  hugepgsize: " << hugepgsize << std::endl
+            << "  use MADV_WILLNEED: " << UseMAdvWillNeed() << std::endl
+            << "  mmap() region [" << x << ", " << endpx << ")" << std::endl;
+
+  g_memstart = reinterpret_cast<void *>(util::iceil(uintptr_t(x), hugepgsize));
+  g_memend = reinterpret_cast<char *>(g_memstart) + (g_ncpus * g_maxpercore);
+
+  ALWAYS_ASSERT(!(reinterpret_cast<uintptr_t>(g_memstart) % hugepgsize));
+  ALWAYS_ASSERT(reinterpret_cast<uintptr_t>(g_memend) <=
+      (reinterpret_cast<uintptr_t>(x) + (g_ncpus * g_maxpercore + hugepgsize)));
+
+  for (size_t i = 0; i < g_ncpus; i++) {
+    g_regions[i].region_begin =
+      reinterpret_cast<char *>(g_memstart) + (i * g_maxpercore);
+    g_regions[i].region_end   =
+      reinterpret_cast<char *>(g_memstart) + ((i + 1) * g_maxpercore);
+    std::cerr << "cpu" << i << " owns [" << g_regions[i].region_begin
+              << ", " << g_regions[i].region_end << ")" << std::endl;
+    ALWAYS_ASSERT(g_regions[i].region_begin < g_regions[i].region_end);
+    ALWAYS_ASSERT(g_regions[i].region_begin >= x);
+    ALWAYS_ASSERT(g_regions[i].region_end <= endpx);
+  }
+
+  s_init = true;
+}
+
+void
+allocator::DumpStats()
+{
+  std::cerr << "[allocator] ncpus=" << g_ncpus << std::endl;
+  for (size_t i = 0; i < g_ncpus; i++) {
+    const bool f = g_regions[i].region_faulted;
+    const size_t remaining =
+      intptr_t(g_regions[i].region_end) -
+      intptr_t(g_regions[i].region_begin);
+    std::cerr << "[allocator] cpu=" << i << " fully_faulted?=" << f
+              << " remaining=" << remaining << " bytes" << std::endl;
+  }
+}
+
+static void *
+initialize_page(void *page, const size_t pagesize, const size_t unit)
+{
+  INVARIANT(((uintptr_t)page % pagesize) == 0);
+
+#ifdef MEMCHECK_MAGIC
+  ::allocator::pgmetadata *pmd = (::allocator::pgmetadata *) page;
+  pmd->unit_ = unit;
+  page = (void *) ((uintptr_t)page + sizeof(*pmd));
+#endif
+
+  void *first = (void *)util::iceil((uintptr_t)page, (uintptr_t)unit);
+  INVARIANT((uintptr_t)first + unit <= (uintptr_t)page + pagesize);
+  void **p = (void **)first;
+  void *next = (void *)((uintptr_t)p + unit);
+  while ((uintptr_t)next + unit <= (uintptr_t)page + pagesize) {
+    INVARIANT(((uintptr_t)p % unit) == 0);
+    *p = next;
+#ifdef MEMCHECK_MAGIC
+    NDB_MEMSET(
+        (char *) p + sizeof(void **),
+        MEMCHECK_MAGIC, unit - sizeof(void **));
+#endif
+    p = (void **)next;
+    next = (void *)((uintptr_t)next + unit);
+  }
+  INVARIANT(((uintptr_t)p % unit) == 0);
+  *p = NULL;
+#ifdef MEMCHECK_MAGIC
+  NDB_MEMSET(
+      (char *) p + sizeof(void **),
+      MEMCHECK_MAGIC, unit - sizeof(void **));
+#endif
+  return first;
+}
+
+void *
+allocator::AllocateArenas(size_t cpu, size_t arena)
+{
+  INVARIANT(cpu < g_ncpus);
+  INVARIANT(arena < MAX_ARENAS);
+  INVARIANT(g_memstart);
+  INVARIANT(g_maxpercore);
+  static const size_t hugepgsize = GetHugepageSize();
+
+  regionctx &pc = g_regions[cpu];
+  pc.lock.lock();
+  if (likely(pc.arenas[arena])) {
+    // claim
+    void *ret = pc.arenas[arena];
+    pc.arenas[arena] = nullptr;
+    pc.lock.unlock();
+    return ret;
+  }
+
+  void * const mypx = AllocateUnmanagedWithLock(pc, 1); // releases lock
+  return initialize_page(mypx, hugepgsize, (arena + 1) * AllocAlignment);
+}
+
+void *
+allocator::AllocateUnmanaged(size_t cpu, size_t nhugepgs)
+{
+  regionctx &pc = g_regions[cpu];
+  pc.lock.lock();
+  return AllocateUnmanagedWithLock(pc, nhugepgs); // releases lock
+}
+
+void *
+allocator::AllocateUnmanagedWithLock(regionctx &pc, size_t nhugepgs)
+{
+  static const size_t hugepgsize = GetHugepageSize();
+
+  void * const mypx = pc.region_begin;
+
+  // check alignment
+  if (reinterpret_cast<uintptr_t>(mypx) % hugepgsize)
+    ALWAYS_ASSERT(false);
+
+  void * const mynewpx =
+    reinterpret_cast<char *>(mypx) + nhugepgs * hugepgsize;
+
+  if (unlikely(mynewpx > pc.region_end)) {
+    std::cerr << "allocator::AllocateUnmanagedWithLock():" << std::endl
+              << "  region ending at " << pc.region_end << " OOM" << std::endl;
+    ALWAYS_ASSERT(false); // out of memory otherwise
+  }
+
+  const bool needs_mmap = !pc.region_faulted;
+  pc.region_begin = mynewpx;
+  pc.lock.unlock();
+
+  evt_allocator_total_region_usage.inc(nhugepgs * hugepgsize);
+
+  if (needs_mmap) {
+    void * const x = mmap(mypx, hugepgsize, PROT_READ | PROT_WRITE,
+        MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+    if (unlikely(x == MAP_FAILED)) {
+      perror("mmap");
+      ALWAYS_ASSERT(false);
+    }
+    INVARIANT(x == mypx);
+    const int advice =
+      UseMAdvWillNeed() ? MADV_HUGEPAGE | MADV_WILLNEED : MADV_HUGEPAGE;
+    if (madvise(x, hugepgsize, advice)) {
+      perror("madvise");
+      ALWAYS_ASSERT(false);
+    }
+  }
+
+  return mypx;
+}
+
+void
+allocator::ReleaseArenas(void **arenas)
+{
+  // cpu -> [(head, tail)]
+  // XXX: use a small_map here?
+  std::map<size_t, static_vector<std::pair<void *, void *>, MAX_ARENAS>> m;
+  for (size_t arena = 0; arena < MAX_ARENAS; arena++) {
+    void *p = arenas[arena];
+    while (p) {
+      void * const pnext = *reinterpret_cast<void **>(p);
+      const size_t cpu = PointerToCpu(p);
+      auto it = m.find(cpu);
+      if (it == m.end()) {
+        auto &v = m[cpu];
+        v.resize(MAX_ARENAS);
+        *reinterpret_cast<void **>(p) = nullptr;
+        v[arena].first = v[arena].second = p;
+      } else {
+        auto &v = it->second;
+        if (!v[arena].second) {
+          *reinterpret_cast<void **>(p) = nullptr;
+          v[arena].first = v[arena].second = p;
+        } else {
+          *reinterpret_cast<void **>(p) = v[arena].first;
+          v[arena].first = p;
+        }
+      }
+      p = pnext;
+    }
+  }
+  for (auto &p : m) {
+    INVARIANT(!p.second.empty());
+    regionctx &pc = g_regions[p.first];
+    lock_guard<spinlock> l(pc.lock);
+    for (size_t arena = 0; arena < MAX_ARENAS; arena++) {
+      INVARIANT(bool(p.second[arena].first) == bool(p.second[arena].second));
+      if (!p.second[arena].first)
+        continue;
+      *reinterpret_cast<void **>(p.second[arena].second) = pc.arenas[arena];
+      pc.arenas[arena] = p.second[arena].first;
+    }
+  }
+}
+
+static void
+numa_hint_memory_placement(void *px, size_t sz, unsigned node)
+{
+  struct bitmask *bm = numa_allocate_nodemask();
+  numa_bitmask_setbit(bm, node);
+  numa_interleave_memory(px, sz, bm);
+  numa_free_nodemask(bm);
+}
+
+void
+allocator::FaultRegion(size_t cpu)
+{
+  static const size_t hugepgsize = GetHugepageSize();
+  ALWAYS_ASSERT(cpu < g_ncpus);
+  regionctx &pc = g_regions[cpu];
+  if (pc.region_faulted)
+    return;
+  lock_guard<std::mutex> l1(pc.fault_lock);
+  lock_guard<spinlock> l(pc.lock); // exclude other users of the allocator
+  if (pc.region_faulted)
+    return;
+  // mmap the entire region + memset it for faulting
+  if (reinterpret_cast<uintptr_t>(pc.region_begin) % hugepgsize)
+    ALWAYS_ASSERT(false);
+  const size_t sz =
+    reinterpret_cast<uintptr_t>(pc.region_end) -
+    reinterpret_cast<uintptr_t>(pc.region_begin);
+  void * const x = mmap(pc.region_begin, sz, PROT_READ | PROT_WRITE,
+      MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+  if (unlikely(x == MAP_FAILED)) {
+    perror("mmap");
+    std::cerr << "  cpu" << cpu
+              << " [" << pc.region_begin << ", " << pc.region_end << ")"
+              << std::endl;
+    ALWAYS_ASSERT(false);
+  }
+  ALWAYS_ASSERT(x == pc.region_begin);
+  const int advice =
+    UseMAdvWillNeed() ? MADV_HUGEPAGE | MADV_WILLNEED : MADV_HUGEPAGE;
+  if (madvise(x, sz, advice)) {
+    perror("madvise");
+    ALWAYS_ASSERT(false);
+  }
+  numa_hint_memory_placement(
+      pc.region_begin,
+      (uintptr_t)pc.region_end - (uintptr_t)pc.region_begin,
+      numa_node_of_cpu(cpu));
+  const size_t nfaults =
+    ((uintptr_t)pc.region_end - (uintptr_t)pc.region_begin) / hugepgsize;
+  std::cerr << "cpu" << cpu << " starting faulting region ("
+            << intptr_t(pc.region_end) - intptr_t(pc.region_begin)
+            << " bytes / " << nfaults << " hugepgs)" << std::endl;
+  timer t;
+  for (char *px = (char *) pc.region_begin;
+       px < (char *) pc.region_end;
+       px += CACHELINE_SIZE)
+    *px = 0xDE;
+  std::cerr << "cpu" << cpu << " finished faulting region in "
+            << t.lap_ms() << " ms" << std::endl;
+  pc.region_faulted = true;
+}
+
+void *allocator::g_memstart = nullptr;
+void *allocator::g_memend = nullptr;
+size_t allocator::g_ncpus = 0;
+size_t allocator::g_maxpercore = 0;
+percore<allocator::regionctx> allocator::g_regions;
diff --git a/silo/allocator.h b/silo/allocator.h
new file mode 100644 (file)
index 0000000..266e686
--- /dev/null
@@ -0,0 +1,145 @@
+#ifndef _NDB_ALLOCATOR_H_
+#define _NDB_ALLOCATOR_H_
+
+#include <cstdint>
+#include <iterator>
+#include <mutex>
+
+#include "util.h"
+#include "core.h"
+#include "macros.h"
+#include "spinlock.h"
+
+class allocator {
+public:
+
+  // our allocator doesn't let allocations exceed maxpercore over a single core
+  //
+  // Initialize can be called many times- but only the first call has effect.
+  //
+  // w/o calling Initialize(), behavior for this class is undefined
+  static void Initialize(size_t ncpus, size_t maxpercore);
+
+  static void DumpStats();
+
+  // returns an arena linked-list
+  static void *
+  AllocateArenas(size_t cpu, size_t sz);
+
+  // allocates nhugepgs * hugepagesize contiguous bytes from CPU's region and
+  // returns the raw, unmanaged pointer.
+  //
+  // Note that memory returned from here cannot be released back to the
+  // allocator, so this should only be used for data structures which live
+  // throughput the duration of the system (ie log buffers)
+  static void *
+  AllocateUnmanaged(size_t cpu, size_t nhugepgs);
+
+  static void
+  ReleaseArenas(void **arenas);
+
+  static const size_t LgAllocAlignment = 4; // all allocations aligned to 2^4 = 16
+  static const size_t AllocAlignment = 1 << LgAllocAlignment;
+  static const size_t MAX_ARENAS = 32;
+
+  static inline std::pair<size_t, size_t>
+  ArenaSize(size_t sz)
+  {
+    const size_t allocsz = util::round_up<size_t, LgAllocAlignment>(sz);
+    const size_t arena = allocsz / AllocAlignment - 1;
+    return std::make_pair(allocsz, arena);
+  }
+
+  // slow, but only needs to be called on initialization
+  static void
+  FaultRegion(size_t cpu);
+
+  // returns true if managed by this allocator, false otherwise
+  static inline bool
+  ManagesPointer(const void *p)
+  {
+    return p >= g_memstart && p < g_memend;
+  }
+
+  // assumes p is managed by this allocator- returns the CPU from which this pointer
+  // was allocated
+  static inline size_t
+  PointerToCpu(const void *p)
+  {
+    ALWAYS_ASSERT(p >= g_memstart);
+    ALWAYS_ASSERT(p < g_memend);
+    const size_t ret =
+      (reinterpret_cast<const char *>(p) -
+       reinterpret_cast<const char *>(g_memstart)) / g_maxpercore;
+    ALWAYS_ASSERT(ret < g_ncpus);
+    return ret;
+  }
+
+#ifdef MEMCHECK_MAGIC
+  struct pgmetadata {
+    uint32_t unit_; // 0-indexed
+  } PACKED;
+
+  // returns nullptr if p is not managed, or has not been allocated yet.
+  // p does not have to be properly aligned
+  static const pgmetadata *
+  PointerToPgMetadata(const void *p);
+#endif
+
+  static size_t
+  GetPageSize()
+  {
+    static const size_t sz = GetPageSizeImpl();
+    return sz;
+  }
+
+  static size_t
+  GetHugepageSize()
+  {
+    static const size_t sz = GetHugepageSizeImpl();
+    return sz;
+  }
+
+private:
+  static size_t GetPageSizeImpl();
+  static size_t GetHugepageSizeImpl();
+  static bool UseMAdvWillNeed();
+
+  struct regionctx {
+    regionctx()
+      : region_begin(nullptr),
+        region_end(nullptr),
+        region_faulted(false)
+    {
+      NDB_MEMSET(arenas, 0, sizeof(arenas));
+    }
+    regionctx(const regionctx &) = delete;
+    regionctx(regionctx &&) = delete;
+    regionctx &operator=(const regionctx &) = delete;
+
+    // set by Initialize()
+    void *region_begin;
+    void *region_end;
+
+    bool region_faulted;
+
+    spinlock lock;
+    std::mutex fault_lock; // XXX: hacky
+    void *arenas[MAX_ARENAS];
+  };
+
+  // assumes caller has the regionctx lock held, and
+  // will release the lock.
+  static void *
+  AllocateUnmanagedWithLock(regionctx &pc, size_t nhugepgs);
+
+  // [g_memstart, g_memstart + ncpus * maxpercore) is the region of memory mmap()-ed
+  static void *g_memstart;
+  static void *g_memend; // g_memstart + ncpus * maxpercore
+  static size_t g_ncpus;
+  static size_t g_maxpercore;
+
+  static percore<regionctx> g_regions CACHE_ALIGNED;
+};
+
+#endif /* _NDB_ALLOCATOR_H_ */
diff --git a/silo/amd64.h b/silo/amd64.h
new file mode 100644 (file)
index 0000000..6a8c673
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _AMD64_H_
+#define _AMD64_H_
+
+#include "macros.h"
+#include <stdint.h>
+
+inline ALWAYS_INLINE void
+nop_pause()
+{
+  __asm volatile("pause" : :);
+}
+
+inline ALWAYS_INLINE uint64_t
+rdtsc(void)
+{
+  uint32_t hi, lo;
+  __asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
+  return ((uint64_t)lo)|(((uint64_t)hi)<<32);
+}
+
+#endif /* _AMD64_H_ */
diff --git a/silo/base_txn_btree.h b/silo/base_txn_btree.h
new file mode 100644 (file)
index 0000000..8a38dd8
--- /dev/null
@@ -0,0 +1,495 @@
+#ifndef _NDB_BASE_TXN_BTREE_H_
+#define _NDB_BASE_TXN_BTREE_H_
+
+#include "btree_choice.h"
+#include "txn.h"
+#include "lockguard.h"
+#include "util.h"
+#include "ndb_type_traits.h"
+
+#include <string>
+#include <map>
+#include <type_traits>
+#include <memory>
+
+// each Transaction implementation should specialize this for special
+// behavior- the default implementation is just nops
+template <template <typename> class Transaction>
+struct base_txn_btree_handler {
+  static inline void on_construct() {} // called when initializing
+  static const bool has_background_task = false;
+};
+
+template <template <typename> class Transaction, typename P>
+class base_txn_btree {
+public:
+
+  typedef transaction_base::tid_t tid_t;
+  typedef transaction_base::size_type size_type;
+  typedef transaction_base::string_type string_type;
+  typedef concurrent_btree::string_type keystring_type;
+
+  base_txn_btree(size_type value_size_hint = 128,
+            bool mostly_append = false,
+            const std::string &name = "<unknown>")
+    : value_size_hint(value_size_hint),
+      name(name),
+      been_destructed(false)
+  {
+    base_txn_btree_handler<Transaction>::on_construct();
+  }
+
+  ~base_txn_btree()
+  {
+    if (!been_destructed)
+      unsafe_purge(false);
+  }
+
+  inline size_t
+  size_estimate() const
+  {
+    return underlying_btree.size();
+  }
+
+  inline size_type
+  get_value_size_hint() const
+  {
+    return value_size_hint;
+  }
+
+  inline void
+  set_value_size_hint(size_type value_size_hint)
+  {
+    this->value_size_hint = value_size_hint;
+  }
+
+  inline void print() {
+    underlying_btree.print();
+  }
+
+  /**
+   * only call when you are sure there are no concurrent modifications on the
+   * tree. is neither threadsafe nor transactional
+   *
+   * Note that when you call unsafe_purge(), this txn_btree becomes
+   * completely invalidated and un-usable. Any further operations
+   * (other than calling the destructor) are undefined
+   */
+  std::map<std::string, uint64_t> unsafe_purge(bool dump_stats = false);
+
+private:
+
+  struct purge_tree_walker : public concurrent_btree::tree_walk_callback {
+    virtual void on_node_begin(const typename concurrent_btree::node_opaque_t *n);
+    virtual void on_node_success();
+    virtual void on_node_failure();
+#ifdef TXN_BTREE_DUMP_PURGE_STATS
+    purge_tree_walker()
+      : purge_stats_nodes(0),
+        purge_stats_nosuffix_nodes(0) {}
+    std::map<size_t, size_t> purge_stats_tuple_record_size_counts; // just the record
+    std::map<size_t, size_t> purge_stats_tuple_alloc_size_counts; // includes overhead
+    //std::map<size_t, size_t> purge_stats_tuple_chain_counts;
+    std::vector<uint16_t> purge_stats_nkeys_node;
+    size_t purge_stats_nodes;
+    size_t purge_stats_nosuffix_nodes;
+
+    std::map<std::string, uint64_t>
+    dump_stats()
+    {
+      std::map<std::string, uint64_t> ret;
+      size_t v = 0;
+      for (std::vector<uint16_t>::iterator it = purge_stats_nkeys_node.begin();
+          it != purge_stats_nkeys_node.end(); ++it)
+        v += *it;
+      const double avg_nkeys_node = double(v)/double(purge_stats_nkeys_node.size());
+      const double avg_fill_factor = avg_nkeys_node/double(concurrent_btree::NKeysPerNode);
+      std::cerr << "btree node stats" << std::endl;
+      std::cerr << "    avg_nkeys_node: " << avg_nkeys_node << std::endl;
+      std::cerr << "    avg_fill_factor: " << avg_fill_factor << std::endl;
+      std::cerr << "    num_nodes: " << purge_stats_nodes << std::endl;
+      std::cerr << "    num_nosuffix_nodes: " << purge_stats_nosuffix_nodes << std::endl;
+      std::cerr << "record size stats (nbytes => count)" << std::endl;
+      for (std::map<size_t, size_t>::iterator it = purge_stats_tuple_record_size_counts.begin();
+          it != purge_stats_tuple_record_size_counts.end(); ++it)
+        std::cerr << "    " << it->first << " => " << it->second << std::endl;
+      std::cerr << "alloc size stats  (nbytes => count)" << std::endl;
+      for (std::map<size_t, size_t>::iterator it = purge_stats_tuple_alloc_size_counts.begin();
+          it != purge_stats_tuple_alloc_size_counts.end(); ++it)
+        std::cerr << "    " << (it->first + sizeof(dbtuple)) << " => " << it->second << std::endl;
+      //std::cerr << "chain stats  (length => count)" << std::endl;
+      //for (std::map<size_t, size_t>::iterator it = purge_stats_tuple_chain_counts.begin();
+      //    it != purge_stats_tuple_chain_counts.end(); ++it) {
+      //  std::cerr << "    " << it->first << " => " << it->second << std::endl;
+      //  ret["chain_" + std::to_string(it->first)] += it->second;
+      //}
+      //std::cerr << "deleted recored stats" << std::endl;
+      //std::cerr << "    logically_removed (total): " << (purge_stats_tuple_logically_removed_no_mark + purge_stats_tuple_logically_removed_with_mark) << std::endl;
+      //std::cerr << "    logically_removed_no_mark: " << purge_stats_tuple_logically_removed_no_mark << std::endl;
+      //std::cerr << "    logically_removed_with_mark: " << purge_stats_tuple_logically_removed_with_mark << std::endl;
+      return ret;
+    }
+#endif
+
+  private:
+    std::vector< std::pair<typename concurrent_btree::value_type, bool> > spec_values;
+  };
+
+protected:
+
+  // readers are placed here so they can be shared amongst
+  // derived implementations
+
+  template <typename Traits, typename Callback,
+            typename KeyReader, typename ValueReader>
+  struct txn_search_range_callback : public concurrent_btree::low_level_search_range_callback {
+    constexpr txn_search_range_callback(
+          Transaction<Traits> *t,
+          Callback *caller_callback,
+          KeyReader *key_reader,
+          ValueReader *value_reader)
+      : t(t), caller_callback(caller_callback),
+        key_reader(key_reader), value_reader(value_reader) {}
+
+    virtual void on_resp_node(const typename concurrent_btree::node_opaque_t *n, uint64_t version);
+    virtual bool invoke(const typename concurrent_btree::string_type &k, typename concurrent_btree::value_type v,
+                        const typename concurrent_btree::node_opaque_t *n, uint64_t version);
+
+  private:
+    Transaction<Traits> *const t;
+    Callback *const caller_callback;
+    KeyReader *const key_reader;
+    ValueReader *const value_reader;
+  };
+
+  template <typename Traits, typename ValueReader>
+  inline bool
+  do_search(Transaction<Traits> &t,
+            const typename P::Key &k,
+            ValueReader &value_reader);
+
+  template <typename Traits, typename Callback,
+            typename KeyReader, typename ValueReader>
+  inline void
+  do_search_range_call(Transaction<Traits> &t,
+                       const typename P::Key &lower,
+                       const typename P::Key *upper,
+                       Callback &callback,
+                       KeyReader &key_reader,
+                       ValueReader &value_reader);
+
+  template <typename Traits, typename Callback,
+            typename KeyReader, typename ValueReader>
+  inline void
+  do_rsearch_range_call(Transaction<Traits> &t,
+                        const typename P::Key &upper,
+                        const typename P::Key *lower,
+                        Callback &callback,
+                        KeyReader &key_reader,
+                        ValueReader &value_reader);
+
+  // expect_new indicates if we expect the record to not exist in the tree-
+  // is just a hint that affects perf, not correctness. remove is put with nullptr
+  // as value.
+  //
+  // NOTE: both key and value are expected to be stable values already
+  template <typename Traits>
+  void do_tree_put(Transaction<Traits> &t,
+                   const std::string *k,
+                   const typename P::Value *v,
+                   dbtuple::tuple_writer_t writer,
+                   bool expect_new);
+
+  concurrent_btree underlying_btree;
+  size_type value_size_hint;
+  std::string name;
+  bool been_destructed;
+};
+
+namespace private_ {
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, txn_btree_search_probe0, txn_btree_search_probe0_cg)
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, txn_btree_search_probe1, txn_btree_search_probe1_cg)
+}
+
+template <template <typename> class Transaction, typename P>
+template <typename Traits, typename ValueReader>
+bool
+base_txn_btree<Transaction, P>::do_search(
+    Transaction<Traits> &t,
+    const typename P::Key &k,
+    ValueReader &value_reader)
+{
+  t.ensure_active();
+
+  typename P::KeyWriter key_writer(&k);
+  const std::string * const key_str =
+    key_writer.fully_materialize(true, t.string_allocator());
+
+  // search the underlying btree to map k=>(btree_node|tuple)
+  typename concurrent_btree::value_type underlying_v{};
+  concurrent_btree::versioned_node_t search_info;
+  const bool found = this->underlying_btree.search(varkey(*key_str), underlying_v, &search_info);
+  if (found) {
+    const dbtuple * const tuple = reinterpret_cast<const dbtuple *>(underlying_v);
+    return t.do_tuple_read(tuple, value_reader);
+  } else {
+    // not found, add to absent_set
+    t.do_node_read(search_info.first, search_info.second);
+    return false;
+  }
+}
+
+template <template <typename> class Transaction, typename P>
+std::map<std::string, uint64_t>
+base_txn_btree<Transaction, P>::unsafe_purge(bool dump_stats)
+{
+  ALWAYS_ASSERT(!been_destructed);
+  been_destructed = true;
+  purge_tree_walker w;
+  scoped_rcu_region guard;
+  underlying_btree.tree_walk(w);
+  underlying_btree.clear();
+#ifdef TXN_BTREE_DUMP_PURGE_STATS
+  if (!dump_stats)
+    return std::map<std::string, uint64_t>();
+  return w.dump_stats();
+#else
+  return std::map<std::string, uint64_t>();
+#endif
+}
+
+template <template <typename> class Transaction, typename P>
+void
+base_txn_btree<Transaction, P>::purge_tree_walker::on_node_begin(const typename concurrent_btree::node_opaque_t *n)
+{
+  INVARIANT(spec_values.empty());
+  spec_values = concurrent_btree::ExtractValues(n);
+}
+
+template <template <typename> class Transaction, typename P>
+void
+base_txn_btree<Transaction, P>::purge_tree_walker::on_node_success()
+{
+  for (size_t i = 0; i < spec_values.size(); i++) {
+    dbtuple *tuple = (dbtuple *) spec_values[i].first;
+    INVARIANT(tuple);
+#ifdef TXN_BTREE_DUMP_PURGE_STATS
+    // XXX(stephentu): should we also walk the chain?
+    purge_stats_tuple_record_size_counts[tuple->is_deleting() ? 0 : tuple->size]++;
+    purge_stats_tuple_alloc_size_counts[tuple->alloc_size]++;
+    //purge_stats_tuple_chain_counts[tuple->chain_length()]++;
+#endif
+    if (base_txn_btree_handler<Transaction>::has_background_task) {
+#ifdef CHECK_INVARIANTS
+      lock_guard<dbtuple> l(tuple, false);
+#endif
+      if (!tuple->is_deleting()) {
+        INVARIANT(tuple->is_latest());
+        tuple->clear_latest();
+        tuple->mark_deleting();
+        dbtuple::release(tuple);
+      } else {
+        // enqueued already to background gc by the writer of the delete
+      }
+    } else {
+      // XXX: this path is probably not right
+      dbtuple::release_no_rcu(tuple);
+    }
+  }
+#ifdef TXN_BTREE_DUMP_PURGE_STATS
+  purge_stats_nkeys_node.push_back(spec_values.size());
+  purge_stats_nodes++;
+  for (size_t i = 0; i < spec_values.size(); i++)
+    if (spec_values[i].second)
+      goto done;
+  purge_stats_nosuffix_nodes++;
+done:
+#endif
+  spec_values.clear();
+}
+
+template <template <typename> class Transaction, typename P>
+void
+base_txn_btree<Transaction, P>::purge_tree_walker::on_node_failure()
+{
+  spec_values.clear();
+}
+
+template <template <typename> class Transaction, typename P>
+template <typename Traits>
+void base_txn_btree<Transaction, P>::do_tree_put(
+    Transaction<Traits> &t,
+    const std::string *k,
+    const typename P::Value *v,
+    dbtuple::tuple_writer_t writer,
+    bool expect_new)
+{
+  INVARIANT(k);
+  INVARIANT(!expect_new || v); // makes little sense to remove() a key you expect
+                               // to not be present, so we assert this doesn't happen
+                               // for now [since this would indicate a suboptimality]
+  t.ensure_active();
+
+  if (unlikely(t.is_snapshot())) {
+    const transaction_base::abort_reason r = transaction_base::ABORT_REASON_USER;
+    t.abort_impl(r);
+    throw transaction_abort_exception(r);
+  }
+  dbtuple *px = nullptr;
+  bool insert = false;
+retry:
+  if (expect_new) {
+    auto ret = t.try_insert_new_tuple(this->underlying_btree, k, v, writer);
+    INVARIANT(!ret.second || ret.first);
+    if (unlikely(ret.second)) {
+      const transaction_base::abort_reason r = transaction_base::ABORT_REASON_WRITE_NODE_INTERFERENCE;
+      t.abort_impl(r);
+      throw transaction_abort_exception(r);
+    }
+    px = ret.first;
+    if (px)
+      insert = true;
+  }
+  if (!px) {
+    // do regular search
+    typename concurrent_btree::value_type bv = 0;
+    if (!this->underlying_btree.search(varkey(*k), bv)) {
+      // XXX(stephentu): if we are removing a key and we can't find it, then we
+      // should just treat this as a read [of an empty-value], instead of
+      // explicitly inserting an empty node...
+      expect_new = true;
+      goto retry;
+    }
+    px = reinterpret_cast<dbtuple *>(bv);
+  }
+  INVARIANT(px);
+  if (!insert) {
+    // add to write set normally, as non-insert
+    t.write_set.emplace_back(px, k, v, writer, &this->underlying_btree, false);
+  } else {
+    // should already exist in write set as insert
+    // (because of try_insert_new_tuple())
+
+    // too expensive to be a practical check
+    //INVARIANT(t.find_write_set(px) != t.write_set.end());
+    //INVARIANT(t.find_write_set(px)->is_insert());
+  }
+}
+
+template <template <typename> class Transaction, typename P>
+template <typename Traits, typename Callback,
+          typename KeyReader, typename ValueReader>
+void
+base_txn_btree<Transaction, P>
+  ::txn_search_range_callback<Traits, Callback, KeyReader, ValueReader>
+  ::on_resp_node(
+    const typename concurrent_btree::node_opaque_t *n, uint64_t version)
+{
+  VERBOSE(std::cerr << "on_resp_node(): <node=0x" << util::hexify(intptr_t(n))
+               << ", version=" << version << ">" << std::endl);
+  VERBOSE(std::cerr << "  " << concurrent_btree::NodeStringify(n) << std::endl);
+  t->do_node_read(n, version);
+}
+
+template <template <typename> class Transaction, typename P>
+template <typename Traits, typename Callback,
+          typename KeyReader, typename ValueReader>
+bool
+base_txn_btree<Transaction, P>
+  ::txn_search_range_callback<Traits, Callback, KeyReader, ValueReader>
+  ::invoke(
+    const typename concurrent_btree::string_type &k, typename concurrent_btree::value_type v,
+    const typename concurrent_btree::node_opaque_t *n, uint64_t version)
+{
+  t->ensure_active();
+  VERBOSE(std::cerr << "search range k: " << util::hexify(k) << " from <node=0x" << util::hexify(n)
+                    << ", version=" << version << ">" << std::endl
+                    << "  " << *((dbtuple *) v) << std::endl);
+  const dbtuple * const tuple = reinterpret_cast<const dbtuple *>(v);
+  if (t->do_tuple_read(tuple, *value_reader))
+    return caller_callback->invoke(
+        (*key_reader)(k), value_reader->results());
+  return true;
+}
+
+template <template <typename> class Transaction, typename P>
+template <typename Traits, typename Callback,
+          typename KeyReader, typename ValueReader>
+void
+base_txn_btree<Transaction, P>::do_search_range_call(
+    Transaction<Traits> &t,
+    const typename P::Key &lower,
+    const typename P::Key *upper,
+    Callback &callback,
+    KeyReader &key_reader,
+    ValueReader &value_reader)
+{
+  t.ensure_active();
+  if (upper)
+    VERBOSE(std::cerr << "txn_btree(0x" << util::hexify(intptr_t(this))
+                 << ")::search_range_call [" << util::hexify(lower)
+                 << ", " << util::hexify(*upper) << ")" << std::endl);
+  else
+    VERBOSE(std::cerr << "txn_btree(0x" << util::hexify(intptr_t(this))
+                 << ")::search_range_call [" << util::hexify(lower)
+                 << ", +inf)" << std::endl);
+
+  typename P::KeyWriter lower_key_writer(&lower);
+  const std::string * const lower_str =
+    lower_key_writer.fully_materialize(true, t.string_allocator());
+
+  typename P::KeyWriter upper_key_writer(upper);
+  const std::string * const upper_str =
+    upper_key_writer.fully_materialize(true, t.string_allocator());
+
+  if (unlikely(upper_str && *upper_str <= *lower_str))
+    return;
+
+  txn_search_range_callback<Traits, Callback, KeyReader, ValueReader> c(
+                       &t, &callback, &key_reader, &value_reader);
+
+  varkey uppervk;
+  if (upper_str)
+    uppervk = varkey(*upper_str);
+  this->underlying_btree.search_range_call(
+      varkey(*lower_str), upper_str ? &uppervk : nullptr,
+      c, t.string_allocator()());
+}
+
+template <template <typename> class Transaction, typename P>
+template <typename Traits, typename Callback,
+          typename KeyReader, typename ValueReader>
+void
+base_txn_btree<Transaction, P>::do_rsearch_range_call(
+    Transaction<Traits> &t,
+    const typename P::Key &upper,
+    const typename P::Key *lower,
+    Callback &callback,
+    KeyReader &key_reader,
+    ValueReader &value_reader)
+{
+  t.ensure_active();
+
+  typename P::KeyWriter lower_key_writer(lower);
+  const std::string * const lower_str =
+    lower_key_writer.fully_materialize(true, t.string_allocator());
+
+  typename P::KeyWriter upper_key_writer(&upper);
+  const std::string * const upper_str =
+    upper_key_writer.fully_materialize(true, t.string_allocator());
+
+  if (unlikely(lower_str && *upper_str <= *lower_str))
+    return;
+
+  txn_search_range_callback<Traits, Callback, KeyReader, ValueReader> c(
+                       &t, &callback, &key_reader, &value_reader);
+
+  varkey lowervk;
+  if (lower_str)
+    lowervk = varkey(*lower_str);
+  this->underlying_btree.rsearch_range_call(
+      varkey(*upper_str), lower_str ? &lowervk : nullptr,
+      c, t.string_allocator()());
+}
+
+#endif /* _NDB_BASE_TXN_BTREE_H_ */
diff --git a/silo/benchmarks/abstract_db.h b/silo/benchmarks/abstract_db.h
new file mode 100644 (file)
index 0000000..ace2a72
--- /dev/null
@@ -0,0 +1,137 @@
+#ifndef _ABSTRACT_DB_H_
+#define _ABSTRACT_DB_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <map>
+#include <string>
+
+#include "abstract_ordered_index.h"
+#include "../str_arena.h"
+
+/**
+ * Abstract interface for a DB. This is to facilitate writing
+ * benchmarks for different systems, making each system present
+ * a unified interface
+ */
+class abstract_db {
+public:
+
+  /**
+   * both get() and put() can throw abstract_abort_exception. If thrown,
+   * abort_txn() must be called (calling commit_txn() will result in undefined
+   * behavior).  Also if thrown, subsequently calling get()/put() will also
+   * result in undefined behavior)
+   */
+  class abstract_abort_exception {};
+
+  // ctor should open db
+  abstract_db() {}
+
+  // dtor should close db
+  virtual ~abstract_db() {}
+
+  /**
+   * an approximate max batch size for updates in a transaction.
+   *
+   * A return value of -1 indicates no maximum
+   */
+  virtual ssize_t txn_max_batch_size() const { return -1; }
+
+  virtual bool index_has_stable_put_memory() const { return false; }
+
+  // XXX(stephentu): laziness
+  virtual size_t
+  sizeof_txn_object(uint64_t txn_flags) const { NDB_UNIMPLEMENTED("sizeof_txn_object"); };
+
+  /**
+   * XXX(stephentu): hack
+   */
+  virtual void do_txn_epoch_sync() const {}
+
+  /**
+   * XXX(stephentu): hack
+   */
+  virtual void do_txn_finish() const {}
+
+  /** loader should be used as a performance hint, not for correctness */
+  virtual void thread_init(bool loader) {}
+
+  virtual void thread_end() {}
+
+  // [ntxns_persisted, ntxns_committed, avg latency]
+  virtual std::tuple<uint64_t, uint64_t, double>
+    get_ntxn_persisted() const { return std::make_tuple(0, 0, 0.0); }
+
+  virtual void reset_ntxn_persisted() { }
+
+  enum TxnProfileHint {
+    HINT_DEFAULT,
+
+    // ycsb profiles
+    HINT_KV_GET_PUT, // KV workloads over a single key
+    HINT_KV_RMW, // get/put over a single key
+    HINT_KV_SCAN, // KV scan workloads (~100 keys)
+
+    // tpcc profiles
+    HINT_TPCC_NEW_ORDER,
+    HINT_TPCC_PAYMENT,
+    HINT_TPCC_DELIVERY,
+    HINT_TPCC_ORDER_STATUS,
+    HINT_TPCC_ORDER_STATUS_READ_ONLY,
+    HINT_TPCC_STOCK_LEVEL,
+    HINT_TPCC_STOCK_LEVEL_READ_ONLY,
+  };
+
+  /**
+   * Initializes a new txn object the space pointed to by buf
+   *
+   * Flags is only for the ndb protocol for now
+   *
+   * [buf, buf + sizeof_txn_object(txn_flags)) is a valid ptr
+   */
+  virtual void *new_txn(
+      uint64_t txn_flags,
+      str_arena &arena,
+      void *buf,
+      TxnProfileHint hint = HINT_DEFAULT) = 0;
+
+  typedef std::map<std::string, uint64_t> counter_map;
+  typedef std::map<std::string, counter_map> txn_counter_map;
+
+  /**
+   * Reports things like read/write set sizes
+   */
+  virtual counter_map
+  get_txn_counters(void *txn) const
+  {
+    return counter_map();
+  }
+
+  /**
+   * Returns true on successful commit.
+   *
+   * On failure, can either throw abstract_abort_exception, or
+   * return false- caller should be prepared to deal with both cases
+   */
+  virtual bool commit_txn(void *txn) = 0;
+
+  /**
+   * XXX
+   */
+  virtual void abort_txn(void *txn) = 0;
+
+  virtual void print_txn_debug(void *txn) const {}
+
+  virtual abstract_ordered_index *
+  open_index(const std::string &name,
+             size_t value_size_hint,
+             bool mostly_append = false) = 0;
+
+  virtual void
+  close_index(abstract_ordered_index *idx) = 0;
+};
+
+#endif /* _ABSTRACT_DB_H_ */
diff --git a/silo/benchmarks/abstract_ordered_index.h b/silo/benchmarks/abstract_ordered_index.h
new file mode 100644 (file)
index 0000000..30a5f3e
--- /dev/null
@@ -0,0 +1,150 @@
+#ifndef _ABSTRACT_ORDERED_INDEX_H_
+#define _ABSTRACT_ORDERED_INDEX_H_
+
+#include <stdint.h>
+#include <string>
+#include <utility>
+#include <map>
+
+#include "../macros.h"
+#include "../str_arena.h"
+
+/**
+ * The underlying index manages memory for keys/values, but
+ * may choose to expose the underlying memory to callers
+ * (see put() and inesrt()).
+ */
+class abstract_ordered_index {
+public:
+
+  virtual ~abstract_ordered_index() {}
+
+  /**
+   * Get a key of length keylen. The underlying DB does not manage
+   * the memory associated with key. Returns true if found, false otherwise
+   */
+  virtual bool get(
+      void *txn,
+      const std::string &key,
+      std::string &value,
+      size_t max_bytes_read = std::string::npos) = 0;
+
+  class scan_callback {
+  public:
+    virtual ~scan_callback() {}
+    // XXX(stephentu): key is passed as (const char *, size_t) pair
+    // because it really should be the string_type of the underlying
+    // tree, but since abstract_ordered_index is not templated we can't
+    // really do better than this for now
+    //
+    // we keep value as std::string b/c we have more control over how those
+    // strings are generated
+    virtual bool invoke(const char *keyp, size_t keylen,
+                        const std::string &value) = 0;
+  };
+
+  /**
+   * Search [start_key, *end_key) if end_key is not null, otherwise
+   * search [start_key, +infty)
+   */
+  virtual void scan(
+      void *txn,
+      const std::string &start_key,
+      const std::string *end_key,
+      scan_callback &callback,
+      str_arena *arena = nullptr) = 0;
+
+  /**
+   * Search (*end_key, start_key] if end_key is not null, otherwise
+   * search (-infty, start_key] (starting at start_key and traversing
+   * backwards)
+   */
+  virtual void rscan(
+      void *txn,
+      const std::string &start_key,
+      const std::string *end_key,
+      scan_callback &callback,
+      str_arena *arena = nullptr) = 0;
+
+  /**
+   * Put a key of length keylen, with mapping of length valuelen.
+   * The underlying DB does not manage the memory pointed to by key or value
+   * (a copy is made).
+   *
+   * If a record with key k exists, overwrites. Otherwise, inserts.
+   *
+   * If the return value is not NULL, then it points to the actual stable
+   * location in memory where the value is located. Thus, [ret, ret+valuelen)
+   * will be valid memory, bytewise equal to [value, value+valuelen), since the
+   * implementations have immutable values for the time being. The value
+   * returned is guaranteed to be valid memory until the key associated with
+   * value is overriden.
+   */
+  virtual const char *
+  put(void *txn,
+      const std::string &key,
+      const std::string &value) = 0;
+
+  virtual const char *
+  put(void *txn,
+      std::string &&key,
+      std::string &&value)
+  {
+    return put(txn, static_cast<const std::string &>(key),
+                    static_cast<const std::string &>(value));
+  }
+
+  /**
+   * Insert a key of length keylen.
+   *
+   * If a record with key k exists, behavior is unspecified- this function
+   * is only to be used when you can guarantee no such key exists (ie in loading phase)
+   *
+   * Default implementation calls put(). See put() for meaning of return value.
+   */
+  virtual const char *
+  insert(void *txn,
+         const std::string &key,
+         const std::string &value)
+  {
+    return put(txn, key, value);
+  }
+
+  virtual const char *
+  insert(void *txn,
+         std::string &&key,
+         std::string &&value)
+  {
+    return insert(txn, static_cast<const std::string &>(key),
+                       static_cast<const std::string &>(value));
+  }
+
+  /**
+   * Default implementation calls put() with NULL (zero-length) value
+   */
+  virtual void remove(
+      void *txn,
+      const std::string &key)
+  {
+    put(txn, key, "");
+  }
+
+  virtual void remove(
+      void *txn,
+      std::string &&key)
+  {
+    remove(txn, static_cast<const std::string &>(key));
+  }
+
+  /**
+   * Only an estimate, not transactional!
+   */
+  virtual size_t size() const = 0;
+
+  /**
+   * Not thread safe for now
+   */
+  virtual std::map<std::string, uint64_t> clear() = 0;
+};
+
+#endif /* _ABSTRACT_ORDERED_INDEX_H_ */
diff --git a/silo/benchmarks/bdb_wrapper.cc b/silo/benchmarks/bdb_wrapper.cc
new file mode 100644 (file)
index 0000000..2ae8fb3
--- /dev/null
@@ -0,0 +1,101 @@
+#include <limits>
+
+#include "bdb_wrapper.h"
+#include "../macros.h"
+
+using namespace std;
+
+bdb_wrapper::bdb_wrapper(const string &envdir, const string &dbfile)
+  : env(0)
+{
+  env = new DbEnv(0);
+  ALWAYS_ASSERT(env->log_set_config(DB_LOG_IN_MEMORY, 1) == 0);
+  ALWAYS_ASSERT(env->set_lg_max(numeric_limits<uint32_t>::max()) == 0);
+  ALWAYS_ASSERT(env->set_lg_regionmax(numeric_limits<uint32_t>::max()) == 0);
+  //ALWAYS_ASSERT(env->set_lg_bsize(numeric_limits<uint32_t>::max()) == 0);
+  ALWAYS_ASSERT(env->set_flags(DB_TXN_NOSYNC, 1) == 0);
+  ALWAYS_ASSERT(env->set_cachesize(4, 0, 1) == 0);
+  ALWAYS_ASSERT(env->open(envdir.c_str(), DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE | DB_THREAD | DB_CREATE, 0) == 0);
+}
+
+bdb_wrapper::~bdb_wrapper()
+{
+  delete env;
+}
+
+void *
+bdb_wrapper::new_txn(
+    uint64_t txn_flags,
+    str_arena &arena,
+    void *buf, TxnProfileHint hint)
+{
+  DbTxn *txn = NULL;
+  ALWAYS_ASSERT(env->txn_begin(NULL, &txn, 0) == 0);
+  ALWAYS_ASSERT(txn != NULL);
+  return (void *) txn;
+}
+
+bool
+bdb_wrapper::commit_txn(void *p)
+{
+  return ((DbTxn *) p)->commit(0) == 0;
+}
+
+void
+bdb_wrapper::abort_txn(void *p)
+{
+  ALWAYS_ASSERT(((DbTxn *) p)->abort() == 0);
+}
+
+abstract_ordered_index *
+bdb_wrapper::open_index(const string &name, size_t value_size_hint, bool mostly_append)
+{
+  Db *db = new Db(env, 0);
+  ALWAYS_ASSERT(db->set_flags(DB_TXN_NOT_DURABLE) == 0);
+  DbTxn *txn = NULL;
+  ALWAYS_ASSERT(env->txn_begin(NULL, &txn, 0) == 0);
+  ALWAYS_ASSERT(db->open(txn, name.c_str(), NULL, DB_BTREE, DB_CREATE, 0) == 0);
+  ALWAYS_ASSERT(txn->commit(0) == 0);
+  return new bdb_ordered_index(db);
+}
+
+void
+bdb_wrapper::close_index(abstract_ordered_index *idx)
+{
+  bdb_ordered_index *bidx = static_cast<bdb_ordered_index *>(idx);
+  delete bidx;
+}
+
+bdb_ordered_index::~bdb_ordered_index()
+{
+  delete db;
+}
+
+bool
+bdb_ordered_index::get(
+    void *txn,
+    const string &key,
+    string &value,
+    size_t max_bytes_read)
+{
+  Dbt kdbt((void *) key.data(), key.size());
+  Dbt vdbt;
+  //vdbt.set_flags(DB_DBT_MALLOC);
+  int retno = db->get((DbTxn *) txn, &kdbt, &vdbt, 0);
+  ALWAYS_ASSERT(retno == 0 || retno == DB_NOTFOUND);
+  // XXX(stephentu): do a better job implementing this
+  value.assign((char *) vdbt.get_data(), min(static_cast<size_t>(vdbt.get_size()), max_bytes_read));
+  return retno == 0;
+}
+
+const char *
+bdb_ordered_index::put(
+    void *txn,
+    const string &key,
+    const string &value)
+{
+  Dbt kdbt((void *) key.data(), key.size());
+  Dbt vdbt((void *) value.data(), value.size());
+  ALWAYS_ASSERT(db->put((DbTxn *) txn, &kdbt, &vdbt, 0) == 0);
+  return 0;
+}
diff --git a/silo/benchmarks/bdb_wrapper.h b/silo/benchmarks/bdb_wrapper.h
new file mode 100644 (file)
index 0000000..f80e9a6
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef _BDB_WRAPPER_H_
+#define _BDB_WRAPPER_H_
+
+#include <string>
+#include <db_cxx.h>
+
+#include "abstract_db.h"
+#include "../macros.h"
+
+class bdb_wrapper : public abstract_db {
+public:
+  bdb_wrapper(const std::string &envdir,
+              const std::string &dbfile);
+  ~bdb_wrapper();
+
+  /**
+   * BDB has small txn sizes
+   */
+  virtual ssize_t txn_max_batch_size() const { return 1000; }
+
+  virtual void *new_txn(
+      uint64_t txn_flags,
+      str_arena &arena,
+      void *buf,
+      TxnProfileHint hint);
+  virtual bool commit_txn(void *txn);
+  virtual void abort_txn(void *txn);
+
+  virtual abstract_ordered_index *
+  open_index(const std::string &name,
+             size_t value_size_hint,
+             bool mostly_append);
+
+  virtual void
+  close_index(abstract_ordered_index *idx);
+
+private:
+  DbEnv *env;
+};
+
+class bdb_ordered_index : public abstract_ordered_index {
+public:
+
+  // takes ownership of db
+  bdb_ordered_index(Db *db) : db(db) {}
+  ~bdb_ordered_index();
+
+  virtual bool get(
+      void *txn,
+      const std::string &key,
+      std::string &value,
+      size_t max_bytes_read);
+
+  virtual const char * put(
+      void *txn,
+      const std::string &key,
+      const std::string &value);
+
+  virtual void scan(
+      void *txn,
+      const std::string &key,
+      const std::string *value,
+      scan_callback &callback,
+      str_arena *arena)
+  {
+    NDB_UNIMPLEMENTED("scan");
+  }
+
+  virtual void rscan(
+      void *txn,
+      const std::string &start_key,
+      const std::string *end_key,
+      scan_callback &callback,
+      str_arena *arena)
+  {
+    NDB_UNIMPLEMENTED("rscan");
+  }
+
+  virtual size_t
+  size() const
+  {
+    NDB_UNIMPLEMENTED("size");
+  }
+
+  virtual std::map<std::string, uint64_t>
+  clear()
+  {
+    NDB_UNIMPLEMENTED("clear");
+  }
+
+private:
+  Db *db;
+};
+
+#endif /* _BDB_WRAPPER_H_ */
diff --git a/silo/benchmarks/bench.cc b/silo/benchmarks/bench.cc
new file mode 100644 (file)
index 0000000..a1c12bb
--- /dev/null
@@ -0,0 +1,428 @@
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <utility>
+#include <string>
+
+#include <stdlib.h>
+#include <sched.h>
+#include <unistd.h>
+#include <sys/sysinfo.h>
+
+#include "bench.h"
+
+#include "../counter.h"
+#include "../scopedperf.hh"
+#include "../allocator.h"
+
+#ifdef USE_JEMALLOC
+//cannot include this header b/c conflicts with malloc.h
+//#include <jemalloc/jemalloc.h>
+extern "C" void malloc_stats_print(void (*write_cb)(void *, const char *), void *cbopaque, const char *opts);
+extern "C" int mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
+#endif
+#ifdef USE_TCMALLOC
+#include <google/heap-profiler.h>
+#endif
+
+using namespace std;
+using namespace util;
+
+size_t nthreads = 1;
+volatile bool running = true;
+int verbose = 0;
+uint64_t txn_flags = 0;
+double scale_factor = 1.0;
+uint64_t runtime = 30;
+uint64_t ops_per_worker = 0;
+int run_mode = RUNMODE_TIME;
+int enable_parallel_loading = false;
+int pin_cpus = 0;
+int slow_exit = 0;
+int retry_aborted_transaction = 0;
+int no_reset_counters = 0;
+int backoff_aborted_transaction = 0;
+
+template <typename T>
+static void
+delete_pointers(const vector<T *> &pts)
+{
+  for (size_t i = 0; i < pts.size(); i++)
+    delete pts[i];
+}
+
+template <typename T>
+static vector<T>
+elemwise_sum(const vector<T> &a, const vector<T> &b)
+{
+  INVARIANT(a.size() == b.size());
+  vector<T> ret(a.size());
+  for (size_t i = 0; i < a.size(); i++)
+    ret[i] = a[i] + b[i];
+  return ret;
+}
+
+template <typename K, typename V>
+static void
+map_agg(map<K, V> &agg, const map<K, V> &m)
+{
+  for (typename map<K, V>::const_iterator it = m.begin();
+       it != m.end(); ++it)
+    agg[it->first] += it->second;
+}
+
+// returns <free_bytes, total_bytes>
+static pair<uint64_t, uint64_t>
+get_system_memory_info()
+{
+  struct sysinfo inf;
+  sysinfo(&inf);
+  return make_pair(inf.mem_unit * inf.freeram, inf.mem_unit * inf.totalram);
+}
+
+static bool
+clear_file(const char *name)
+{
+  ofstream ofs(name);
+  ofs.close();
+  return true;
+}
+
+static void
+write_cb(void *p, const char *s) UNUSED;
+static void
+write_cb(void *p, const char *s)
+{
+  const char *f = "jemalloc.stats";
+  static bool s_clear_file UNUSED = clear_file(f);
+  ofstream ofs(f, ofstream::app);
+  ofs << s;
+  ofs.flush();
+  ofs.close();
+}
+
+static event_avg_counter evt_avg_abort_spins("avg_abort_spins");
+
+void
+bench_worker::run()
+{
+  // XXX(stephentu): so many nasty hacks here. should actually
+  // fix some of this stuff one day
+  if (set_core_id)
+    coreid::set_core_id(worker_id); // cringe
+  {
+    scoped_rcu_region r; // register this thread in rcu region
+  }
+  on_run_setup();
+  scoped_db_thread_ctx ctx(db, false);
+  const workload_desc_vec workload = get_workload();
+  txn_counts.resize(workload.size());
+  barrier_a->count_down();
+  barrier_b->wait_for();
+  while (running && (run_mode != RUNMODE_OPS || ntxn_commits < ops_per_worker)) {
+    double d = r.next_uniform();
+    for (size_t i = 0; i < workload.size(); i++) {
+      if ((i + 1) == workload.size() || d < workload[i].frequency) {
+      retry:
+        timer t;
+        const unsigned long old_seed = r.get_seed();
+        const auto ret = workload[i].fn(this);
+        if (likely(ret.first)) {
+          ++ntxn_commits;
+          latency_numer_us += t.lap();
+          backoff_shifts >>= 1;
+        } else {
+          ++ntxn_aborts;
+          if (retry_aborted_transaction && running) {
+            if (backoff_aborted_transaction) {
+              if (backoff_shifts < 63)
+                backoff_shifts++;
+              uint64_t spins = 1UL << backoff_shifts;
+              spins *= 100; // XXX: tuned pretty arbitrarily
+              evt_avg_abort_spins.offer(spins);
+              while (spins) {
+                nop_pause();
+                spins--;
+              }
+            }
+            r.set_seed(old_seed);
+            goto retry;
+          }
+        }
+        size_delta += ret.second; // should be zero on abort
+        txn_counts[i]++; // txn_counts aren't used to compute throughput (is
+                         // just an informative number to print to the console
+                         // in verbose mode)
+        break;
+      }
+      d -= workload[i].frequency;
+    }
+  }
+}
+
+void
+bench_runner::run()
+{
+  // load data
+  const vector<bench_loader *> loaders = make_loaders();
+  {
+    spin_barrier b(loaders.size());
+    const pair<uint64_t, uint64_t> mem_info_before = get_system_memory_info();
+    {
+      scoped_timer t("dataloading", verbose);
+      for (vector<bench_loader *>::const_iterator it = loaders.begin();
+          it != loaders.end(); ++it) {
+        (*it)->set_barrier(b);
+        (*it)->start();
+      }
+      for (vector<bench_loader *>::const_iterator it = loaders.begin();
+          it != loaders.end(); ++it)
+        (*it)->join();
+    }
+    const pair<uint64_t, uint64_t> mem_info_after = get_system_memory_info();
+    const int64_t delta = int64_t(mem_info_before.first) - int64_t(mem_info_after.first); // free mem
+    const double delta_mb = double(delta)/1048576.0;
+    if (verbose)
+      cerr << "DB size: " << delta_mb << " MB" << endl;
+  }
+
+  db->do_txn_epoch_sync(); // also waits for worker threads to be persisted
+  {
+    const auto persisted_info = db->get_ntxn_persisted();
+    if (get<0>(persisted_info) != get<1>(persisted_info))
+      cerr << "ERROR: " << persisted_info << endl;
+    //ALWAYS_ASSERT(get<0>(persisted_info) == get<1>(persisted_info));
+    if (verbose)
+      cerr << persisted_info << " txns persisted in loading phase" << endl;
+  }
+  db->reset_ntxn_persisted();
+
+  if (!no_reset_counters) {
+    event_counter::reset_all_counters(); // XXX: for now - we really should have a before/after loading
+    PERF_EXPR(scopedperf::perfsum_base::resetall());
+  }
+  {
+    const auto persisted_info = db->get_ntxn_persisted();
+    if (get<0>(persisted_info) != 0 ||
+        get<1>(persisted_info) != 0 ||
+        get<2>(persisted_info) != 0.0) {
+      cerr << persisted_info << endl;
+      ALWAYS_ASSERT(false);
+    }
+  }
+
+  map<string, size_t> table_sizes_before;
+  if (verbose) {
+    for (map<string, abstract_ordered_index *>::iterator it = open_tables.begin();
+         it != open_tables.end(); ++it) {
+      scoped_rcu_region guard;
+      const size_t s = it->second->size();
+      cerr << "table " << it->first << " size " << s << endl;
+      table_sizes_before[it->first] = s;
+    }
+    cerr << "starting benchmark..." << endl;
+  }
+
+  const pair<uint64_t, uint64_t> mem_info_before = get_system_memory_info();
+
+  const vector<bench_worker *> workers = make_workers();
+  ALWAYS_ASSERT(!workers.empty());
+  for (vector<bench_worker *>::const_iterator it = workers.begin();
+       it != workers.end(); ++it)
+    (*it)->start();
+
+  barrier_a.wait_for(); // wait for all threads to start up
+  timer t, t_nosync;
+  barrier_b.count_down(); // bombs away!
+  if (run_mode == RUNMODE_TIME) {
+    sleep(runtime);
+    running = false;
+  }
+  __sync_synchronize();
+  for (size_t i = 0; i < nthreads; i++)
+    workers[i]->join();
+  const unsigned long elapsed_nosync = t_nosync.lap();
+  db->do_txn_finish(); // waits for all worker txns to persist
+  size_t n_commits = 0;
+  size_t n_aborts = 0;
+  uint64_t latency_numer_us = 0;
+  for (size_t i = 0; i < nthreads; i++) {
+    n_commits += workers[i]->get_ntxn_commits();
+    n_aborts += workers[i]->get_ntxn_aborts();
+    latency_numer_us += workers[i]->get_latency_numer_us();
+  }
+  const auto persisted_info = db->get_ntxn_persisted();
+
+  const unsigned long elapsed = t.lap(); // lap() must come after do_txn_finish(),
+                                         // because do_txn_finish() potentially
+                                         // waits a bit
+
+  // various sanity checks
+  ALWAYS_ASSERT(get<0>(persisted_info) == get<1>(persisted_info));
+  // not == b/c persisted_info does not count read-only txns
+  ALWAYS_ASSERT(n_commits >= get<1>(persisted_info));
+
+  const double elapsed_nosync_sec = double(elapsed_nosync) / 1000000.0;
+  const double agg_nosync_throughput = double(n_commits) / elapsed_nosync_sec;
+  const double avg_nosync_per_core_throughput = agg_nosync_throughput / double(workers.size());
+
+  const double elapsed_sec = double(elapsed) / 1000000.0;
+  const double agg_throughput = double(n_commits) / elapsed_sec;
+  const double avg_per_core_throughput = agg_throughput / double(workers.size());
+
+  const double agg_abort_rate = double(n_aborts) / elapsed_sec;
+  const double avg_per_core_abort_rate = agg_abort_rate / double(workers.size());
+
+  // we can use n_commits here, because we explicitly wait for all txns
+  // run to be durable
+  const double agg_persist_throughput = double(n_commits) / elapsed_sec;
+  const double avg_per_core_persist_throughput =
+    agg_persist_throughput / double(workers.size());
+
+  // XXX(stephentu): latency currently doesn't account for read-only txns
+  const double avg_latency_us =
+    double(latency_numer_us) / double(n_commits);
+  const double avg_latency_ms = avg_latency_us / 1000.0;
+  const double avg_persist_latency_ms =
+    get<2>(persisted_info) / 1000.0;
+
+  if (verbose) {
+    const pair<uint64_t, uint64_t> mem_info_after = get_system_memory_info();
+    const int64_t delta = int64_t(mem_info_before.first) - int64_t(mem_info_after.first); // free mem
+    const double delta_mb = double(delta)/1048576.0;
+    map<string, size_t> agg_txn_counts = workers[0]->get_txn_counts();
+    ssize_t size_delta = workers[0]->get_size_delta();
+    for (size_t i = 1; i < workers.size(); i++) {
+      map_agg(agg_txn_counts, workers[i]->get_txn_counts());
+      size_delta += workers[i]->get_size_delta();
+    }
+    const double size_delta_mb = double(size_delta)/1048576.0;
+    map<string, counter_data> ctrs = event_counter::get_all_counters();
+
+    cerr << "--- table statistics ---" << endl;
+    for (map<string, abstract_ordered_index *>::iterator it = open_tables.begin();
+         it != open_tables.end(); ++it) {
+      scoped_rcu_region guard;
+      const size_t s = it->second->size();
+      const ssize_t delta = ssize_t(s) - ssize_t(table_sizes_before[it->first]);
+      cerr << "table " << it->first << " size " << it->second->size();
+      if (delta < 0)
+        cerr << " (" << delta << " records)" << endl;
+      else
+        cerr << " (+" << delta << " records)" << endl;
+    }
+#ifdef ENABLE_BENCH_TXN_COUNTERS
+    cerr << "--- txn counter statistics ---" << endl;
+    {
+      // take from thread 0 for now
+      abstract_db::txn_counter_map agg = workers[0]->get_local_txn_counters();
+      for (auto &p : agg) {
+        cerr << p.first << ":" << endl;
+        for (auto &q : p.second)
+          cerr << "  " << q.first << " : " << q.second << endl;
+      }
+    }
+#endif
+    cerr << "--- benchmark statistics ---" << endl;
+    cerr << "runtime: " << elapsed_sec << " sec" << endl;
+    cerr << "memory delta: " << delta_mb  << " MB" << endl;
+    cerr << "memory delta rate: " << (delta_mb / elapsed_sec)  << " MB/sec" << endl;
+    cerr << "logical memory delta: " << size_delta_mb << " MB" << endl;
+    cerr << "logical memory delta rate: " << (size_delta_mb / elapsed_sec) << " MB/sec" << endl;
+    cerr << "agg_nosync_throughput: " << agg_nosync_throughput << " ops/sec" << endl;
+    cerr << "avg_nosync_per_core_throughput: " << avg_nosync_per_core_throughput << " ops/sec/core" << endl;
+    cerr << "agg_throughput: " << agg_throughput << " ops/sec" << endl;
+    cerr << "avg_per_core_throughput: " << avg_per_core_throughput << " ops/sec/core" << endl;
+    cerr << "agg_persist_throughput: " << agg_persist_throughput << " ops/sec" << endl;
+    cerr << "avg_per_core_persist_throughput: " << avg_per_core_persist_throughput << " ops/sec/core" << endl;
+    cerr << "avg_latency: " << avg_latency_ms << " ms" << endl;
+    cerr << "avg_persist_latency: " << avg_persist_latency_ms << " ms" << endl;
+    cerr << "agg_abort_rate: " << agg_abort_rate << " aborts/sec" << endl;
+    cerr << "avg_per_core_abort_rate: " << avg_per_core_abort_rate << " aborts/sec/core" << endl;
+    cerr << "txn breakdown: " << format_list(agg_txn_counts.begin(), agg_txn_counts.end()) << endl;
+    cerr << "--- system counters (for benchmark) ---" << endl;
+    for (map<string, counter_data>::iterator it = ctrs.begin();
+         it != ctrs.end(); ++it)
+      cerr << it->first << ": " << it->second << endl;
+    cerr << "--- perf counters (if enabled, for benchmark) ---" << endl;
+    PERF_EXPR(scopedperf::perfsum_base::printall());
+    cerr << "--- allocator stats ---" << endl;
+    ::allocator::DumpStats();
+    cerr << "---------------------------------------" << endl;
+
+#ifdef USE_JEMALLOC
+    cerr << "dumping heap profile..." << endl;
+    mallctl("prof.dump", NULL, NULL, NULL, 0);
+    cerr << "printing jemalloc stats..." << endl;
+    malloc_stats_print(write_cb, NULL, "");
+#endif
+#ifdef USE_TCMALLOC
+    HeapProfilerDump("before-exit");
+#endif
+  }
+
+  // output for plotting script
+  cout << agg_throughput << " "
+       << agg_persist_throughput << " "
+       << avg_latency_ms << " "
+       << avg_persist_latency_ms << " "
+       << agg_abort_rate << endl;
+  cout.flush();
+
+  if (!slow_exit)
+    return;
+
+  map<string, uint64_t> agg_stats;
+  for (map<string, abstract_ordered_index *>::iterator it = open_tables.begin();
+       it != open_tables.end(); ++it) {
+    map_agg(agg_stats, it->second->clear());
+    delete it->second;
+  }
+  if (verbose) {
+    for (auto &p : agg_stats)
+      cerr << p.first << " : " << p.second << endl;
+
+  }
+  open_tables.clear();
+
+  delete_pointers(loaders);
+  delete_pointers(workers);
+}
+
+template <typename K, typename V>
+struct map_maxer {
+  typedef map<K, V> map_type;
+  void
+  operator()(map_type &agg, const map_type &m) const
+  {
+    for (typename map_type::const_iterator it = m.begin();
+        it != m.end(); ++it)
+      agg[it->first] = std::max(agg[it->first], it->second);
+  }
+};
+
+//template <typename KOuter, typename KInner, typename VInner>
+//struct map_maxer<KOuter, map<KInner, VInner>> {
+//  typedef map<KInner, VInner> inner_map_type;
+//  typedef map<KOuter, inner_map_type> map_type;
+//};
+
+#ifdef ENABLE_BENCH_TXN_COUNTERS
+void
+bench_worker::measure_txn_counters(void *txn, const char *txn_name)
+{
+  auto ret = db->get_txn_counters(txn);
+  map_maxer<string, uint64_t>()(local_txn_counters[txn_name], ret);
+}
+#endif
+
+map<string, size_t>
+bench_worker::get_txn_counts() const
+{
+  map<string, size_t> m;
+  const workload_desc_vec workload = get_workload();
+  for (size_t i = 0; i < txn_counts.size(); i++)
+    m[workload[i].name] = txn_counts[i];
+  return m;
+}
diff --git a/silo/benchmarks/bench.h b/silo/benchmarks/bench.h
new file mode 100644 (file)
index 0000000..777cce0
--- /dev/null
@@ -0,0 +1,338 @@
+#ifndef _NDB_BENCH_H_
+#define _NDB_BENCH_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <vector>
+#include <utility>
+#include <string>
+
+#include "abstract_db.h"
+#include "../macros.h"
+#include "../thread.h"
+#include "../util.h"
+#include "../spinbarrier.h"
+#include "../rcu.h"
+
+extern void ycsb_do_test(abstract_db *db, int argc, char **argv);
+extern void tpcc_do_test(abstract_db *db, int argc, char **argv);
+extern void queue_do_test(abstract_db *db, int argc, char **argv);
+extern void encstress_do_test(abstract_db *db, int argc, char **argv);
+extern void bid_do_test(abstract_db *db, int argc, char **argv);
+
+enum {
+  RUNMODE_TIME = 0,
+  RUNMODE_OPS  = 1
+};
+
+// benchmark global variables
+extern size_t nthreads;
+extern volatile bool running;
+extern int verbose;
+extern uint64_t txn_flags;
+extern double scale_factor;
+extern uint64_t runtime;
+extern uint64_t ops_per_worker;
+extern int run_mode;
+extern int enable_parallel_loading;
+extern int pin_cpus;
+extern int slow_exit;
+extern int retry_aborted_transaction;
+extern int no_reset_counters;
+extern int backoff_aborted_transaction;
+
+class scoped_db_thread_ctx {
+public:
+  scoped_db_thread_ctx(const scoped_db_thread_ctx &) = delete;
+  scoped_db_thread_ctx(scoped_db_thread_ctx &&) = delete;
+  scoped_db_thread_ctx &operator=(const scoped_db_thread_ctx &) = delete;
+
+  scoped_db_thread_ctx(abstract_db *db, bool loader)
+    : db(db)
+  {
+    db->thread_init(loader);
+  }
+  ~scoped_db_thread_ctx()
+  {
+    db->thread_end();
+  }
+private:
+  abstract_db *const db;
+};
+
+class bench_loader : public ndb_thread {
+public:
+  bench_loader(unsigned long seed, abstract_db *db,
+               const std::map<std::string, abstract_ordered_index *> &open_tables)
+    : r(seed), db(db), open_tables(open_tables), b(0)
+  {
+    txn_obj_buf.reserve(str_arena::MinStrReserveLength);
+    txn_obj_buf.resize(db->sizeof_txn_object(txn_flags));
+  }
+  inline void
+  set_barrier(spin_barrier &b)
+  {
+    ALWAYS_ASSERT(!this->b);
+    this->b = &b;
+  }
+  virtual void
+  run()
+  {
+    { // XXX(stephentu): this is a hack
+      scoped_rcu_region r; // register this thread in rcu region
+    }
+    ALWAYS_ASSERT(b);
+    b->count_down();
+    b->wait_for();
+    scoped_db_thread_ctx ctx(db, true);
+    load();
+  }
+protected:
+  inline void *txn_buf() { return (void *) txn_obj_buf.data(); }
+
+  virtual void load() = 0;
+
+  util::fast_random r;
+  abstract_db *const db;
+  std::map<std::string, abstract_ordered_index *> open_tables;
+  spin_barrier *b;
+  std::string txn_obj_buf;
+  str_arena arena;
+};
+
+class bench_worker : public ndb_thread {
+public:
+
+  bench_worker(unsigned int worker_id,
+               bool set_core_id,
+               unsigned long seed, abstract_db *db,
+               const std::map<std::string, abstract_ordered_index *> &open_tables,
+               spin_barrier *barrier_a, spin_barrier *barrier_b)
+    : worker_id(worker_id), set_core_id(set_core_id),
+      r(seed), db(db), open_tables(open_tables),
+      barrier_a(barrier_a), barrier_b(barrier_b),
+      // the ntxn_* numbers are per worker
+      ntxn_commits(0), ntxn_aborts(0),
+      latency_numer_us(0),
+      backoff_shifts(0), // spin between [0, 2^backoff_shifts) times before retry
+      size_delta(0)
+  {
+    txn_obj_buf.reserve(str_arena::MinStrReserveLength);
+    txn_obj_buf.resize(db->sizeof_txn_object(txn_flags));
+  }
+
+  virtual ~bench_worker() {}
+
+  // returns [did_commit?, size_increase_bytes]
+  typedef std::pair<bool, ssize_t> txn_result;
+  typedef txn_result (*txn_fn_t)(bench_worker *);
+
+  struct workload_desc {
+    workload_desc() {}
+    workload_desc(const std::string &name, double frequency, txn_fn_t fn)
+      : name(name), frequency(frequency), fn(fn)
+    {
+      ALWAYS_ASSERT(frequency > 0.0);
+      ALWAYS_ASSERT(frequency <= 1.0);
+    }
+    std::string name;
+    double frequency;
+    txn_fn_t fn;
+  };
+  typedef std::vector<workload_desc> workload_desc_vec;
+  virtual workload_desc_vec get_workload() const = 0;
+
+  virtual void run();
+
+  inline size_t get_ntxn_commits() const { return ntxn_commits; }
+  inline size_t get_ntxn_aborts() const { return ntxn_aborts; }
+
+  inline uint64_t get_latency_numer_us() const { return latency_numer_us; }
+
+  inline double
+  get_avg_latency_us() const
+  {
+    return double(latency_numer_us) / double(ntxn_commits);
+  }
+
+  std::map<std::string, size_t> get_txn_counts() const;
+
+  typedef abstract_db::counter_map counter_map;
+  typedef abstract_db::txn_counter_map txn_counter_map;
+
+#ifdef ENABLE_BENCH_TXN_COUNTERS
+  inline txn_counter_map
+  get_local_txn_counters() const
+  {
+    return local_txn_counters;
+  }
+#endif
+
+  inline ssize_t get_size_delta() const { return size_delta; }
+
+protected:
+
+  virtual void on_run_setup() {}
+
+  inline void *txn_buf() { return (void *) txn_obj_buf.data(); }
+
+  unsigned int worker_id;
+  bool set_core_id;
+  util::fast_random r;
+  abstract_db *const db;
+  std::map<std::string, abstract_ordered_index *> open_tables;
+  spin_barrier *const barrier_a;
+  spin_barrier *const barrier_b;
+
+private:
+  size_t ntxn_commits;
+  size_t ntxn_aborts;
+  uint64_t latency_numer_us;
+  unsigned backoff_shifts;
+
+protected:
+
+#ifdef ENABLE_BENCH_TXN_COUNTERS
+  txn_counter_map local_txn_counters;
+  void measure_txn_counters(void *txn, const char *txn_name);
+#else
+  inline ALWAYS_INLINE void measure_txn_counters(void *txn, const char *txn_name) {}
+#endif
+
+  std::vector<size_t> txn_counts; // breakdown of txns
+  ssize_t size_delta; // how many logical bytes (of values) did the worker add to the DB
+
+  std::string txn_obj_buf;
+  str_arena arena;
+};
+
+class bench_runner {
+public:
+  bench_runner(const bench_runner &) = delete;
+  bench_runner(bench_runner &&) = delete;
+  bench_runner &operator=(const bench_runner &) = delete;
+
+  bench_runner(abstract_db *db)
+    : db(db), barrier_a(nthreads), barrier_b(1) {}
+  virtual ~bench_runner() {}
+  void run();
+protected:
+  // only called once
+  virtual std::vector<bench_loader*> make_loaders() = 0;
+
+  // only called once
+  virtual std::vector<bench_worker*> make_workers() = 0;
+
+  abstract_db *const db;
+  std::map<std::string, abstract_ordered_index *> open_tables;
+
+  // barriers for actual benchmark execution
+  spin_barrier barrier_a;
+  spin_barrier barrier_b;
+};
+
+// XXX(stephentu): limit_callback is not optimal, should use
+// static_limit_callback if possible
+class limit_callback : public abstract_ordered_index::scan_callback {
+public:
+  limit_callback(ssize_t limit = -1)
+    : limit(limit), n(0)
+  {
+    ALWAYS_ASSERT(limit == -1 || limit > 0);
+  }
+
+  virtual bool invoke(
+      const char *keyp, size_t keylen,
+      const std::string &value)
+  {
+    INVARIANT(limit == -1 || n < size_t(limit));
+    values.emplace_back(std::string(keyp, keylen), value);
+    return (limit == -1) || (++n < size_t(limit));
+  }
+
+  typedef std::pair<std::string, std::string> kv_pair;
+  std::vector<kv_pair> values;
+
+  const ssize_t limit;
+private:
+  size_t n;
+};
+
+
+class latest_key_callback : public abstract_ordered_index::scan_callback {
+public:
+  latest_key_callback(std::string &k, ssize_t limit = -1)
+    : limit(limit), n(0), k(&k)
+  {
+    ALWAYS_ASSERT(limit == -1 || limit > 0);
+  }
+
+  virtual bool invoke(
+      const char *keyp, size_t keylen,
+      const std::string &value)
+  {
+    INVARIANT(limit == -1 || n < size_t(limit));
+    k->assign(keyp, keylen);
+    ++n;
+    return (limit == -1) || (n < size_t(limit));
+  }
+
+  inline size_t size() const { return n; }
+  inline std::string &kstr() { return *k; }
+
+private:
+  ssize_t limit;
+  size_t n;
+  std::string *k;
+};
+
+// explicitly copies keys, because btree::search_range_call() interally
+// re-uses a single string to pass keys (so using standard string assignment
+// will force a re-allocation b/c of shared ref-counting)
+//
+// this isn't done for values, because each value has a distinct string from
+// the string allocator, so there are no mutations while holding > 1 ref-count
+template <size_t N>
+class static_limit_callback : public abstract_ordered_index::scan_callback {
+public:
+  // XXX: push ignore_key into lower layer
+  static_limit_callback(str_arena *arena, bool ignore_key)
+    : n(0), arena(arena), ignore_key(ignore_key)
+  {
+    static_assert(N > 0, "xx");
+  }
+
+  virtual bool invoke(
+      const char *keyp, size_t keylen,
+      const std::string &value)
+  {
+    INVARIANT(n < N);
+    INVARIANT(arena->manages(&value));
+    if (ignore_key) {
+      values.emplace_back(nullptr, &value);
+    } else {
+      std::string * const s_px = arena->next();
+      INVARIANT(s_px && s_px->empty());
+      s_px->assign(keyp, keylen);
+      values.emplace_back(s_px, &value);
+    }
+    return ++n < N;
+  }
+
+  inline size_t
+  size() const
+  {
+    return values.size();
+  }
+
+  typedef std::pair<const std::string *, const std::string *> kv_pair;
+  typename util::vec<kv_pair, N>::type values;
+
+private:
+  size_t n;
+  str_arena *arena;
+  bool ignore_key;
+};
+
+#endif /* _NDB_BENCH_H_ */
diff --git a/silo/benchmarks/bid.cc b/silo/benchmarks/bid.cc
new file mode 100644 (file)
index 0000000..bddcbad
--- /dev/null
@@ -0,0 +1,266 @@
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <utility>
+#include <string>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../macros.h"
+#include "../varkey.h"
+#include "../thread.h"
+#include "../util.h"
+#include "../spinbarrier.h"
+
+#include "../record/encoder.h"
+#include "bench.h"
+
+using namespace std;
+using namespace util;
+
+static size_t nusers;
+static size_t nproducts;
+static const float pricefactor = 10000.0; // bids range from [0, 10000.0)
+
+#define BIDUSER_REC_KEY_FIELDS(x, y) \
+  x(uint32_t,uid)
+#define BIDUSER_REC_VALUE_FIELDS(x, y) \
+  x(uint32_t,bid)
+DO_STRUCT(biduser_rec, BIDUSER_REC_KEY_FIELDS, BIDUSER_REC_VALUE_FIELDS)
+
+#define BID_REC_KEY_FIELDS(x, y) \
+  x(uint32_t,uid) \
+  y(uint32_t,bid)
+#define BID_REC_VALUE_FIELDS(x, y) \
+  x(uint32_t,pid) \
+  y(float,amount)
+DO_STRUCT(bid_rec, BID_REC_KEY_FIELDS, BID_REC_VALUE_FIELDS)
+
+#define BIDMAX_REC_KEY_FIELDS(x, y) \
+  x(uint32_t,pid)
+#define BIDMAX_REC_VALUE_FIELDS(x, y) \
+  x(float,amount)
+DO_STRUCT(bidmax_rec, BIDMAX_REC_KEY_FIELDS, BIDMAX_REC_VALUE_FIELDS)
+
+class bid_worker : public bench_worker {
+public:
+  bid_worker(
+      unsigned int worker_id,
+      unsigned long seed, abstract_db *db,
+      const map<string, abstract_ordered_index *> &open_tables,
+      spin_barrier *barrier_a, spin_barrier *barrier_b)
+    : bench_worker(worker_id, false, seed, db,
+                   open_tables, barrier_a, barrier_b),
+      bidusertbl(open_tables.at("biduser")),
+      bidtbl(open_tables.at("bid")),
+      bidmaxtbl(open_tables.at("bidmax"))
+  {
+  }
+
+  txn_result
+  txn_bid()
+  {
+    void *txn = db->new_txn(txn_flags, arena, txn_buf());
+    try {
+      // pick user at random
+      biduser_rec::key biduser_key(r.next() % nusers);
+      ALWAYS_ASSERT(bidusertbl->get(txn, Encode(obj_k0, biduser_key), obj_v0));
+      biduser_rec::value biduser_value_temp;
+      const biduser_rec::value *biduser_value = Decode(obj_v0, biduser_value_temp);
+
+      // update the user's bid
+      const uint32_t bid = biduser_value->bid;
+      biduser_value_temp.bid++;
+      bidusertbl->put(txn, Encode(str(), biduser_key), Encode(str(), biduser_value_temp));
+
+      // insert the new bid
+      const bid_rec::key bid_key(biduser_key.uid, bid);
+      const bid_rec::value bid_value(r.next() % nproducts, r.next_uniform() * pricefactor);
+      bidtbl->insert(txn, Encode(str(), bid_key), Encode(str(), bid_value));
+
+      // update the max value if necessary
+      const bidmax_rec::key bidmax_key(bid_value.pid);
+      ALWAYS_ASSERT(bidmaxtbl->get(txn, Encode(obj_k0, bidmax_key), obj_v0));
+      bidmax_rec::value bidmax_value_temp;
+      const bidmax_rec::value *bidmax_value = Decode(obj_v0, bidmax_value_temp);
+
+      if (bid_value.amount > bidmax_value->amount) {
+        bidmax_value_temp.amount = bid_value.amount;
+        bidmaxtbl->put(txn, Encode(str(), bidmax_key), Encode(str(), bidmax_value_temp));
+      }
+
+      if (likely(db->commit_txn(txn)))
+        return txn_result(true, 0);
+    } catch (abstract_db::abstract_abort_exception &ex) {
+      db->abort_txn(txn);
+    }
+    return txn_result(false, 0);
+  }
+
+  static txn_result
+  TxnBid(bench_worker *w)
+  {
+    return static_cast<bid_worker *>(w)->txn_bid();
+  }
+
+  virtual workload_desc_vec
+  get_workload() const
+  {
+    workload_desc_vec w;
+    w.push_back(workload_desc("Bid", 1.0, TxnBid));
+    return w;
+  }
+
+private:
+  inline ALWAYS_INLINE string &
+  str()
+  {
+    return *arena.next();
+  }
+
+  abstract_ordered_index *bidusertbl;
+  abstract_ordered_index *bidtbl;
+  abstract_ordered_index *bidmaxtbl;
+
+  // scratch buffer space
+  string obj_k0;
+  string obj_v0;
+
+};
+
+class bid_loader : public bench_loader {
+public:
+  bid_loader(unsigned long seed,
+             abstract_db *db,
+             const map<string, abstract_ordered_index *> &open_tables)
+    : bench_loader(seed, db, open_tables)
+  {}
+
+protected:
+  virtual void
+  load()
+  {
+    abstract_ordered_index *bidusertbl = open_tables.at("biduser");
+    abstract_ordered_index *bidmaxtbl = open_tables.at("bidmax");
+    try {
+      // load
+      const size_t batchsize = (db->txn_max_batch_size() == -1) ?
+        10000 : db->txn_max_batch_size();
+      ALWAYS_ASSERT(batchsize > 0);
+
+      {
+        const size_t nbatches = nusers / batchsize;
+        if (nbatches == 0) {
+          void *txn = db->new_txn(txn_flags, arena, txn_buf());
+          for (size_t j = 0; j < nusers; j++) {
+            const biduser_rec::key key(j);
+            const biduser_rec::value value(0);
+            string buf0;
+            bidusertbl->insert(txn, Encode(key), Encode(buf0, value));
+          }
+          if (verbose)
+            cerr << "batch 1/1 done" << endl;
+          ALWAYS_ASSERT(db->commit_txn(txn));
+        } else {
+          for (size_t i = 0; i < nbatches; i++) {
+            size_t keyend = (i == nbatches - 1) ? nusers : (i + 1) * batchsize;
+            void *txn = db->new_txn(txn_flags, arena, txn_buf());
+            for (size_t j = i * batchsize; j < keyend; j++) {
+              const biduser_rec::key key(j);
+              const biduser_rec::value value(0);
+              string buf0;
+              bidusertbl->insert(txn, Encode(key), Encode(buf0, value));
+            }
+            if (verbose)
+              cerr << "batch " << (i + 1) << "/" << nbatches << " done" << endl;
+            ALWAYS_ASSERT(db->commit_txn(txn));
+          }
+        }
+        if (verbose)
+          cerr << "[INFO] finished loading BIDUSER table" << endl;
+      }
+
+      {
+        const size_t nbatches = nproducts / batchsize;
+        if (nbatches == 0) {
+          void *txn = db->new_txn(txn_flags, arena, txn_buf());
+          for (size_t j = 0; j < nproducts; j++) {
+            const bidmax_rec::key key(j);
+            const bidmax_rec::value value(0.0);
+            string buf0;
+            bidmaxtbl->insert(txn, Encode(key), Encode(buf0, value));
+          }
+          if (verbose)
+            cerr << "batch 1/1 done" << endl;
+          ALWAYS_ASSERT(db->commit_txn(txn));
+        } else {
+          for (size_t i = 0; i < nbatches; i++) {
+            size_t keyend = (i == nbatches - 1) ? nproducts : (i + 1) * batchsize;
+            void *txn = db->new_txn(txn_flags, arena, txn_buf());
+            for (size_t j = i * batchsize; j < keyend; j++) {
+              const bidmax_rec::key key(j);
+              const bidmax_rec::value value(0.0);
+              string buf0;
+              bidmaxtbl->insert(txn, Encode(key), Encode(buf0, value));
+            }
+            if (verbose)
+              cerr << "batch " << (i + 1) << "/" << nbatches << " done" << endl;
+            ALWAYS_ASSERT(db->commit_txn(txn));
+          }
+        }
+        if (verbose)
+          cerr << "[INFO] finished loading BIDMAX table" << endl;
+      }
+
+    } catch (abstract_db::abstract_abort_exception &ex) {
+      // shouldn't abort on loading!
+      ALWAYS_ASSERT(false);
+    }
+
+  }
+};
+
+class bid_bench_runner : public bench_runner {
+public:
+  bid_bench_runner(abstract_db *db)
+    : bench_runner(db)
+  {
+    open_tables["biduser"] = db->open_index("biduser", sizeof(biduser_rec));
+    open_tables["bid"] = db->open_index("bid", sizeof(bid_rec));
+    open_tables["bidmax"] = db->open_index("bidmax", sizeof(bidmax_rec));
+  }
+
+protected:
+  virtual vector<bench_loader *>
+  make_loaders()
+  {
+    vector<bench_loader *> ret;
+    ret.push_back(new bid_loader(0, db, open_tables));
+    return ret;
+  }
+
+  virtual vector<bench_worker *>
+  make_workers()
+  {
+    fast_random r(36578943);
+    vector<bench_worker *> ret;
+    for (size_t i = 0; i < nthreads; i++)
+      ret.push_back(
+        new bid_worker(
+          i, r.next(), db, open_tables,
+          &barrier_a, &barrier_b));
+    return ret;
+  }
+};
+
+void
+bid_do_test(abstract_db *db, int argc, char **argv)
+{
+  nusers = size_t(scale_factor * 1000.0);
+  nproducts = size_t(scale_factor * 1000.0);
+  ALWAYS_ASSERT(nusers > 0);
+  ALWAYS_ASSERT(nproducts > 0);
+  bid_bench_runner r(db);
+  r.run();
+}
diff --git a/silo/benchmarks/dbtest.cc b/silo/benchmarks/dbtest.cc
new file mode 100644 (file)
index 0000000..0605654
--- /dev/null
@@ -0,0 +1,407 @@
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <utility>
+#include <string>
+#include <set>
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/sysinfo.h>
+
+#include "../allocator.h"
+#include "../stats_server.h"
+#include "bench.h"
+#include "bdb_wrapper.h"
+#include "ndb_wrapper.h"
+#include "ndb_wrapper_impl.h"
+#include "kvdb_wrapper.h"
+#include "kvdb_wrapper_impl.h"
+#if !NO_MYSQL
+#include "mysql_wrapper.h"
+#endif
+
+using namespace std;
+using namespace util;
+
+static vector<string>
+split_ws(const string &s)
+{
+  vector<string> r;
+  istringstream iss(s);
+  copy(istream_iterator<string>(iss),
+       istream_iterator<string>(),
+       back_inserter<vector<string>>(r));
+  return r;
+}
+
+static size_t
+parse_memory_spec(const string &s)
+{
+  string x(s);
+  size_t mult = 1;
+  if (x.back() == 'G') {
+    mult = static_cast<size_t>(1) << 30;
+    x.pop_back();
+  } else if (x.back() == 'M') {
+    mult = static_cast<size_t>(1) << 20;
+    x.pop_back();
+  } else if (x.back() == 'K') {
+    mult = static_cast<size_t>(1) << 10;
+    x.pop_back();
+  }
+  return strtoul(x.c_str(), nullptr, 10) * mult;
+}
+
+int
+main(int argc, char **argv)
+{
+  abstract_db *db = NULL;
+  void (*test_fn)(abstract_db *, int argc, char **argv) = NULL;
+  string bench_type = "ycsb";
+  string db_type = "ndb-proto2";
+  char *curdir = get_current_dir_name();
+  string basedir = curdir;
+  string bench_opts;
+  size_t numa_memory = 0;
+  free(curdir);
+  int saw_run_spec = 0;
+  int nofsync = 0;
+  int do_compress = 0;
+  int fake_writes = 0;
+  int disable_gc = 0;
+  int disable_snapshots = 0;
+  vector<string> logfiles;
+  vector<vector<unsigned>> assignments;
+  string stats_server_sockfile;
+  while (1) {
+    static struct option long_options[] =
+    {
+      {"verbose"                    , no_argument       , &verbose                   , 1}   ,
+      {"parallel-loading"           , no_argument       , &enable_parallel_loading   , 1}   ,
+      {"pin-cpus"                   , no_argument       , &pin_cpus                  , 1}   ,
+      {"slow-exit"                  , no_argument       , &slow_exit                 , 1}   ,
+      {"retry-aborted-transactions" , no_argument       , &retry_aborted_transaction , 1}   ,
+      {"backoff-aborted-transactions" , no_argument     , &backoff_aborted_transaction , 1}   ,
+      {"bench"                      , required_argument , 0                          , 'b'} ,
+      {"scale-factor"               , required_argument , 0                          , 's'} ,
+      {"num-threads"                , required_argument , 0                          , 't'} ,
+      {"db-type"                    , required_argument , 0                          , 'd'} ,
+      {"basedir"                    , required_argument , 0                          , 'B'} ,
+      {"txn-flags"                  , required_argument , 0                          , 'f'} ,
+      {"runtime"                    , required_argument , 0                          , 'r'} ,
+      {"ops-per-worker"             , required_argument , 0                          , 'n'} ,
+      {"bench-opts"                 , required_argument , 0                          , 'o'} ,
+      {"numa-memory"                , required_argument , 0                          , 'm'} , // implies --pin-cpus
+      {"logfile"                    , required_argument , 0                          , 'l'} ,
+      {"assignment"                 , required_argument , 0                          , 'a'} ,
+      {"log-nofsync"                , no_argument       , &nofsync                   , 1}   ,
+      {"log-compress"               , no_argument       , &do_compress               , 1}   ,
+      {"log-fake-writes"            , no_argument       , &fake_writes               , 1}   ,
+      {"disable-gc"                 , no_argument       , &disable_gc                , 1}   ,
+      {"disable-snapshots"          , no_argument       , &disable_snapshots         , 1}   ,
+      {"stats-server-sockfile"      , required_argument , 0                          , 'x'} ,
+      {"no-reset-counters"          , no_argument       , &no_reset_counters         , 1}   ,
+      {0, 0, 0, 0}
+    };
+    int option_index = 0;
+    int c = getopt_long(argc, argv, "b:s:t:d:B:f:r:n:o:m:l:a:x:", long_options, &option_index);
+    if (c == -1)
+      break;
+
+    switch (c) {
+    case 0:
+      if (long_options[option_index].flag != 0)
+        break;
+      abort();
+      break;
+
+    case 'b':
+      bench_type = optarg;
+      break;
+
+    case 's':
+      scale_factor = strtod(optarg, NULL);
+      ALWAYS_ASSERT(scale_factor > 0.0);
+      break;
+
+    case 't':
+      nthreads = strtoul(optarg, NULL, 10);
+      ALWAYS_ASSERT(nthreads > 0);
+      break;
+
+    case 'd':
+      db_type = optarg;
+      break;
+
+    case 'B':
+      basedir = optarg;
+      break;
+
+    case 'f':
+      txn_flags = strtoul(optarg, NULL, 10);
+      break;
+
+    case 'r':
+      ALWAYS_ASSERT(!saw_run_spec);
+      saw_run_spec = 1;
+      runtime = strtoul(optarg, NULL, 10);
+      ALWAYS_ASSERT(runtime > 0);
+      run_mode = RUNMODE_TIME;
+      break;
+
+    case 'n':
+      ALWAYS_ASSERT(!saw_run_spec);
+      saw_run_spec = 1;
+      ops_per_worker = strtoul(optarg, NULL, 10);
+      ALWAYS_ASSERT(ops_per_worker > 0);
+      run_mode = RUNMODE_OPS;
+
+    case 'o':
+      bench_opts = optarg;
+      break;
+
+    case 'm':
+      {
+        pin_cpus = 1;
+        const size_t m = parse_memory_spec(optarg);
+        ALWAYS_ASSERT(m > 0);
+        numa_memory = m;
+      }
+      break;
+
+    case 'l':
+      logfiles.emplace_back(optarg);
+      break;
+
+    case 'a':
+      assignments.emplace_back(
+          ParseCSVString<unsigned, RangeAwareParser<unsigned>>(optarg));
+      break;
+
+    case 'x':
+      stats_server_sockfile = optarg;
+      break;
+
+    case '?':
+      /* getopt_long already printed an error message. */
+      exit(1);
+
+    default:
+      abort();
+    }
+  }
+
+  if (bench_type == "ycsb")
+    test_fn = ycsb_do_test;
+  else if (bench_type == "tpcc")
+    test_fn = tpcc_do_test;
+  else if (bench_type == "queue")
+    test_fn = queue_do_test;
+  else if (bench_type == "encstress")
+    test_fn = encstress_do_test;
+  else if (bench_type == "bid")
+    test_fn = bid_do_test;
+  else
+    ALWAYS_ASSERT(false);
+
+  if (do_compress && logfiles.empty()) {
+    cerr << "[ERROR] --log-compress specified without logging enabled" << endl;
+    return 1;
+  }
+
+  if (fake_writes && logfiles.empty()) {
+    cerr << "[ERROR] --log-fake-writes specified without logging enabled" << endl;
+    return 1;
+  }
+
+  if (nofsync && logfiles.empty()) {
+    cerr << "[ERROR] --log-nofsync specified without logging enabled" << endl;
+    return 1;
+  }
+
+  if (fake_writes && nofsync) {
+    cerr << "[WARNING] --log-nofsync has no effect with --log-fake-writes enabled" << endl;
+  }
+
+#ifndef ENABLE_EVENT_COUNTERS
+  if (!stats_server_sockfile.empty()) {
+    cerr << "[WARNING] --stats-server-sockfile with no event counters enabled is useless" << endl;
+  }
+#endif
+
+  // initialize the numa allocator
+  if (numa_memory > 0) {
+    const size_t maxpercpu = util::iceil(
+        numa_memory / nthreads, ::allocator::GetHugepageSize());
+    numa_memory = maxpercpu * nthreads;
+    ::allocator::Initialize(nthreads, maxpercpu);
+  }
+
+  const set<string> can_persist({"ndb-proto2"});
+  if (!logfiles.empty() && !can_persist.count(db_type)) {
+    cerr << "[ERROR] benchmark " << db_type
+         << " does not have persistence implemented" << endl;
+    return 1;
+  }
+
+#ifdef PROTO2_CAN_DISABLE_GC
+  const set<string> has_gc({"ndb-proto1", "ndb-proto2"});
+  if (disable_gc && !has_gc.count(db_type)) {
+    cerr << "[ERROR] benchmark " << db_type
+         << " does not have gc to disable" << endl;
+    return 1;
+  }
+#else
+  if (disable_gc) {
+    cerr << "[ERROR] macro PROTO2_CAN_DISABLE_GC was not set, cannot disable gc" << endl;
+    return 1;
+  }
+#endif
+
+#ifdef PROTO2_CAN_DISABLE_SNAPSHOTS
+  const set<string> has_snapshots({"ndb-proto2"});
+  if (disable_snapshots && !has_snapshots.count(db_type)) {
+    cerr << "[ERROR] benchmark " << db_type
+         << " does not have snapshots to disable" << endl;
+    return 1;
+  }
+#else
+  if (disable_snapshots) {
+    cerr << "[ERROR] macro PROTO2_CAN_DISABLE_SNAPSHOTS was not set, cannot disable snapshots" << endl;
+    return 1;
+  }
+#endif
+
+  if (db_type == "bdb") {
+    const string cmd = "rm -rf " + basedir + "/db/*";
+    // XXX(stephentu): laziness
+    int ret UNUSED = system(cmd.c_str());
+    db = new bdb_wrapper("db", bench_type + ".db");
+  } else if (db_type == "ndb-proto1") {
+    // XXX: hacky simulation of proto1
+    db = new ndb_wrapper<transaction_proto2>(
+        logfiles, assignments, !nofsync, do_compress, fake_writes);
+    transaction_proto2_static::set_hack_status(true);
+    ALWAYS_ASSERT(transaction_proto2_static::get_hack_status());
+#ifdef PROTO2_CAN_DISABLE_GC
+    if (!disable_gc)
+      transaction_proto2_static::InitGC();
+#endif
+  } else if (db_type == "ndb-proto2") {
+    db = new ndb_wrapper<transaction_proto2>(
+        logfiles, assignments, !nofsync, do_compress, fake_writes);
+    ALWAYS_ASSERT(!transaction_proto2_static::get_hack_status());
+#ifdef PROTO2_CAN_DISABLE_GC
+    if (!disable_gc)
+      transaction_proto2_static::InitGC();
+#endif
+#ifdef PROTO2_CAN_DISABLE_SNAPSHOTS
+    if (disable_snapshots)
+      transaction_proto2_static::DisableSnapshots();
+#endif
+  } else if (db_type == "kvdb") {
+    db = new kvdb_wrapper<true>;
+  } else if (db_type == "kvdb-st") {
+    db = new kvdb_wrapper<false>;
+#if !NO_MYSQL
+  } else if (db_type == "mysql") {
+    string dbdir = basedir + "/mysql-db";
+    db = new mysql_wrapper(dbdir, bench_type);
+#endif
+  } else
+    ALWAYS_ASSERT(false);
+
+#ifdef DEBUG
+  cerr << "WARNING: benchmark built in DEBUG mode!!!" << endl;
+#endif
+
+#ifdef CHECK_INVARIANTS
+  cerr << "WARNING: invariant checking is enabled - should disable for benchmark" << endl;
+#ifdef PARANOID_CHECKING
+  cerr << "  *** Paranoid checking is enabled ***" << endl;
+#endif
+#endif
+
+  if (verbose) {
+    const unsigned long ncpus = coreid::num_cpus_online();
+    cerr << "Database Benchmark:"                           << endl;
+    cerr << "  pid: " << getpid()                           << endl;
+    cerr << "settings:"                                     << endl;
+    cerr << "  par-loading : " << enable_parallel_loading   << endl;
+    cerr << "  pin-cpus    : " << pin_cpus                  << endl;
+    cerr << "  slow-exit   : " << slow_exit                 << endl;
+    cerr << "  retry-txns  : " << retry_aborted_transaction << endl;
+    cerr << "  backoff-txns: " << backoff_aborted_transaction << endl;
+    cerr << "  bench       : " << bench_type                << endl;
+    cerr << "  scale       : " << scale_factor              << endl;
+    cerr << "  num-cpus    : " << ncpus                     << endl;
+    cerr << "  num-threads : " << nthreads                  << endl;
+    cerr << "  db-type     : " << db_type                   << endl;
+    cerr << "  basedir     : " << basedir                   << endl;
+    cerr << "  txn-flags   : " << hexify(txn_flags)         << endl;
+    if (run_mode == RUNMODE_TIME)
+      cerr << "  runtime     : " << runtime                 << endl;
+    else
+      cerr << "  ops/worker  : " << ops_per_worker          << endl;
+#ifdef USE_VARINT_ENCODING
+    cerr << "  var-encode  : yes"                           << endl;
+#else
+    cerr << "  var-encode  : no"                            << endl;
+#endif
+
+#ifdef USE_JEMALLOC
+    cerr << "  allocator   : jemalloc"                      << endl;
+#elif defined USE_TCMALLOC
+    cerr << "  allocator   : tcmalloc"                      << endl;
+#elif defined USE_FLOW
+    cerr << "  allocator   : flow"                          << endl;
+#else
+    cerr << "  allocator   : libc"                          << endl;
+#endif
+    if (numa_memory > 0) {
+      cerr << "  numa-memory : " << numa_memory             << endl;
+    } else {
+      cerr << "  numa-memory : disabled"                    << endl;
+    }
+    cerr << "  logfiles : " << logfiles                     << endl;
+    cerr << "  assignments : " << assignments               << endl;
+    cerr << "  disable-gc : " << disable_gc                 << endl;
+    cerr << "  disable-snapshots : " << disable_snapshots   << endl;
+    cerr << "  stats-server-sockfile: " << stats_server_sockfile << endl;
+
+    cerr << "system properties:" << endl;
+    cerr << "  btree_internal_node_size: " << concurrent_btree::InternalNodeSize() << endl;
+    cerr << "  btree_leaf_node_size    : " << concurrent_btree::LeafNodeSize() << endl;
+
+#ifdef TUPLE_PREFETCH
+    cerr << "  tuple_prefetch          : yes" << endl;
+#else
+    cerr << "  tuple_prefetch          : no" << endl;
+#endif
+
+#ifdef BTREE_NODE_PREFETCH
+    cerr << "  btree_node_prefetch     : yes" << endl;
+#else
+    cerr << "  btree_node_prefetch     : no" << endl;
+#endif
+
+  }
+
+  if (!stats_server_sockfile.empty()) {
+    stats_server *srvr = new stats_server(stats_server_sockfile);
+    thread(&stats_server::serve_forever, srvr).detach();
+  }
+
+  vector<string> bench_toks = split_ws(bench_opts);
+  int argc = 1 + bench_toks.size();
+  char *argv[argc];
+  argv[0] = (char *) bench_type.c_str();
+  for (size_t i = 1; i <= bench_toks.size(); i++)
+    argv[i] = (char *) bench_toks[i - 1].c_str();
+  test_fn(db, argc, argv);
+  delete db;
+  return 0;
+}
diff --git a/silo/benchmarks/encstress.cc b/silo/benchmarks/encstress.cc
new file mode 100644 (file)
index 0000000..7b5577a
--- /dev/null
@@ -0,0 +1,180 @@
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <utility>
+#include <string>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../macros.h"
+#include "../varkey.h"
+#include "../thread.h"
+#include "../util.h"
+#include "../spinbarrier.h"
+
+#include "../record/encoder.h"
+#include "bench.h"
+
+using namespace std;
+using namespace util;
+
+static size_t nkeys;
+
+#define ENCSTRESS_REC_KEY_FIELDS(x, y) \
+  x(int32_t,k0)
+#define ENCSTRESS_REC_VALUE_FIELDS(x, y) \
+  x(int32_t,f0) \
+  y(int32_t,f1) \
+  y(int32_t,f2) \
+  y(int32_t,f3) \
+  y(int32_t,f4) \
+  y(int32_t,f5) \
+  y(int32_t,f6) \
+  y(int32_t,f7)
+DO_STRUCT(encstress_rec, ENCSTRESS_REC_KEY_FIELDS, ENCSTRESS_REC_VALUE_FIELDS)
+
+class encstress_worker : public bench_worker {
+public:
+  encstress_worker(
+      unsigned int worker_id,
+      unsigned long seed, abstract_db *db,
+      const map<string, abstract_ordered_index *> &open_tables,
+      spin_barrier *barrier_a, spin_barrier *barrier_b)
+    : bench_worker(worker_id, false, seed, db,
+                   open_tables, barrier_a, barrier_b),
+      tbl(open_tables.at("table"))
+  {
+  }
+
+  txn_result
+  txn_read()
+  {
+    void *txn = db->new_txn(txn_flags, arena, txn_buf());
+    const string k = u64_varkey(r.next() % nkeys).str();
+    try {
+      string v;
+      ALWAYS_ASSERT(tbl->get(txn, k, v));
+      if (likely(db->commit_txn(txn)))
+        return txn_result(true, 0);
+    } catch (abstract_db::abstract_abort_exception &ex) {
+      db->abort_txn(txn);
+    }
+    return txn_result(false, 0);
+  }
+
+  static txn_result
+  TxnRead(bench_worker *w)
+  {
+    return static_cast<encstress_worker *>(w)->txn_read();
+  }
+
+  virtual workload_desc_vec
+  get_workload() const
+  {
+    workload_desc_vec w;
+    w.push_back(workload_desc("Read", 1.0, TxnRead));
+    return w;
+  }
+
+private:
+  abstract_ordered_index *tbl;
+};
+
+class encstress_loader : public bench_loader {
+public:
+  encstress_loader(unsigned long seed,
+                   abstract_db *db,
+                   const map<string, abstract_ordered_index *> &open_tables)
+    : bench_loader(seed, db, open_tables)
+  {}
+
+protected:
+  virtual void
+  load()
+  {
+    abstract_ordered_index *tbl = open_tables.at("table");
+    try {
+      // load
+      const size_t batchsize = (db->txn_max_batch_size() == -1) ?
+        10000 : db->txn_max_batch_size();
+      ALWAYS_ASSERT(batchsize > 0);
+      const size_t nbatches = nkeys / batchsize;
+      if (nbatches == 0) {
+        void *txn = db->new_txn(txn_flags, arena, txn_buf());
+        for (size_t j = 0; j < nkeys; j++) {
+          const encstress_rec::key key(j);
+          encstress_rec::value rec;
+          rec.f0 = 1; rec.f1 = 1; rec.f2 = 1; rec.f3 = 1;
+          rec.f4 = 1; rec.f5 = 1; rec.f6 = 1; rec.f7 = 1;
+          string buf;
+          tbl->insert(txn, Encode(key), Encode(buf, rec));
+        }
+        if (verbose)
+          cerr << "batch 1/1 done" << endl;
+        ALWAYS_ASSERT(db->commit_txn(txn));
+      } else {
+        for (size_t i = 0; i < nbatches; i++) {
+          size_t keyend = (i == nbatches - 1) ? nkeys : (i + 1) * batchsize;
+          void *txn = db->new_txn(txn_flags, arena, txn_buf());
+          for (size_t j = i * batchsize; j < keyend; j++) {
+            const encstress_rec::key key(j);
+            encstress_rec::value rec;
+            rec.f0 = 1; rec.f1 = 1; rec.f2 = 1; rec.f3 = 1;
+            rec.f4 = 1; rec.f5 = 1; rec.f6 = 1; rec.f7 = 1;
+            string buf;
+            tbl->insert(txn, Encode(key), Encode(buf, rec));
+          }
+          if (verbose)
+            cerr << "batch " << (i + 1) << "/" << nbatches << " done" << endl;
+          ALWAYS_ASSERT(db->commit_txn(txn));
+        }
+      }
+    } catch (abstract_db::abstract_abort_exception &ex) {
+      // shouldn't abort on loading!
+      ALWAYS_ASSERT(false);
+    }
+    if (verbose)
+      cerr << "[INFO] finished loading USERTABLE" << endl;
+  }
+};
+
+class encstress_bench_runner : public bench_runner {
+public:
+  encstress_bench_runner(abstract_db *db)
+    : bench_runner(db)
+  {
+    open_tables["table"] = db->open_index("table", sizeof(encstress_rec));
+  }
+
+protected:
+  virtual vector<bench_loader *>
+  make_loaders()
+  {
+    vector<bench_loader *> ret;
+    ret.push_back(new encstress_loader(0, db, open_tables));
+    return ret;
+  }
+
+  virtual vector<bench_worker *>
+  make_workers()
+  {
+    fast_random r(8544290);
+    vector<bench_worker *> ret;
+    for (size_t i = 0; i < nthreads; i++)
+      ret.push_back(
+        new encstress_worker(
+          i, r.next(), db, open_tables,
+          &barrier_a, &barrier_b));
+    return ret;
+  }
+};
+
+void
+encstress_do_test(abstract_db *db, int argc, char **argv)
+{
+  nkeys = size_t(scale_factor * 1000.0);
+  ALWAYS_ASSERT(nkeys > 0);
+  encstress_bench_runner r(db);
+  r.run();
+}
diff --git a/silo/benchmarks/gc_runner.sh b/silo/benchmarks/gc_runner.sh
new file mode 100755 (executable)
index 0000000..3b5aa42
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+set -x
+
+BENCH=./dbtest
+NTHREADS=28
+PREFIX=$1
+YCSB_MEM=`python -c "print int(100+1.4*$NTHREADS)"`
+
+$BENCH \
+  --verbose \
+  --bench ycsb \
+  --db-type ndb-proto2 \
+  --scale-factor 320000 \
+  --num-threads $NTHREADS \
+  --bench-opts '--workload-mix 80,0,20,0' \
+  --numa-memory ${YCSB_MEM}G \
+  --parallel-loading \
+  --runtime 60 \
+  --slow-exit 2>&1 | grep chain_ > results/$PREFIX-ycsb-chains.txt
+
+$BENCH \
+  --verbose \
+  --bench tpcc \
+  --db-type ndb-proto2 \
+  --scale-factor $NTHREADS \
+  --num-threads $NTHREADS \
+  --numa-memory $((4 * $NTHREADS))G \
+  --parallel-loading \
+  --runtime 60 \
+  --slow-exit 2>&1 | grep chain_ > results/$PREFIX-tpcc-chains.txt
diff --git a/silo/benchmarks/kvdb_wrapper.h b/silo/benchmarks/kvdb_wrapper.h
new file mode 100644 (file)
index 0000000..b2a4fdd
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef _KVDB_WRAPPER_H_
+#define _KVDB_WRAPPER_H_
+
+#include "abstract_db.h"
+#include "../btree_choice.h"
+#include "../rcu.h"
+
+template <bool UseConcurrencyControl>
+class kvdb_wrapper : public abstract_db {
+public:
+
+  virtual ssize_t txn_max_batch_size() const OVERRIDE { return 100; }
+
+  virtual void do_txn_epoch_sync() const { }
+
+  virtual void do_txn_finish() const { }
+
+  virtual size_t
+  sizeof_txn_object(uint64_t txn_flags) const
+  {
+    return sizeof(scoped_rcu_region);
+  }
+
+  virtual void *
+  new_txn(uint64_t txn_flags, str_arena &arena, void *buf, TxnProfileHint hint)
+  {
+    return new (buf) scoped_rcu_region;
+  }
+
+  virtual bool
+  commit_txn(void *txn)
+  {
+    ((scoped_rcu_region *) txn)->~scoped_rcu_region();
+    return true;
+  }
+
+  virtual void abort_txn(void *txn) { ALWAYS_ASSERT(false); } // txn should never abort
+  virtual void print_txn_debug(void *txn) const { }
+
+  virtual abstract_ordered_index *
+  open_index(const std::string &name,
+             size_t value_size_hint,
+             bool mostly_append);
+
+  virtual void
+  close_index(abstract_ordered_index *idx)
+  {
+    delete idx;
+  }
+};
+
+template <bool UseConcurrencyControl>
+class kvdb_ordered_index : public abstract_ordered_index {
+public:
+  kvdb_ordered_index(const std::string &name)
+    : name(name) {}
+  virtual bool get(
+      void *txn,
+      const std::string &key,
+      std::string &value, size_t max_bytes_read);
+  virtual const char * put(
+      void *txn,
+      const std::string &key,
+      const std::string &value);
+  virtual const char *
+  insert(void *txn,
+         const std::string &key,
+         const std::string &value);
+  virtual void scan(
+      void *txn,
+      const std::string &start_key,
+      const std::string *end_key,
+      scan_callback &callback,
+      str_arena *arena);
+  virtual void rscan(
+      void *txn,
+      const std::string &start_key,
+      const std::string *end_key,
+      scan_callback &callback,
+      str_arena *arena);
+  virtual void remove(
+      void *txn,
+      const std::string &key);
+  virtual size_t size() const;
+  virtual std::map<std::string, uint64_t> clear();
+private:
+  std::string name;
+  typedef
+    typename std::conditional<
+      UseConcurrencyControl,
+      concurrent_btree,
+      single_threaded_btree>::type
+    my_btree;
+  typedef typename my_btree::key_type key_type;
+  my_btree btr;
+};
+
+#endif /* _KVDB_WRAPPER_H_ */
diff --git a/silo/benchmarks/kvdb_wrapper_impl.h b/silo/benchmarks/kvdb_wrapper_impl.h
new file mode 100644 (file)
index 0000000..315ea88
--- /dev/null
@@ -0,0 +1,558 @@
+#ifndef _KVDB_WRAPPER_IMPL_H_
+#define _KVDB_WRAPPER_IMPL_H_
+
+#include <vector>
+#include <limits>
+#include <utility>
+
+#include "kvdb_wrapper.h"
+#include "../varint.h"
+#include "../macros.h"
+#include "../util.h"
+#include "../amd64.h"
+#include "../lockguard.h"
+#include "../prefetch.h"
+#include "../scopedperf.hh"
+#include "../counter.h"
+
+namespace private_ {
+  static event_avg_counter evt_avg_kvdb_stable_version_spins("avg_kvdb_stable_version_spins");
+  static event_avg_counter evt_avg_kvdb_lock_acquire_spins("avg_kvdb_lock_acquire_spins");
+  static event_avg_counter evt_avg_kvdb_read_retries("avg_kvdb_read_retries");
+
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, kvdb_get_probe0, kvdb_get_probe0_cg);
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, kvdb_get_probe1, kvdb_get_probe1_cg);
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, kvdb_put_probe0, kvdb_put_probe0_cg);
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, kvdb_insert_probe0, kvdb_insert_probe0_cg);
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, kvdb_scan_probe0, kvdb_scan_probe0_cg);
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, kvdb_remove_probe0, kvdb_remove_probe0_cg);
+}
+
+// defines single-threaded version
+template <bool UseConcurrencyControl>
+struct record_version {
+  uint16_t sz;
+
+  inline ALWAYS_INLINE bool
+  is_locked() const
+  {
+    return false;
+  }
+
+  inline ALWAYS_INLINE void lock() {}
+
+  inline ALWAYS_INLINE void unlock() {}
+
+  static inline ALWAYS_INLINE size_t
+  Size(uint32_t v)
+  {
+    return 0;
+  }
+
+  inline ALWAYS_INLINE size_t
+  size() const
+  {
+    return sz;
+  }
+
+  inline ALWAYS_INLINE void
+  set_size(size_t s)
+  {
+    INVARIANT(s <= std::numeric_limits<uint16_t>::max());
+    sz = s;
+  }
+
+  inline ALWAYS_INLINE uint32_t
+  stable_version() const
+  {
+    return 0;
+  }
+
+  inline ALWAYS_INLINE bool
+  check_version(uint32_t version) const
+  {
+    return true;
+  }
+};
+
+// concurrency control version
+template <>
+struct record_version<true> {
+  // [ locked | size  | version ]
+  // [  0..1  | 1..17 | 17..32  ]
+
+  static const uint32_t HDR_LOCKED_MASK = 0x1;
+
+  static const uint32_t HDR_SIZE_SHIFT = 1;
+  static const uint32_t HDR_SIZE_MASK = std::numeric_limits<uint16_t>::max() << HDR_SIZE_SHIFT;
+
+  static const uint32_t HDR_VERSION_SHIFT = 17;
+  static const uint32_t HDR_VERSION_MASK = ((uint32_t)-1) << HDR_VERSION_SHIFT;
+
+  record_version<true>() : hdr(0) {}
+
+  volatile uint32_t hdr;
+
+  static inline bool
+  IsLocked(uint32_t v)
+  {
+    return v & HDR_LOCKED_MASK;
+  }
+
+  inline bool
+  is_locked() const
+  {
+    return IsLocked(hdr);
+  }
+
+  inline void
+  lock()
+  {
+#ifdef ENABLE_EVENT_COUNTERS
+    unsigned long nspins = 0;
+#endif
+    uint32_t v = hdr;
+    while (IsLocked(v) ||
+           !__sync_bool_compare_and_swap(&hdr, v, v | HDR_LOCKED_MASK)) {
+      nop_pause();
+      v = hdr;
+#ifdef ENABLE_EVENT_COUNTERS
+      ++nspins;
+#endif
+    }
+    COMPILER_MEMORY_FENCE;
+#ifdef ENABLE_EVENT_COUNTERS
+    private_::evt_avg_kvdb_lock_acquire_spins.offer(nspins);
+#endif
+  }
+
+  inline void
+  unlock()
+  {
+    uint32_t v = hdr;
+    INVARIANT(IsLocked(v));
+    const uint32_t n = Version(v);
+    v &= ~HDR_VERSION_MASK;
+    v |= (((n + 1) << HDR_VERSION_SHIFT) & HDR_VERSION_MASK);
+    v &= ~HDR_LOCKED_MASK;
+    INVARIANT(!IsLocked(v));
+    COMPILER_MEMORY_FENCE;
+    hdr = v;
+  }
+
+  static inline size_t
+  Size(uint32_t v)
+  {
+    return (v & HDR_SIZE_MASK) >> HDR_SIZE_SHIFT;
+  }
+
+  inline size_t
+  size() const
+  {
+    return Size(hdr);
+  }
+
+  inline void
+  set_size(size_t s)
+  {
+    INVARIANT(s <= std::numeric_limits<uint16_t>::max());
+    INVARIANT(is_locked());
+    const uint16_t new_sz = static_cast<uint16_t>(s);
+    hdr &= ~HDR_SIZE_MASK;
+    hdr |= (new_sz << HDR_SIZE_SHIFT);
+    INVARIANT(size() == s);
+  }
+
+  static inline uint32_t
+  Version(uint32_t v)
+  {
+    return (v & HDR_VERSION_MASK) >> HDR_VERSION_SHIFT;
+  }
+
+  inline uint32_t
+  stable_version() const
+  {
+    uint32_t v = hdr;
+#ifdef ENABLE_EVENT_COUNTERS
+    unsigned long nspins = 0;
+#endif
+    while (IsLocked(v)) {
+      nop_pause();
+      v = hdr;
+#ifdef ENABLE_EVENT_COUNTERS
+      ++nspins;
+#endif
+    }
+    COMPILER_MEMORY_FENCE;
+#ifdef ENABLE_EVENT_COUNTERS
+    private_::evt_avg_kvdb_stable_version_spins.offer(nspins);
+#endif
+    return v;
+  }
+
+  inline bool
+  check_version(uint32_t version) const
+  {
+    COMPILER_MEMORY_FENCE;
+    return hdr == version;
+  }
+};
+
+template <bool UseConcurrencyControl>
+struct basic_kvdb_record : public record_version<UseConcurrencyControl> {
+  typedef record_version<UseConcurrencyControl> super_type;
+  uint16_t alloc_size;
+  char data[0];
+
+  basic_kvdb_record(uint16_t alloc_size, const std::string &s)
+    : record_version<UseConcurrencyControl>(),
+      alloc_size(alloc_size)
+  {
+#ifdef CHECK_INVARIANTS
+    this->lock();
+    this->set_size(s.size());
+    do_write(s);
+    this->unlock();
+#else
+    this->set_size(s.size());
+    do_write(s);
+#endif
+  }
+
+  inline void
+  prefetch() const
+  {
+#ifdef PREFETCH
+    prefetch_bytes(this, sizeof(*this) + size());
+#endif
+  }
+
+  inline void
+  do_read(std::string &s, size_t max_bytes_read) const
+  {
+    if (UseConcurrencyControl) {
+#ifdef ENABLE_EVENT_COUNTERS
+      unsigned long nretries = 0;
+#endif
+    retry:
+      const uint32_t v = this->stable_version();
+      const size_t sz = std::min(super_type::Size(v), max_bytes_read);
+      s.assign(&data[0], sz);
+      if (unlikely(!this->check_version(v))) {
+#ifdef ENABLE_EVENT_COUNTERS
+        ++nretries;
+#endif
+        goto retry;
+      }
+#ifdef ENABLE_EVENT_COUNTERS
+      private_::evt_avg_kvdb_read_retries.offer(nretries);
+#endif
+    } else {
+      const size_t sz = std::min(this->size(), max_bytes_read);
+      s.assign(&data[0], sz);
+    }
+  }
+
+  inline bool
+  do_write(const std::string &s)
+  {
+    INVARIANT(!UseConcurrencyControl || this->is_locked());
+    if (unlikely(s.size() > alloc_size))
+      return false;
+    this->set_size(s.size());
+    NDB_MEMCPY(&data[0], s.data(), s.size());
+    return true;
+  }
+
+  static basic_kvdb_record *
+  alloc(const std::string &s)
+  {
+    const size_t sz = s.size();
+    const size_t max_alloc_sz =
+      std::numeric_limits<uint16_t>::max() + sizeof(basic_kvdb_record);
+    const size_t alloc_sz =
+      std::min(
+          util::round_up<size_t, allocator::LgAllocAlignment>(sizeof(basic_kvdb_record) + sz),
+          max_alloc_sz);
+    char * const p = reinterpret_cast<char *>(rcu::s_instance.alloc(alloc_sz));
+    INVARIANT(p);
+    return new (p) basic_kvdb_record(alloc_sz - sizeof(basic_kvdb_record), s);
+  }
+
+private:
+  static inline void
+  deleter(void *r)
+  {
+    basic_kvdb_record * const px =
+      reinterpret_cast<basic_kvdb_record *>(r);
+    const size_t alloc_sz = px->alloc_size + sizeof(*px);
+    px->~basic_kvdb_record();
+    rcu::s_instance.dealloc(px, alloc_sz);
+  }
+
+public:
+  static void
+  release(basic_kvdb_record *r)
+  {
+    if (unlikely(!r))
+      return;
+    rcu::s_instance.free_with_fn(r, deleter);
+  }
+
+  static void
+  release_no_rcu(basic_kvdb_record *r)
+  {
+    if (unlikely(!r))
+      return;
+    deleter(r);
+  }
+
+} PACKED;
+
+template <bool UseConcurrencyControl>
+bool
+kvdb_ordered_index<UseConcurrencyControl>::get(
+    void *txn,
+    const std::string &key,
+    std::string &value, size_t max_bytes_read)
+{
+  typedef basic_kvdb_record<UseConcurrencyControl> kvdb_record;
+  ANON_REGION("kvdb_ordered_index::get:", &private_::kvdb_get_probe0_cg);
+  typename my_btree::value_type v = 0;
+  if (btr.search(varkey(key), v)) {
+    ANON_REGION("kvdb_ordered_index::get:do_read:", &private_::kvdb_get_probe1_cg);
+    const kvdb_record * const r = (const kvdb_record *) v;
+    r->prefetch();
+    r->do_read(value, max_bytes_read);
+    return true;
+  }
+  return false;
+}
+
+template <bool UseConcurrencyControl>
+const char *
+kvdb_ordered_index<UseConcurrencyControl>::put(
+    void *txn,
+    const std::string &key,
+    const std::string &value)
+{
+  typedef basic_kvdb_record<UseConcurrencyControl> kvdb_record;
+  ANON_REGION("kvdb_ordered_index::put:", &private_::kvdb_put_probe0_cg);
+  typename my_btree::value_type v = 0, v_old = 0;
+  if (btr.search(varkey(key), v)) {
+    // easy
+    kvdb_record * const r = (kvdb_record *) v;
+    r->prefetch();
+    lock_guard<kvdb_record> guard(*r);
+    if (r->do_write(value))
+      return 0;
+    // replace
+    kvdb_record * const rnew = kvdb_record::alloc(value);
+    btr.insert(varkey(key), (typename my_btree::value_type) rnew, &v_old, 0);
+    INVARIANT((typename my_btree::value_type) r == v_old);
+    // rcu-free the old record
+    kvdb_record::release(r);
+    return 0;
+  }
+  kvdb_record * const rnew = kvdb_record::alloc(value);
+  if (!btr.insert(varkey(key), (typename my_btree::value_type) rnew, &v_old, 0)) {
+    kvdb_record * const r = (kvdb_record *) v_old;
+    kvdb_record::release(r);
+  }
+  return 0;
+}
+
+template <bool UseConcurrencyControl>
+const char *
+kvdb_ordered_index<UseConcurrencyControl>::insert(void *txn,
+                           const std::string &key,
+                           const std::string &value)
+{
+  typedef basic_kvdb_record<UseConcurrencyControl> kvdb_record;
+  ANON_REGION("kvdb_ordered_index::insert:", &private_::kvdb_insert_probe0_cg);
+  kvdb_record * const rnew = kvdb_record::alloc(value);
+  typename my_btree::value_type v_old = 0;
+  if (!btr.insert(varkey(key), (typename my_btree::value_type) rnew, &v_old, 0)) {
+    kvdb_record * const r = (kvdb_record *) v_old;
+    kvdb_record::release(r);
+  }
+  return 0;
+}
+
+template <typename Btree, bool UseConcurrencyControl>
+class kvdb_wrapper_search_range_callback : public Btree::search_range_callback {
+public:
+  typedef basic_kvdb_record<UseConcurrencyControl> kvdb_record;
+  kvdb_wrapper_search_range_callback(
+      abstract_ordered_index::scan_callback &upcall,
+      str_arena *arena)
+    : upcall(&upcall), arena(arena) {}
+
+  virtual bool
+  invoke(const typename Btree::string_type &k, typename Btree::value_type v)
+  {
+    const kvdb_record * const r = (const kvdb_record *) v;
+    std::string * const s_px = likely(arena) ? arena->next() : nullptr;
+    INVARIANT(s_px && s_px->empty());
+    r->prefetch();
+    r->do_read(*s_px, std::numeric_limits<size_t>::max());
+    return upcall->invoke(k.data(), k.length(), *s_px);
+  }
+
+private:
+  abstract_ordered_index::scan_callback *upcall;
+  str_arena *arena;
+};
+
+template <bool UseConcurrencyControl>
+void
+kvdb_ordered_index<UseConcurrencyControl>::scan(
+    void *txn,
+    const std::string &start_key,
+    const std::string *end_key,
+    scan_callback &callback,
+    str_arena *arena)
+{
+  ANON_REGION("kvdb_ordered_index::scan:", &private_::kvdb_scan_probe0_cg);
+  kvdb_wrapper_search_range_callback<my_btree, UseConcurrencyControl> c(callback, arena);
+  key_type end(end_key ? key_type(*end_key) : key_type());
+  btr.search_range_call(key_type(start_key), end_key ? &end : 0, c, arena->next());
+}
+
+template <bool UseConcurrencyControl>
+void
+kvdb_ordered_index<UseConcurrencyControl>::rscan(
+    void *txn,
+    const std::string &start_key,
+    const std::string *end_key,
+    scan_callback &callback,
+    str_arena *arena)
+{
+  ANON_REGION("kvdb_ordered_index::rscan:", &private_::kvdb_scan_probe0_cg);
+  kvdb_wrapper_search_range_callback<my_btree, UseConcurrencyControl> c(callback, arena);
+  key_type end(end_key ? key_type(*end_key) : key_type());
+  btr.rsearch_range_call(key_type(start_key), end_key ? &end : 0, c, arena->next());
+}
+
+template <bool UseConcurrencyControl>
+void
+kvdb_ordered_index<UseConcurrencyControl>::remove(void *txn, const std::string &key)
+{
+  typedef basic_kvdb_record<UseConcurrencyControl> kvdb_record;
+  ANON_REGION("kvdb_ordered_index::remove:", &private_::kvdb_remove_probe0_cg);
+  typename my_btree::value_type v = 0;
+  if (btr.remove(varkey(key), &v)) {
+    kvdb_record * const r = (kvdb_record *) v;
+    kvdb_record::release(r);
+  }
+}
+
+template <bool UseConcurrencyControl>
+size_t
+kvdb_ordered_index<UseConcurrencyControl>::size() const
+{
+  return btr.size();
+}
+
+template <typename Btree, bool UseConcurrencyControl>
+struct purge_tree_walker : public Btree::tree_walk_callback {
+  typedef basic_kvdb_record<UseConcurrencyControl> kvdb_record;
+
+#ifdef TXN_BTREE_DUMP_PURGE_STATS
+  purge_tree_walker()
+    : purge_stats_nodes(0),
+      purge_stats_nosuffix_nodes(0) {}
+  std::map<size_t, size_t> purge_stats_record_size_counts; // just the record
+  std::map<size_t, size_t> purge_stats_alloc_size_counts; // includes overhead
+  std::vector<uint16_t> purge_stats_nkeys_node;
+  size_t purge_stats_nodes;
+  size_t purge_stats_nosuffix_nodes;
+
+  void
+  dump_stats()
+  {
+    size_t v = 0;
+    for (std::vector<uint16_t>::iterator it = purge_stats_nkeys_node.begin();
+        it != purge_stats_nkeys_node.end(); ++it)
+      v += *it;
+    const double avg_nkeys_node = double(v)/double(purge_stats_nkeys_node.size());
+    const double avg_fill_factor = avg_nkeys_node/double(Btree::NKeysPerNode);
+    std::cerr << "btree node stats" << std::endl;
+    std::cerr << "    avg_nkeys_node: " << avg_nkeys_node << std::endl;
+    std::cerr << "    avg_fill_factor: " << avg_fill_factor << std::endl;
+    std::cerr << "    num_nodes: " << purge_stats_nodes << std::endl;
+    std::cerr << "    num_nosuffix_nodes: " << purge_stats_nosuffix_nodes << std::endl;
+    std::cerr << "record size stats (nbytes => count)" << std::endl;
+    for (std::map<size_t, size_t>::iterator it = purge_stats_record_size_counts.begin();
+        it != purge_stats_record_size_counts.end(); ++it)
+      std::cerr << "    " << it->first << " => " << it->second << std::endl;
+    std::cerr << "alloc size stats  (nbytes => count)" << std::endl;
+    for (std::map<size_t, size_t>::iterator it = purge_stats_alloc_size_counts.begin();
+        it != purge_stats_alloc_size_counts.end(); ++it)
+      std::cerr << "    " << (it->first + sizeof(kvdb_record)) << " => " << it->second << std::endl;
+  }
+#endif
+
+  virtual void
+  on_node_begin(const typename Btree::node_opaque_t *n)
+  {
+    INVARIANT(spec_values.empty());
+    spec_values = Btree::ExtractValues(n);
+  }
+
+  virtual void
+  on_node_success()
+  {
+    for (size_t i = 0; i < spec_values.size(); i++) {
+      kvdb_record * const r = (kvdb_record *) spec_values[i].first;
+      purge_stats_record_size_counts[r->size()]++;
+      purge_stats_alloc_size_counts[r->alloc_size]++;
+      kvdb_record::release_no_rcu(r);
+    }
+#ifdef TXN_BTREE_DUMP_PURGE_STATS
+    purge_stats_nkeys_node.push_back(spec_values.size());
+    purge_stats_nodes++;
+    for (size_t i = 0; i < spec_values.size(); i++)
+      if (spec_values[i].second)
+        goto done;
+    purge_stats_nosuffix_nodes++;
+done:
+#endif
+    spec_values.clear();
+  }
+
+  virtual void
+  on_node_failure()
+  {
+    spec_values.clear();
+  }
+
+private:
+  std::vector<std::pair<typename Btree::value_type, bool>> spec_values;
+};
+
+template <bool UseConcurrencyControl>
+std::map<std::string, uint64_t>
+kvdb_ordered_index<UseConcurrencyControl>::clear()
+{
+
+  purge_tree_walker<my_btree, UseConcurrencyControl> w;
+  scoped_rcu_region guard;
+  btr.tree_walk(w);
+  btr.clear();
+#ifdef TXN_BTREE_DUMP_PURGE_STATS
+  std::cerr << "purging kvdb index: " << name << std::endl;
+  w.dump_stats();
+#endif
+  return std::map<std::string, uint64_t>();
+}
+
+template <bool UseConcurrencyControl>
+abstract_ordered_index *
+kvdb_wrapper<UseConcurrencyControl>::open_index(
+    const std::string &name, size_t value_size_hint, bool mostly_append)
+{
+  return new kvdb_ordered_index<UseConcurrencyControl>(name);
+}
+
+#endif /* _KVDB_WRAPPER_IMPL_H_ */
diff --git a/silo/benchmarks/masstree/README b/silo/benchmarks/masstree/README
new file mode 100644 (file)
index 0000000..b472995
--- /dev/null
@@ -0,0 +1,3 @@
+We strip out pieces of kvtest.hh that we need here- this is bad software
+engineering practice, since we really should make our btree implement the
+Client interface used in the masstree test code.
diff --git a/silo/benchmarks/masstree/kvrandom.cc b/silo/benchmarks/masstree/kvrandom.cc
new file mode 100644 (file)
index 0000000..13e9d69
--- /dev/null
@@ -0,0 +1,38 @@
+/* Masstree
+ * Eddie Kohler, Yandong Mao, Robert Morris
+ * Copyright (c) 2012 President and Fellows of Harvard College
+ * Copyright (c) 2012 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Masstree LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Masstree LICENSE file; the license in that file is
+ * legally binding.
+ */
+#include "kvrandom.hh"
+//#include "compiler.hh"
+#include <stdio.h>
+
+const uint32_t kvrandom_psdes_nr::c1[] = {
+    0xBAA96887U, 0x1E17D32CU, 0x03BCDC3CU, 0x0F33D1B2U
+};
+const uint32_t kvrandom_psdes_nr::c2[] = {
+    0x4B0F3B58U, 0xE874F0C3U, 0x6955C5A6U, 0x55A7CA46U
+};
+
+uint32_t kvrandom_psdes_nr::psdes(uint32_t lword, uint32_t irword) {
+    for (int i = 0; i < niter; ++i) {
+       uint32_t iswap = irword;
+       uint32_t ia = irword ^ c1[i];
+       uint32_t il = ia & 0xFFFF, ih = ia >> 16;
+       uint32_t ib = il * il + ~(ih * ih);
+       ia = (ib >> 16) | (ib << 16);
+       irword = lword ^ ((ia ^ c2[i]) + il * ih);
+       lword = iswap;
+    }
+    return irword;
+}
diff --git a/silo/benchmarks/masstree/kvrandom.hh b/silo/benchmarks/masstree/kvrandom.hh
new file mode 100644 (file)
index 0000000..4c6b3be
--- /dev/null
@@ -0,0 +1,100 @@
+/* Masstree
+ * Eddie Kohler, Yandong Mao, Robert Morris
+ * Copyright (c) 2012 President and Fellows of Harvard College
+ * Copyright (c) 2012 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Masstree LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Masstree LICENSE file; the license in that file is
+ * legally binding.
+ */
+#ifndef KVRANDOM_HH
+#define KVRANDOM_HH 1
+#include <inttypes.h>
+#include <stdlib.h>
+
+// A simple LCG with parameters from Numerical Recipes.
+class kvrandom_lcg_nr_simple { public:
+    enum { min_value = 0, max_value = 0xFFFFFFFFU };
+    typedef uint32_t value_type;
+    typedef uint32_t seed_type;
+    kvrandom_lcg_nr_simple()
+       : seed_(default_seed) {
+    }
+    explicit kvrandom_lcg_nr_simple(seed_type seed)
+       : seed_(seed) {
+    }
+    void reset(seed_type seed) {
+       seed_ = seed;
+    }
+    value_type next() {
+       return (seed_ = seed_ * a + c);
+    }
+  private:
+    uint32_t seed_;
+    enum { default_seed = 819234718U, a = 1664525U, c = 1013904223U };
+};
+
+// A combination version of the NR LCG that uses only its higher order
+// digits. (In the default NR LCG the lowest bits have less randomness; e.g.,
+// the low bit flips between 0 and 1 with every call.)
+class kvrandom_lcg_nr : public kvrandom_lcg_nr_simple { public:
+    enum { min_value = 0, max_value = 0x7FFFFFFF };
+    typedef int32_t value_type;
+    kvrandom_lcg_nr(seed_type seed) : kvrandom_lcg_nr_simple(seed) {}
+    value_type next() {
+       uint32_t x0 = kvrandom_lcg_nr_simple::next(),
+           x1 = kvrandom_lcg_nr_simple::next();
+       return (x0 >> 15) | ((x1 & 0x7FFE) << 16);
+    }
+};
+
+// A random number generator taken from NR's ran4. Based on hashing.
+class kvrandom_psdes_nr { public:
+    enum { min_value = 0, max_value = 0xFFFFFFFFU };
+    typedef uint32_t value_type;
+    typedef uint32_t seed_type;
+    kvrandom_psdes_nr() {
+       reset(1);
+    }
+    explicit kvrandom_psdes_nr(seed_type seed) {
+       reset(seed);
+    }
+    void reset(seed_type seed) {
+       seed_ = seed;
+       next_ = 1;
+    }
+    value_type next() {
+       uint32_t value = psdes(seed_, next_);
+       ++next_;
+       return value;
+    }
+    value_type operator[](uint32_t index) const {
+       return psdes(seed_, index);
+    }
+  private:
+    uint32_t seed_;
+    uint32_t next_;
+    enum { niter = 4 };
+    static const uint32_t c1[niter], c2[niter];
+    static uint32_t psdes(uint32_t lword, uint32_t irword);
+};
+
+// a wrapper around random(), for backwards compatibility
+class kvrandom_random { public:
+    kvrandom_random() {
+    }
+    void reset(uint32_t seed) {
+       srandom(seed);
+    }
+    int32_t next() const {
+       return random();
+    }
+};
+
+#endif
diff --git a/silo/benchmarks/masstree/kvtest.cc b/silo/benchmarks/masstree/kvtest.cc
new file mode 100644 (file)
index 0000000..f14f688
--- /dev/null
@@ -0,0 +1,179 @@
+#include <iostream>
+#include <vector>
+
+#include <unistd.h>
+
+#include "../../btree_choice.h"
+#include "../../thread.h"
+#include "../../spinbarrier.h"
+#include "../../varkey.h"
+#include "kvrandom.hh"
+
+using namespace std;
+using namespace util;
+
+struct quick_istr {
+private:
+  char buf_[32];
+  char *bbuf_;
+public:
+  inline quick_istr()
+  {
+    set(0);
+  }
+
+  inline quick_istr(unsigned long x, int minlen = 0)
+  {
+    set(x, minlen);
+  }
+
+  inline void
+  set(unsigned long x, int minlen = 0)
+  {
+    bbuf_ = buf_ + sizeof(buf_) - 1;
+    do {
+      *--bbuf_ = (x % 10) + '0';
+      x /= 10;
+    } while (--minlen > 0 || x != 0);
+  }
+
+  inline const char *
+  c_str()
+  {
+    buf_[sizeof(buf_) - 1] = 0;
+    return bbuf_;
+  }
+
+  inline const char *
+  data() const
+  {
+    return bbuf_;
+  }
+
+  inline size_t
+  size() const
+  {
+    return (buf_ + sizeof(buf_) - 1) - bbuf_;
+  }
+
+  inline varkey
+  key() const
+  {
+    return varkey((const uint8_t *) bbuf_, size());
+  }
+};
+
+template <typename T>
+class kvtest_worker : public ndb_thread {
+public:
+  kvtest_worker(btree &btr,
+                spin_barrier &b,
+                unsigned int id,
+                const volatile bool *phases)
+    : ndb_thread(false, string("kvtest-worker")),
+      btr(&btr), b(&b), id(id), phases(phases) {}
+
+  virtual void
+  run()
+  {
+    b->count_down();
+    b->wait_for();
+    T()(*btr, id, phases);
+  }
+
+private:
+  btree *btr;
+  spin_barrier *b;
+  unsigned int id;
+  const volatile bool *phases;
+};
+
+template <typename T>
+class kvtest_runner {
+public:
+  kvtest_runner(unsigned int nthreads)
+    : nthreads(nthreads) {}
+
+  void
+  go()
+  {
+    btree btr;
+    spin_barrier barrier(nthreads);
+    volatile bool phases[T::NPhases] = {0};
+    vector<kvtest_worker<T> *> workers;
+    for (unsigned int i = 0; i < nthreads; i++)
+      workers.push_back(new kvtest_worker<T>(btr, barrier, i, phases));
+    for (unsigned int i = 0; i < nthreads; i++)
+      workers[i]->start();
+    for (unsigned int i = 0; i < T::NPhases; i++) {
+      sleep(T::PhaseRuntimes[i]);
+      phases[i] = 1;
+      __sync_synchronize();
+    }
+    for (unsigned int i = 0; i < nthreads; i++) {
+      workers[i]->join();
+      delete workers[i];
+    }
+  }
+
+public:
+  unsigned int nthreads;
+};
+
+struct kvtest_rw1 {
+  static const size_t NPhases = 2;
+  static const unsigned long PhaseRuntimes[NPhases];
+
+  typedef kvrandom_lcg_nr rand_type;
+
+  void
+  operator()(btree &btr, unsigned int id, const volatile bool *phases) const
+  {
+    const int seed = 31949 + id % 48;
+    rand_type r(seed);
+    timer t;
+    unsigned n;
+    for (n = 0; !phases[0]; ++n) {
+      const int32_t x = (int32_t) r.next();
+      const quick_istr key(x), value(x + 1);
+      btree::value_type v = (btree::value_type) malloc(value.size());
+      NDB_MEMCPY(v, value.data(), value.size());
+      btr.insert(key.key(), v, 0, 0);
+    }
+    const double put_ms = t.lap_ms();
+    int32_t *a = (int32_t *) malloc(sizeof(int32_t) * n);
+    r.reset(seed);
+    for (unsigned i = 0; i < n; i++)
+      a[i] = (int32_t) r.next();
+    for (unsigned i = 0; i < n; ++i)
+      swap(a[i], a[r.next() % n]);
+
+    t.lap();
+    unsigned g;
+    for (g = 0; g < n && !phases[1]; ++g) {
+      const quick_istr key(a[g]), value(a[g] + 1);
+      btree::value_type v = 0;
+      ALWAYS_ASSERT(btr.search(key.key(), v));
+      ALWAYS_ASSERT(memcmp(value.data(), v, value.size()) == 0);
+    }
+    const double get_ms = t.lap_ms();
+
+    cout << "puts: " << n << ", rate: " << (double(n) / (put_ms / 1000.0)) << " ops/sec/core" << endl;
+    cout << "gets: " << g << ", rate: " << (double(g) / (get_ms / 1000.0)) << " ops/sec/core" << endl;
+
+    // XXX(stephentu): free btree values
+  }
+};
+
+const unsigned long kvtest_rw1::PhaseRuntimes[NPhases] = { 10, 10 }; // seconds
+
+int
+main(int argc, char **argv)
+{
+  ALWAYS_ASSERT(argc == 2);
+  int nthreads = atoi(argv[1]);
+  ALWAYS_ASSERT(nthreads > 0);
+  kvtest_runner<kvtest_rw1> r(nthreads);
+  r.go();
+  return 0;
+}
diff --git a/silo/benchmarks/mysql_wrapper.cc b/silo/benchmarks/mysql_wrapper.cc
new file mode 100644 (file)
index 0000000..f62293c
--- /dev/null
@@ -0,0 +1,255 @@
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <iostream>
+#include <sstream>
+
+#include "../macros.h"
+#include "mysql_wrapper.h"
+
+using namespace std;
+static bool embed_active = false;
+
+static inline void
+print_error_and_bail(MYSQL *conn)
+{
+  cerr << "mysql_error_message: " << mysql_error(conn) << endl;
+  ALWAYS_ASSERT(false);
+}
+
+static inline void
+check_result(MYSQL *conn, int result)
+{
+  if (likely(result == 0))
+    return;
+  print_error_and_bail(conn);
+}
+
+mysql_wrapper::mysql_wrapper(const string &dir, const string &db)
+  : db(db)
+{
+  struct stat st;
+  if (stat(dir.c_str(), &st) != 0) {
+    cerr << "ERROR! The db directory " << dir << " does not exist" << endl;
+    ALWAYS_ASSERT(false);
+  }
+
+  if (!__sync_bool_compare_and_swap(&embed_active, false, true)) {
+    cerr << "only one embedmysql object can exist at once" << endl;
+    ALWAYS_ASSERT(false);
+  }
+
+  char dir_arg[1024];
+  snprintf(dir_arg, sizeof(dir_arg), "--datadir=%s", dir.c_str());
+
+  /**
+       --innodb-buffer-pool-size=$SPACE
+       --innodb_log_file_size=1792M
+       --port=$PORT
+       --transaction_isolation=serializable
+       --max_connections=300
+       --local-infile=1
+       --max_allowed_packet=1073741824
+       --max_heap_table_size=2147483648
+       --group_concat_max_len=1073741824
+       --skip-slave-start
+       --innodb_flush_method=O_DIRECT
+       --log-error
+  */
+
+  const char *mysql_av[] =
+    {
+      "progname",
+      "--skip-grant-tables",
+      dir_arg,
+      "--character-set-server=utf8",
+      "--innodb-buffer-pool-size=4G", // XXX: don't hardocde
+      "--innodb_log_file_size=1792M", // max log file size
+      "--transaction_isolation=serializable",
+      "--innodb_flush_method=O_DIRECT",
+      "--innodb_flush_log_at_trx_commit=0", // only flush log once every second
+      "--sync_binlog=0",
+      "--language=" MYSQL_SHARE_DIR,
+    };
+
+  check_result(0, mysql_library_init(ARRAY_NELEMS(mysql_av), (char **) mysql_av, 0));
+
+  MYSQL *conn = new_connection("");
+  ostringstream b;
+  b << "CREATE DATABASE IF NOT EXISTS " << db << ";";
+  check_result(conn, mysql_query(conn, b.str().c_str()));
+  check_result(conn, mysql_select_db(conn, db.c_str()));
+  mysql_close(conn);
+}
+
+mysql_wrapper::~mysql_wrapper()
+{
+  mysql_server_end();
+  ALWAYS_ASSERT(__sync_bool_compare_and_swap(&embed_active, true, false));
+}
+
+void
+mysql_wrapper::thread_init(bool loader)
+{
+  ALWAYS_ASSERT(tl_conn == NULL);
+  tl_conn = new_connection(db);
+  ALWAYS_ASSERT(tl_conn);
+}
+
+void
+mysql_wrapper::thread_end()
+{
+  ALWAYS_ASSERT(tl_conn);
+  mysql_close(tl_conn);
+  tl_conn = NULL;
+  mysql_thread_end();
+}
+
+void *
+mysql_wrapper::new_txn(
+    uint64_t txn_flags,
+    str_arena &arena,
+    void *buf,
+    TxnProfileHint hint)
+{
+  ALWAYS_ASSERT(tl_conn);
+  check_result(tl_conn, mysql_real_query(tl_conn, "BEGIN", 5));
+  return (void *) tl_conn;
+}
+
+bool
+mysql_wrapper::commit_txn(void *p)
+{
+  ALWAYS_ASSERT(tl_conn == p);
+  return mysql_commit(tl_conn) == 0;
+}
+
+void
+mysql_wrapper::abort_txn(void *p)
+{
+  ALWAYS_ASSERT(tl_conn == p);
+  check_result(tl_conn, mysql_rollback(tl_conn));
+}
+
+abstract_ordered_index *
+mysql_wrapper::open_index(const string &name, size_t value_size_hint, bool mostly_append)
+{
+  ALWAYS_ASSERT(value_size_hint <= 256); // limitation
+  MYSQL *conn = new_connection(db);
+  ostringstream b_create, b_truncate;
+  b_create <<
+    "CREATE TABLE IF NOT EXISTS " << name << " ("
+    "  tbl_key VARBINARY(256) PRIMARY KEY, "
+    "  tbl_value VARBINARY(256) "
+    ") ENGINE=InnoDB;";
+  b_truncate <<
+    "TRUNCATE TABLE " << name << ";";
+  check_result(conn, mysql_query(conn, b_create.str().c_str()));
+  check_result(conn, mysql_query(conn, b_truncate.str().c_str()));
+  check_result(conn, mysql_commit(conn));
+  mysql_close(conn);
+  return new mysql_ordered_index(name);
+}
+
+void
+mysql_wrapper::close_index(abstract_ordered_index *idx)
+{
+  delete idx;
+}
+
+static inline string
+my_escape(MYSQL *conn, const char *p, size_t l)
+{
+  char buf[2*l + 1];
+  unsigned long newl = mysql_real_escape_string(conn, &buf[0], p, l);
+  return string(&buf[0], newl);
+}
+
+bool
+mysql_ordered_index::get(
+    void *txn,
+    const string &key,
+    string &value, size_t max_bytes_read)
+{
+  INVARIANT(txn == mysql_wrapper::tl_conn);
+  ALWAYS_ASSERT(key.size() <= 256);
+  ostringstream b;
+  b << "SELECT tbl_value FROM " << name << " WHERE tbl_key = '" << my_escape(mysql_wrapper::tl_conn, key.data(), key.size()) << "';";
+  string q = b.str();
+  check_result(mysql_wrapper::tl_conn, mysql_real_query(mysql_wrapper::tl_conn, q.data(), q.size()));
+  MYSQL_RES *res = mysql_store_result(mysql_wrapper::tl_conn);
+  ALWAYS_ASSERT(res);
+  MYSQL_ROW row = mysql_fetch_row(res);
+  bool ret = false;
+  if (row) {
+    unsigned long *lengths = mysql_fetch_lengths(res);
+    value.assign(row[0], min(lengths[0], max_bytes_read));
+    ret = true;
+  }
+  mysql_free_result(res);
+  return ret;
+}
+
+const char *
+mysql_ordered_index::put(
+    void *txn,
+    const string &key,
+    const string &value)
+{
+  INVARIANT(txn == mysql_wrapper::tl_conn);
+  ALWAYS_ASSERT(key.size() <= 256);
+  ALWAYS_ASSERT(value.size() <= 256);
+  string escaped_key = my_escape(mysql_wrapper::tl_conn, key.data(), key.size());
+  string escaped_value = my_escape(mysql_wrapper::tl_conn, value.data(), value.size());
+  ostringstream b;
+  b << "UPDATE " << name << " SET tbl_value='" << escaped_value << "' WHERE tbl_key='" << escaped_key << "';";
+  string q = b.str();
+  check_result(mysql_wrapper::tl_conn, mysql_real_query(mysql_wrapper::tl_conn, q.data(), q.size()));
+  my_ulonglong ret = mysql_affected_rows(mysql_wrapper::tl_conn);
+  if (unlikely(ret == (my_ulonglong) -1))
+    print_error_and_bail(mysql_wrapper::tl_conn);
+  if (ret)
+    return 0;
+  ostringstream b1;
+  b1 << "INSERT INTO " << name << " VALUES ('" << escaped_key << "', '" << escaped_value << "');";
+  string q1 = b1.str();
+  check_result(mysql_wrapper::tl_conn, mysql_real_query(mysql_wrapper::tl_conn, q1.data(), q1.size()));
+  return 0;
+}
+
+const char *
+mysql_ordered_index::insert(
+    void *txn,
+    const string &key,
+    const string &value)
+{
+  INVARIANT(txn == mysql_wrapper::tl_conn);
+  ALWAYS_ASSERT(key.size() <= 256);
+  ALWAYS_ASSERT(value.size() <= 256);
+  string escaped_key = my_escape(mysql_wrapper::tl_conn, key.data(), key.size());
+  string escaped_value = my_escape(mysql_wrapper::tl_conn, value.data(), value.size());
+  ostringstream b1;
+  b1 << "INSERT INTO " << name << " VALUES ('" << escaped_key << "', '" << escaped_value << "');";
+  string q1 = b1.str();
+  check_result(mysql_wrapper::tl_conn, mysql_real_query(mysql_wrapper::tl_conn, q1.data(), q1.size()));
+  return 0;
+}
+
+MYSQL *
+mysql_wrapper::new_connection(const string &db)
+{
+  MYSQL *conn = mysql_init(0);
+  mysql_options(conn, MYSQL_OPT_USE_EMBEDDED_CONNECTION, 0);
+  if (!mysql_real_connect(conn, 0, 0, 0, db.c_str(), 0, 0, CLIENT_FOUND_ROWS | CLIENT_MULTI_STATEMENTS)) {
+    mysql_close(conn);
+    cerr << "mysql_real_connect: " << mysql_error(conn) << endl;
+    ALWAYS_ASSERT(false);
+  }
+  check_result(conn, mysql_autocommit(conn, 0));
+  return conn;
+}
+
+__thread MYSQL *mysql_wrapper::tl_conn = NULL;
diff --git a/silo/benchmarks/mysql_wrapper.h b/silo/benchmarks/mysql_wrapper.h
new file mode 100644 (file)
index 0000000..f0f0014
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef _MYSQL_WRAPPER_H_
+#define _MYSQL_WRAPPER_H_
+
+#include <string>
+#include <mysql/mysql.h>
+
+#include "abstract_db.h"
+#include "../macros.h"
+
+class mysql_wrapper : public abstract_db {
+  friend class mysql_ordered_index;
+public:
+  mysql_wrapper(const std::string &dir, const std::string &db);
+  ~mysql_wrapper();
+
+  virtual void thread_init(bool loader);
+  virtual void thread_end();
+
+  virtual void *new_txn(
+      uint64_t txn_flags,
+      str_arena &arena,
+      void *buf,
+      TxnProfileHint hint);
+  virtual bool commit_txn(void *txn);
+  virtual void abort_txn(void *txn);
+
+  virtual abstract_ordered_index *
+  open_index(const std::string &name,
+             size_t value_size_hint,
+             bool mostly_append);
+
+  virtual void
+  close_index(abstract_ordered_index *idx);
+
+private:
+  std::string db;
+  MYSQL *new_connection(const std::string &db);
+  static __thread MYSQL *tl_conn;
+};
+
+class mysql_ordered_index : public abstract_ordered_index {
+public:
+  mysql_ordered_index(const std::string &name) : name(name) {}
+
+  virtual bool get(
+      void *txn,
+      const std::string &key,
+      std::string &value,
+      size_t max_bytes_read);
+
+  virtual const char * put(
+      void *txn,
+      const std::string &key,
+      const std::string &value);
+
+  virtual const char * insert(
+      void *txn,
+      const std::string &key,
+      const std::string &value);
+
+  virtual void scan(
+      void *txn,
+      const std::string &key,
+      const std::string *value,
+      scan_callback &callback,
+      str_arena *arena)
+  {
+    NDB_UNIMPLEMENTED("scan");
+  }
+
+  virtual void rscan(
+      void *txn,
+      const std::string &start_key,
+      const std::string *end_key,
+      scan_callback &callback,
+      str_arena *arena)
+  {
+    NDB_UNIMPLEMENTED("rscan");
+  }
+
+  virtual size_t
+  size() const
+  {
+    NDB_UNIMPLEMENTED("size");
+  }
+
+  virtual std::map<std::string, uint64_t>
+  clear()
+  {
+    NDB_UNIMPLEMENTED("clear");
+  }
+
+private:
+  std::string name;
+};
+
+#endif /* _MYSQL_WRAPPER_H_ */
diff --git a/silo/benchmarks/ndb_wrapper.h b/silo/benchmarks/ndb_wrapper.h
new file mode 100644 (file)
index 0000000..e659f23
--- /dev/null
@@ -0,0 +1,164 @@
+#ifndef _NDB_WRAPPER_H_
+#define _NDB_WRAPPER_H_
+
+#include "abstract_db.h"
+#include "../txn_btree.h"
+
+namespace private_ {
+  struct ndbtxn {
+    abstract_db::TxnProfileHint hint;
+    char buf[0];
+  } PACKED;
+
+  // XXX: doesn't check to make sure you are passing in an ndbtx
+  // of the right hint
+  template <template <typename> class Transaction, typename Traits>
+  struct cast_base {
+    typedef Transaction<Traits> type;
+    inline ALWAYS_INLINE type *
+    operator()(struct ndbtxn *p) const
+    {
+      return reinterpret_cast<type *>(&p->buf[0]);
+    }
+  };
+
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, ndb_get_probe0, ndb_get_probe0_cg)
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, ndb_put_probe0, ndb_put_probe0_cg)
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, ndb_insert_probe0, ndb_insert_probe0_cg)
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, ndb_scan_probe0, ndb_scan_probe0_cg)
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, ndb_remove_probe0, ndb_remove_probe0_cg)
+  STATIC_COUNTER_DECL(scopedperf::tsc_ctr, ndb_dtor_probe0, ndb_dtor_probe0_cg)
+}
+
+template <template <typename> class Transaction>
+class ndb_wrapper : public abstract_db {
+protected:
+  typedef private_::ndbtxn ndbtxn;
+  template <typename Traits>
+    using cast = private_::cast_base<Transaction, Traits>;
+
+public:
+
+  ndb_wrapper(
+      const std::vector<std::string> &logfiles,
+      const std::vector<std::vector<unsigned>> &assignments_given,
+      bool call_fsync,
+      bool use_compression,
+      bool fake_writes);
+
+  virtual ssize_t txn_max_batch_size() const OVERRIDE { return 100; }
+
+  virtual void
+  do_txn_epoch_sync() const
+  {
+    txn_epoch_sync<Transaction>::sync();
+  }
+
+  virtual void
+  do_txn_finish() const
+  {
+    txn_epoch_sync<Transaction>::finish();
+  }
+
+  virtual void
+  thread_init(bool loader)
+  {
+    txn_epoch_sync<Transaction>::thread_init(loader);
+  }
+
+  virtual void
+  thread_end()
+  {
+    txn_epoch_sync<Transaction>::thread_end();
+  }
+
+  virtual std::tuple<uint64_t, uint64_t, double>
+  get_ntxn_persisted() const
+  {
+    return txn_epoch_sync<Transaction>::compute_ntxn_persisted();
+  }
+
+  virtual void
+  reset_ntxn_persisted()
+  {
+    txn_epoch_sync<Transaction>::reset_ntxn_persisted();
+  }
+
+  virtual size_t
+  sizeof_txn_object(uint64_t txn_flags) const;
+
+  virtual void *new_txn(
+      uint64_t txn_flags,
+      str_arena &arena,
+      void *buf,
+      TxnProfileHint hint);
+  virtual bool commit_txn(void *txn);
+  virtual void abort_txn(void *txn);
+  virtual void print_txn_debug(void *txn) const;
+  virtual std::map<std::string, uint64_t> get_txn_counters(void *txn) const;
+
+  virtual abstract_ordered_index *
+  open_index(const std::string &name,
+             size_t value_size_hint,
+             bool mostly_append);
+
+  virtual void
+  close_index(abstract_ordered_index *idx);
+
+};
+
+template <template <typename> class Transaction>
+class ndb_ordered_index : public abstract_ordered_index {
+protected:
+  typedef private_::ndbtxn ndbtxn;
+  template <typename Traits>
+    using cast = private_::cast_base<Transaction, Traits>;
+
+public:
+  ndb_ordered_index(const std::string &name, size_t value_size_hint, bool mostly_append);
+  virtual bool get(
+      void *txn,
+      const std::string &key,
+      std::string &value, size_t max_bytes_read);
+  virtual const char * put(
+      void *txn,
+      const std::string &key,
+      const std::string &value);
+  virtual const char * put(
+      void *txn,
+      std::string &&key,
+      std::string &&value);
+  virtual const char *
+  insert(void *txn,
+         const std::string &key,
+         const std::string &value);
+  virtual const char *
+  insert(void *txn,
+         std::string &&key,
+         std::string &&value);
+  virtual void scan(
+      void *txn,
+      const std::string &start_key,
+      const std::string *end_key,
+      scan_callback &callback,
+      str_arena *arena);
+  virtual void rscan(
+      void *txn,
+      const std::string &start_key,
+      const std::string *end_key,
+      scan_callback &callback,
+      str_arena *arena);
+  virtual void remove(
+      void *txn,
+      const std::string &key);
+  virtual void remove(
+      void *txn,
+      std::string &&key);
+  virtual size_t size() const;
+  virtual std::map<std::string, uint64_t> clear();
+private:
+  std::string name;
+  txn_btree<Transaction> btr;
+};
+
+#endif /* _NDB_WRAPPER_H_ */
diff --git a/silo/benchmarks/ndb_wrapper_impl.h b/silo/benchmarks/ndb_wrapper_impl.h
new file mode 100644 (file)
index 0000000..412d68f
--- /dev/null
@@ -0,0 +1,600 @@
+#ifndef _NDB_WRAPPER_IMPL_H_
+#define _NDB_WRAPPER_IMPL_H_
+
+#include <stdint.h>
+#include "ndb_wrapper.h"
+#include "../counter.h"
+#include "../rcu.h"
+#include "../varkey.h"
+#include "../macros.h"
+#include "../util.h"
+#include "../scopedperf.hh"
+#include "../txn.h"
+//#include "../txn_proto1_impl.h"
+#include "../txn_proto2_impl.h"
+#include "../tuple.h"
+
+struct hint_default_traits : public default_transaction_traits {
+  typedef str_arena StringAllocator;
+};
+
+// ycsb profiles
+
+struct hint_kv_get_put_traits {
+  static const size_t read_set_expected_size = 1;
+  static const size_t write_set_expected_size = 1;
+  static const size_t absent_set_expected_size = 1;
+  static const bool stable_input_memory = true;
+  static const bool hard_expected_sizes = true;
+  static const bool read_own_writes = false;
+  typedef str_arena StringAllocator;
+};
+
+struct hint_kv_rmw_traits : public hint_kv_get_put_traits {};
+
+struct hint_kv_scan_traits {
+  static const size_t read_set_expected_size = 100;
+  static const size_t write_set_expected_size = 1;
+  static const size_t absent_set_expected_size = read_set_expected_size / 7 + 1;
+  static const bool stable_input_memory = true;
+  static const bool hard_expected_sizes = false;
+  static const bool read_own_writes = false;
+  typedef str_arena StringAllocator;
+};
+
+// tpcc profiles
+
+struct hint_read_only_traits {
+  static const size_t read_set_expected_size = 1;
+  static const size_t write_set_expected_size = 1;
+  static const size_t absent_set_expected_size = 1;
+  static const bool stable_input_memory = true;
+  static const bool hard_expected_sizes = true;
+  static const bool read_own_writes = false;
+  typedef str_arena StringAllocator;
+};
+
+struct hint_tpcc_new_order_traits {
+  static const size_t read_set_expected_size = 35;
+  static const size_t write_set_expected_size = 35;
+  static const size_t absent_set_expected_size = 1;
+  static const bool stable_input_memory = true;
+  static const bool hard_expected_sizes = true;
+  static const bool read_own_writes = false;
+  typedef str_arena StringAllocator;
+};
+
+struct hint_tpcc_payment_traits {
+  static const size_t read_set_expected_size = 85;
+  static const size_t write_set_expected_size = 10;
+  static const size_t absent_set_expected_size = 15;
+  static const bool stable_input_memory = true;
+  static const bool hard_expected_sizes = false;
+  static const bool read_own_writes = false;
+  typedef str_arena StringAllocator;
+};
+
+struct hint_tpcc_delivery_traits {
+  static const size_t read_set_expected_size = 175;
+  static const size_t write_set_expected_size = 175;
+  static const size_t absent_set_expected_size = 35;
+  static const bool stable_input_memory = true;
+  static const bool hard_expected_sizes = false;
+  static const bool read_own_writes = false;
+  typedef str_arena StringAllocator;
+};
+
+struct hint_tpcc_order_status_traits {
+  static const size_t read_set_expected_size = 95;
+  static const size_t write_set_expected_size = 1;
+  static const size_t absent_set_expected_size = 25;
+  static const bool stable_input_memory = true;
+  static const bool hard_expected_sizes = false;
+  static const bool read_own_writes = false;
+  typedef str_arena StringAllocator;
+};
+
+struct hint_tpcc_order_status_read_only_traits : public hint_read_only_traits {};
+
+struct hint_tpcc_stock_level_traits {
+  static const size_t read_set_expected_size = 500;
+  static const size_t write_set_expected_size = 1;
+  static const size_t absent_set_expected_size = 25;
+  static const bool stable_input_memory = true;
+  static const bool hard_expected_sizes = false;
+  static const bool read_own_writes = false;
+  typedef str_arena StringAllocator;
+};
+
+struct hint_tpcc_stock_level_read_only_traits : public hint_read_only_traits {};
+
+#define TXN_PROFILE_HINT_OP(x) \
+  x(abstract_db::HINT_DEFAULT, hint_default_traits) \
+  x(abstract_db::HINT_KV_GET_PUT, hint_kv_get_put_traits) \
+  x(abstract_db::HINT_KV_RMW, hint_kv_rmw_traits) \
+  x(abstract_db::HINT_KV_SCAN, hint_kv_scan_traits) \
+  x(abstract_db::HINT_TPCC_NEW_ORDER, hint_tpcc_new_order_traits) \
+  x(abstract_db::HINT_TPCC_PAYMENT, hint_tpcc_payment_traits) \
+  x(abstract_db::HINT_TPCC_DELIVERY, hint_tpcc_delivery_traits) \
+  x(abstract_db::HINT_TPCC_ORDER_STATUS, hint_tpcc_order_status_traits) \
+  x(abstract_db::HINT_TPCC_ORDER_STATUS_READ_ONLY, hint_tpcc_order_status_read_only_traits) \
+  x(abstract_db::HINT_TPCC_STOCK_LEVEL, hint_tpcc_stock_level_traits) \
+  x(abstract_db::HINT_TPCC_STOCK_LEVEL_READ_ONLY, hint_tpcc_stock_level_read_only_traits)
+
+template <template <typename> class Transaction>
+ndb_wrapper<Transaction>::ndb_wrapper(
+    const std::vector<std::string> &logfiles,
+    const std::vector<std::vector<unsigned>> &assignments_given,
+    bool call_fsync,
+    bool use_compression,
+    bool fake_writes)
+{
+  if (logfiles.empty())
+    return;
+  std::vector<std::vector<unsigned>> assignments_used;
+  txn_logger::Init(
+      nthreads, logfiles, assignments_given, &assignments_used,
+      call_fsync,
+      use_compression,
+      fake_writes);
+  if (verbose) {
+    std::cerr << "[logging subsystem]" << std::endl;
+    std::cerr << "  assignments: " << assignments_used << std::endl;
+    std::cerr << "  call fsync : " << call_fsync       << std::endl;
+    std::cerr << "  compression: " << use_compression  << std::endl;
+    std::cerr << "  fake_writes: " << fake_writes      << std::endl;
+  }
+}
+
+template <template <typename> class Transaction>
+size_t
+ndb_wrapper<Transaction>::sizeof_txn_object(uint64_t txn_flags) const
+{
+#define MY_OP_X(a, b) sizeof(typename cast< b >::type),
+  const size_t xs[] = {
+    TXN_PROFILE_HINT_OP(MY_OP_X)
+  };
+#undef MY_OP_X
+  size_t xmax = 0;
+  for (size_t i = 0; i < ARRAY_NELEMS(xs); i++)
+    xmax = std::max(xmax, xs[i]);
+  return xmax;
+}
+
+template <template <typename> class Transaction>
+void *
+ndb_wrapper<Transaction>::new_txn(
+    uint64_t txn_flags,
+    str_arena &arena,
+    void *buf,
+    TxnProfileHint hint)
+{
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(buf);
+  p->hint = hint;
+#define MY_OP_X(a, b) \
+  case a: \
+    new (&p->buf[0]) typename cast< b >::type(txn_flags, arena); \
+    return p;
+  switch (hint) {
+    TXN_PROFILE_HINT_OP(MY_OP_X)
+  default:
+    ALWAYS_ASSERT(false);
+  }
+#undef MY_OP_X
+  return 0;
+}
+
+template <typename T>
+static inline ALWAYS_INLINE void
+Destroy(T *t)
+{
+  PERF_DECL(static std::string probe1_name(std::string(__PRETTY_FUNCTION__) + std::string(":total:")));
+  ANON_REGION(probe1_name.c_str(), &private_::ndb_dtor_probe0_cg);
+  t->~T();
+}
+
+template <template <typename> class Transaction>
+bool
+ndb_wrapper<Transaction>::commit_txn(void *txn)
+{
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      const bool ret = t->commit(); \
+      Destroy(t); \
+      return ret; \
+    }
+  switch (p->hint) {
+    TXN_PROFILE_HINT_OP(MY_OP_X)
+  default:
+    ALWAYS_ASSERT(false);
+  }
+#undef MY_OP_X
+  return false;
+}
+
+template <template <typename> class Transaction>
+void
+ndb_wrapper<Transaction>::abort_txn(void *txn)
+{
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      t->abort(); \
+      Destroy(t); \
+      return; \
+    }
+  switch (p->hint) {
+    TXN_PROFILE_HINT_OP(MY_OP_X)
+  default:
+    ALWAYS_ASSERT(false);
+  }
+#undef MY_OP_X
+}
+
+template <template <typename> class Transaction>
+void
+ndb_wrapper<Transaction>::print_txn_debug(void *txn) const
+{
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      t->dump_debug_info(); \
+      return; \
+    }
+  switch (p->hint) {
+    TXN_PROFILE_HINT_OP(MY_OP_X)
+  default:
+    ALWAYS_ASSERT(false);
+  }
+#undef MY_OP_X
+}
+
+template <template <typename> class Transaction>
+std::map<std::string, uint64_t>
+ndb_wrapper<Transaction>::get_txn_counters(void *txn) const
+{
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      return t->get_txn_counters(); \
+    }
+  switch (p->hint) {
+    TXN_PROFILE_HINT_OP(MY_OP_X)
+  default:
+    ALWAYS_ASSERT(false);
+  }
+#undef MY_OP_X
+  return std::map<std::string, uint64_t>();
+}
+
+template <template <typename> class Transaction>
+abstract_ordered_index *
+ndb_wrapper<Transaction>::open_index(const std::string &name, size_t value_size_hint, bool mostly_append)
+{
+  return new ndb_ordered_index<Transaction>(name, value_size_hint, mostly_append);
+}
+
+template <template <typename> class Transaction>
+void
+ndb_wrapper<Transaction>::close_index(abstract_ordered_index *idx)
+{
+  delete idx;
+}
+
+template <template <typename> class Transaction>
+ndb_ordered_index<Transaction>::ndb_ordered_index(
+    const std::string &name, size_t value_size_hint, bool mostly_append)
+  : name(name), btr(value_size_hint, mostly_append, name)
+{
+  // for debugging
+  //std::cerr << name << " : btree= "
+  //          << btr.get_underlying_btree()
+  //          << std::endl;
+}
+
+template <template <typename> class Transaction>
+bool
+ndb_ordered_index<Transaction>::get(
+    void *txn,
+    const std::string &key,
+    std::string &value, size_t max_bytes_read)
+{
+  PERF_DECL(static std::string probe1_name(std::string(__PRETTY_FUNCTION__) + std::string(":total:")));
+  ANON_REGION(probe1_name.c_str(), &private_::ndb_get_probe0_cg);
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+  try {
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      if (!btr.search(*t, key, value, max_bytes_read)) \
+        return false; \
+      return true; \
+    }
+    switch (p->hint) {
+      TXN_PROFILE_HINT_OP(MY_OP_X)
+    default:
+      ALWAYS_ASSERT(false);
+    }
+#undef MY_OP_X
+    INVARIANT(!value.empty());
+    return true;
+  } catch (transaction_abort_exception &ex) {
+    throw abstract_db::abstract_abort_exception();
+  }
+}
+
+// XXX: find way to remove code duplication below using C++ templates!
+
+template <template <typename> class Transaction>
+const char *
+ndb_ordered_index<Transaction>::put(
+    void *txn,
+    const std::string &key,
+    const std::string &value)
+{
+  PERF_DECL(static std::string probe1_name(std::string(__PRETTY_FUNCTION__) + std::string(":total:")));
+  ANON_REGION(probe1_name.c_str(), &private_::ndb_put_probe0_cg);
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+  try {
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      btr.put(*t, key, value); \
+      return 0; \
+    }
+    switch (p->hint) {
+      TXN_PROFILE_HINT_OP(MY_OP_X)
+    default:
+      ALWAYS_ASSERT(false);
+    }
+#undef MY_OP_X
+  } catch (transaction_abort_exception &ex) {
+    throw abstract_db::abstract_abort_exception();
+  }
+  return 0;
+}
+
+template <template <typename> class Transaction>
+const char *
+ndb_ordered_index<Transaction>::put(
+    void *txn,
+    std::string &&key,
+    std::string &&value)
+{
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+  try {
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      btr.put(*t, std::move(key), std::move(value)); \
+      return 0; \
+    }
+    switch (p->hint) {
+      TXN_PROFILE_HINT_OP(MY_OP_X)
+    default:
+      ALWAYS_ASSERT(false);
+    }
+#undef MY_OP_X
+  } catch (transaction_abort_exception &ex) {
+    throw abstract_db::abstract_abort_exception();
+  }
+  return 0;
+}
+
+template <template <typename> class Transaction>
+const char *
+ndb_ordered_index<Transaction>::insert(
+    void *txn,
+    const std::string &key,
+    const std::string &value)
+{
+  PERF_DECL(static std::string probe1_name(std::string(__PRETTY_FUNCTION__) + std::string(":total:")));
+  ANON_REGION(probe1_name.c_str(), &private_::ndb_insert_probe0_cg);
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+  try {
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      btr.insert(*t, key, value); \
+      return 0; \
+    }
+    switch (p->hint) {
+      TXN_PROFILE_HINT_OP(MY_OP_X)
+    default:
+      ALWAYS_ASSERT(false);
+    }
+#undef MY_OP_X
+  } catch (transaction_abort_exception &ex) {
+    throw abstract_db::abstract_abort_exception();
+  }
+  return 0;
+}
+
+template <template <typename> class Transaction>
+const char *
+ndb_ordered_index<Transaction>::insert(
+    void *txn,
+    std::string &&key,
+    std::string &&value)
+{
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+  try {
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      btr.insert(*t, std::move(key), std::move(value)); \
+      return 0; \
+    }
+    switch (p->hint) {
+      TXN_PROFILE_HINT_OP(MY_OP_X)
+    default:
+      ALWAYS_ASSERT(false);
+    }
+#undef MY_OP_X
+  } catch (transaction_abort_exception &ex) {
+    throw abstract_db::abstract_abort_exception();
+  }
+  return 0;
+}
+
+template <template <typename> class Transaction>
+class ndb_wrapper_search_range_callback : public txn_btree<Transaction>::search_range_callback {
+public:
+  ndb_wrapper_search_range_callback(abstract_ordered_index::scan_callback &upcall)
+    : upcall(&upcall) {}
+
+  virtual bool
+  invoke(const typename txn_btree<Transaction>::keystring_type &k,
+         const typename txn_btree<Transaction>::string_type &v)
+  {
+    return upcall->invoke(k.data(), k.length(), v);
+  }
+
+private:
+  abstract_ordered_index::scan_callback *upcall;
+};
+
+template <template <typename> class Transaction>
+void
+ndb_ordered_index<Transaction>::scan(
+    void *txn,
+    const std::string &start_key,
+    const std::string *end_key,
+    scan_callback &callback,
+    str_arena *arena)
+{
+  PERF_DECL(static std::string probe1_name(std::string(__PRETTY_FUNCTION__) + std::string(":total:")));
+  ANON_REGION(probe1_name.c_str(), &private_::ndb_scan_probe0_cg);
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+  ndb_wrapper_search_range_callback<Transaction> c(callback);
+  try {
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      btr.search_range_call(*t, start_key, end_key, c); \
+      return; \
+    }
+    switch (p->hint) {
+      TXN_PROFILE_HINT_OP(MY_OP_X)
+    default:
+      ALWAYS_ASSERT(false);
+    }
+#undef MY_OP_X
+  } catch (transaction_abort_exception &ex) {
+    throw abstract_db::abstract_abort_exception();
+  }
+}
+
+template <template <typename> class Transaction>
+void
+ndb_ordered_index<Transaction>::rscan(
+    void *txn,
+    const std::string &start_key,
+    const std::string *end_key,
+    scan_callback &callback,
+    str_arena *arena)
+{
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+  ndb_wrapper_search_range_callback<Transaction> c(callback);
+  try {
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      btr.rsearch_range_call(*t, start_key, end_key, c); \
+      return; \
+    }
+    switch (p->hint) {
+      TXN_PROFILE_HINT_OP(MY_OP_X)
+    default:
+      ALWAYS_ASSERT(false);
+    }
+#undef MY_OP_X
+  } catch (transaction_abort_exception &ex) {
+    throw abstract_db::abstract_abort_exception();
+  }
+}
+
+template <template <typename> class Transaction>
+void
+ndb_ordered_index<Transaction>::remove(void *txn, const std::string &key)
+{
+  PERF_DECL(static std::string probe1_name(std::string(__PRETTY_FUNCTION__) + std::string(":total:")));
+  ANON_REGION(probe1_name.c_str(), &private_::ndb_remove_probe0_cg);
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+  try {
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      btr.remove(*t, key); \
+      return; \
+    }
+    switch (p->hint) {
+      TXN_PROFILE_HINT_OP(MY_OP_X)
+    default:
+      ALWAYS_ASSERT(false);
+    }
+#undef MY_OP_X
+  } catch (transaction_abort_exception &ex) {
+    throw abstract_db::abstract_abort_exception();
+  }
+}
+
+template <template <typename> class Transaction>
+void
+ndb_ordered_index<Transaction>::remove(void *txn, std::string &&key)
+{
+  ndbtxn * const p = reinterpret_cast<ndbtxn *>(txn);
+  try {
+#define MY_OP_X(a, b) \
+  case a: \
+    { \
+      auto t = cast< b >()(p); \
+      btr.remove(*t, std::move(key)); \
+      return; \
+    }
+    switch (p->hint) {
+      TXN_PROFILE_HINT_OP(MY_OP_X)
+    default:
+      ALWAYS_ASSERT(false);
+    }
+#undef MY_OP_X
+  } catch (transaction_abort_exception &ex) {
+    throw abstract_db::abstract_abort_exception();
+  }
+}
+
+template <template <typename> class Transaction>
+size_t
+ndb_ordered_index<Transaction>::size() const
+{
+  return btr.size_estimate();
+}
+
+template <template <typename> class Transaction>
+std::map<std::string, uint64_t>
+ndb_ordered_index<Transaction>::clear()
+{
+#ifdef TXN_BTREE_DUMP_PURGE_STATS
+  std::cerr << "purging txn index: " << name << std::endl;
+#endif
+  return btr.unsafe_purge(true);
+}
+
+#endif /* _NDB_WRAPPER_IMPL_H_ */
diff --git a/silo/benchmarks/plotter.py b/silo/benchmarks/plotter.py
new file mode 100644 (file)
index 0000000..cf35280
--- /dev/null
@@ -0,0 +1,16 @@
+import matplotlib
+matplotlib.use('Agg')
+import pylab as plt
+
+import sys
+
+if __name__ == '__main__':
+  (_, fname, oname) = sys.argv
+  execfile(fname)
+  for name, data in zip(DBS, RESULTS):
+    plt.plot(THREADS, data)
+  plt.xlabel('num threads')
+  plt.ylabel('ops/sec')
+  plt.title('')
+  plt.legend(DBS, loc='lower right')
+  plt.savefig(oname)
diff --git a/silo/benchmarks/queue.cc b/silo/benchmarks/queue.cc
new file mode 100644 (file)
index 0000000..cb29501
--- /dev/null
@@ -0,0 +1,296 @@
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <utility>
+#include <string>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../macros.h"
+#include "../varkey.h"
+#include "../thread.h"
+#include "../util.h"
+#include "../spinbarrier.h"
+
+#include "bench.h"
+
+using namespace std;
+using namespace util;
+
+static size_t nkeys;
+
+static inline string
+queue_key(uint64_t id0, uint64_t id1)
+{
+  big_endian_trfm<uint64_t> t;
+  string buf(2 * sizeof(uint64_t), 0);
+  uint64_t *p = (uint64_t *) &buf[0];
+  *p++ = t(id0);
+  *p++ = t(id1);
+  return buf;
+}
+
+static const string queue_values("ABCDEFGH");
+
+class queue_worker : public bench_worker {
+public:
+  queue_worker(unsigned int worker_id,
+               unsigned long seed, abstract_db *db,
+               const map<string, abstract_ordered_index *> &open_tables,
+               spin_barrier *barrier_a, spin_barrier *barrier_b,
+               uint64_t id, bool consumer)
+    : bench_worker(worker_id, false, seed, db,
+                   open_tables, barrier_a, barrier_b),
+      tbl(open_tables.at("table")), id(id), consumer(consumer),
+      ctr(consumer ? 0 : nkeys)
+  {
+  }
+
+  txn_result
+  txn_produce()
+  {
+    void *txn = db->new_txn(txn_flags, arena, txn_buf());
+    try {
+      const string k = queue_key(id, ctr);
+      tbl->insert(txn, k, queue_values);
+      if (likely(db->commit_txn(txn))) {
+        ctr++;
+        return txn_result(true, queue_values.size());
+      }
+    } catch (abstract_db::abstract_abort_exception &ex) {
+      db->abort_txn(txn);
+    }
+    return txn_result(false, 0);
+  }
+
+  static txn_result
+  TxnProduce(bench_worker *w)
+  {
+    return static_cast<queue_worker *>(w)->txn_produce();
+  }
+
+  txn_result
+  txn_consume()
+  {
+    void *txn = db->new_txn(txn_flags, arena, txn_buf());
+    try {
+      const string lowk = queue_key(id, 0);
+      const string highk = queue_key(id, numeric_limits<uint64_t>::max());
+      limit_callback c(1);
+      tbl->scan(txn, lowk, &highk, c);
+      ssize_t ret = 0;
+      if (likely(!c.values.empty())) {
+        ALWAYS_ASSERT(c.values.size() == 1);
+        const string &k = c.values.front().first;
+        tbl->remove(txn, k);
+        ret = -queue_values.size();
+      }
+      if (likely(db->commit_txn(txn)))
+        return txn_result(true, ret);
+    } catch (abstract_db::abstract_abort_exception &ex) {
+      db->abort_txn(txn);
+    }
+    return txn_result(false, 0);
+  }
+
+  static txn_result
+  TxnConsume(bench_worker *w)
+  {
+    return static_cast<queue_worker *>(w)->txn_consume();
+  }
+
+  txn_result
+  txn_consume_scanhint()
+  {
+    void *txn = db->new_txn(txn_flags, arena, txn_buf());
+    try {
+      const string lowk = queue_key(id, ctr);
+      const string highk = queue_key(id, numeric_limits<uint64_t>::max());
+      limit_callback c(1);
+      tbl->scan(txn, lowk, &highk, c);
+      const bool found = !c.values.empty();
+      ssize_t ret = 0;
+      if (likely(found)) {
+        ALWAYS_ASSERT(c.values.size() == 1);
+        const string &k = c.values.front().first;
+        tbl->remove(txn, k);
+        ret = -queue_values.size();
+      }
+      if (likely(db->commit_txn(txn))) {
+        if (likely(found)) ctr++;
+        return txn_result(true, ret);
+      }
+    } catch (abstract_db::abstract_abort_exception &ex) {
+      db->abort_txn(txn);
+    }
+    return txn_result(false, 0);
+  }
+
+  static txn_result
+  TxnConsumeScanHint(bench_worker *w)
+  {
+    return static_cast<queue_worker *>(w)->txn_consume_scanhint();
+  }
+
+  txn_result
+  txn_consume_noscan()
+  {
+    void *txn = db->new_txn(txn_flags, arena, txn_buf());
+    try {
+      const string k = queue_key(id, ctr);
+      string v;
+      bool found = false;
+      ssize_t ret = 0;
+      if (likely((found = tbl->get(txn, k, v)))) {
+        tbl->remove(txn, k);
+        ret = -queue_values.size();
+      }
+      if (likely(db->commit_txn(txn))) {
+        if (likely(found)) ctr++;
+        return txn_result(true, ret);
+      }
+    } catch (abstract_db::abstract_abort_exception &ex) {
+      db->abort_txn(txn);
+    }
+    return txn_result(false, 0);
+  }
+
+  static txn_result
+  TxnConsumeNoScan(bench_worker *w)
+  {
+    return static_cast<queue_worker *>(w)->txn_consume_noscan();
+  }
+
+  virtual workload_desc_vec
+  get_workload() const
+  {
+    workload_desc_vec w;
+    if (consumer)
+      w.push_back(workload_desc("Consume", 1.0, TxnConsume));
+      //w.push_back(workload_desc("ConsumeScanHint", 1.0, TxnConsumeScanHint));
+      //w.push_back(workload_desc("ConsumeNoScan", 1.0, TxnConsumeNoScan));
+    else
+      w.push_back(workload_desc("Produce", 1.0, TxnProduce));
+    return w;
+  }
+
+private:
+  abstract_ordered_index *tbl;
+  uint64_t id;
+  bool consumer;
+  uint64_t ctr;
+};
+
+class queue_table_loader : public bench_loader {
+public:
+  queue_table_loader(unsigned long seed,
+                     abstract_db *db,
+                     const map<string, abstract_ordered_index *> &open_tables)
+    : bench_loader(seed, db, open_tables)
+  {}
+
+protected:
+  virtual void
+  load()
+  {
+    abstract_ordered_index *tbl = open_tables.at("table");
+    try {
+      // load
+      const size_t batchsize = (db->txn_max_batch_size() == -1) ?
+        10000 : db->txn_max_batch_size();
+      ALWAYS_ASSERT(batchsize > 0);
+      const size_t nbatches = nkeys / batchsize;
+      for (size_t id = 0; id < nthreads / 2; id++) {
+        if (nbatches == 0) {
+          void *txn = db->new_txn(txn_flags, arena, txn_buf());
+          for (size_t j = 0; j < nkeys; j++) {
+            const string k = queue_key(id, j);
+            const string &v = queue_values;
+            tbl->insert(txn, k, v);
+          }
+          if (verbose)
+            cerr << "batch 1/1 done" << endl;
+          ALWAYS_ASSERT(db->commit_txn(txn));
+        } else {
+          for (size_t i = 0; i < nbatches; i++) {
+            size_t keyend = (i == nbatches - 1) ? nkeys : (i + 1) * batchsize;
+            void *txn = db->new_txn(txn_flags, arena, txn_buf());
+            for (size_t j = i * batchsize; j < keyend; j++) {
+              const string k = queue_key(id, j);
+              const string &v = queue_values;
+              tbl->insert(txn, k, v);
+            }
+            if (verbose)
+              cerr << "batch " << (i + 1) << "/" << nbatches << " done" << endl;
+            ALWAYS_ASSERT(db->commit_txn(txn));
+          }
+        }
+      }
+    } catch (abstract_db::abstract_abort_exception &ex) {
+      // shouldn't abort on loading!
+      ALWAYS_ASSERT(false);
+    }
+    if (verbose)
+      cerr << "[INFO] finished loading table" << endl;
+  }
+};
+
+class queue_bench_runner : public bench_runner {
+public:
+  queue_bench_runner(abstract_db *db, bool write_only)
+    : bench_runner(db), write_only(write_only)
+  {
+    open_tables["table"] = db->open_index("table", queue_values.size());
+  }
+
+protected:
+  virtual vector<bench_loader *>
+  make_loaders()
+  {
+    vector<bench_loader *> ret;
+    ret.push_back(new queue_table_loader(0, db, open_tables));
+    return ret;
+  }
+
+  virtual vector<bench_worker *>
+  make_workers()
+  {
+    fast_random r(8544290);
+    vector<bench_worker *> ret;
+    if (write_only) {
+      for (size_t i = 0; i < nthreads; i++)
+        ret.push_back(
+          new queue_worker(
+            i, r.next(), db, open_tables,
+            &barrier_a, &barrier_b, i, false));
+    } else {
+      ALWAYS_ASSERT(nthreads >= 2);
+      if (verbose && (nthreads % 2))
+        cerr << "queue_bench_runner: odd number of workers given" << endl;
+      for (size_t i = 0; i < nthreads / 2; i++) {
+        ret.push_back(
+          new queue_worker(
+            i, r.next(), db, open_tables,
+            &barrier_a, &barrier_b, i, true));
+        ret.push_back(
+          new queue_worker(
+            i + 1, r.next(), db, open_tables,
+            &barrier_a, &barrier_b, i, false));
+      }
+    }
+    return ret;
+  }
+
+private:
+  bool write_only;
+};
+
+void
+queue_do_test(abstract_db *db, int argc, char **argv)
+{
+  nkeys = size_t(scale_factor * 1000.0);
+  ALWAYS_ASSERT(nkeys > 0);
+  queue_bench_runner r(db, true);
+  r.run();
+}
diff --git a/silo/benchmarks/results/NOTES.txt b/silo/benchmarks/results/NOTES.txt
new file mode 100644 (file)
index 0000000..427ef5b
--- /dev/null
@@ -0,0 +1,19 @@
+Exp notes:
+
+istc3-8-1-13.py: 40 ms ticker, full persistence
+
+istc3-8-1-13_fake_writes.py: same as itsc3-8-1-13.py, except --log-fake-writes is used
+
+istc3-8-1-13_log_reduce_size.py: same as istc3-8-1-13.py, except LOGGER_UNSAFE_REDUCE_BUFFER_SIZE is defined
+
+istc3-8-1-13_log_reduce_size_nofsync.py: same as istc3-8-1-13_log_reduce_size.py, except --log-nofsync is used
+
+istc3-8-1-13_fake_writes_stride.py: same as istc3-8-1-13_fake_writes.py, except LOGGER_STRIDE_OVER_BUFFER is defined and stridelen=(CACHELINE_SIZE/2)
+
+istc3-8-1-13_fake_writes_stride1.py: same as istc3-8-1-13_fake_writes_stride.py, except stridelen=1
+
+istc3-8-1-13_fake_compress.py: same as istc3-8-1-13.py, except LOGGER_UNSAFE_FAKE_COMPRESSION is enabled
+
+istc3-8-1-13_compress.py: same as istc3-8-1-13.py, except --log-compress is used
+
+istc3-8-1-13_newbench.py: same as istc3-8-1-13.py, except we use 'new-benchmarks/dbtest' (delta encoding)
diff --git a/silo/benchmarks/results/ben-3-8-13.py b/silo/benchmarks/results/ben-3-8-13.py
new file mode 100644 (file)
index 0000000..c7ce728
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'scale_factor': 80, 'threads': 80, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (232976.0, 3.76111)), ({'scale_factor': 72, 'threads': 72, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (254892.0, 3.73888)), ({'scale_factor': 64, 'threads': 64, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (242310.0, 3.46666)), ({'scale_factor': 56, 'threads': 56, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (237052.0, 3.57222)), ({'scale_factor': 48, 'threads': 48, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (230557.0, 3.74444)), ({'scale_factor': 40, 'threads': 40, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (234613.0, 3.87222)), ({'scale_factor': 32, 'threads': 32, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (224310.0, 3.7)), ({'scale_factor': 24, 'threads': 24, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (190809.0, 2.90555)), ({'scale_factor': 16, 'threads': 16, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (142130.0, 2.01667)), ({'scale_factor': 8, 'threads': 8, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (76759.6, 1.21667)), ({'scale_factor': 4, 'threads': 4, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (38735.2, 0.533333)), ({'scale_factor': 2, 'threads': 2, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (20094.2, 0.305555)), ({'scale_factor': 1, 'threads': 1, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (10286.7, 0.0))]
diff --git a/silo/benchmarks/results/ben-4-10-13.py b/silo/benchmarks/results/ben-4-10-13.py
new file mode 100644 (file)
index 0000000..91834f1
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 1, 'name': 'scale_tpcc', 'numa_memory': '2G', 'threads': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(35595.2, 0.0), (35134.1, 0.0), (35668.9, 0.0)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 10, 'name': 'scale_tpcc', 'numa_memory': '20G', 'threads': 10, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(293841.0, 12.4664), (294454.0, 11.8998), (295441.0, 13.7664)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 20, 'name': 'scale_tpcc', 'numa_memory': '40G', 'threads': 20, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(573735.0, 26.2659), (571127.0, 24.2994), (572429.0, 25.0326)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 30, 'name': 'scale_tpcc', 'numa_memory': '60G', 'threads': 30, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(842923.0, 37.6319), (841078.0, 37.3323), (848000.0, 39.3986)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 40, 'name': 'scale_tpcc', 'numa_memory': '80G', 'threads': 40, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(1117960.0, 47.8294), (1117570.0, 49.1965), (1117690.0, 47.7618)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 50, 'name': 'scale_tpcc', 'numa_memory': '100G', 'threads': 50, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(1377360.0, 63.2581), (1375480.0, 60.6967), (1380110.0, 58.1962)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 60, 'name': 'scale_tpcc', 'numa_memory': '120G', 'threads': 60, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(1606770.0, 68.7615), (1625400.0, 68.9893), (1578890.0, 65.9616)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 70, 'name': 'scale_tpcc', 'numa_memory': '140G', 'threads': 70, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(1788150.0, 74.5197), (1770310.0, 75.1934), (1779690.0, 73.7555)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 80, 'name': 'scale_tpcc', 'numa_memory': '160G', 'threads': 80, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(1743840.0, 69.416), (1838940.0, 76.984), (1749190.0, 71.3892)]),({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 75, 'name': 'scale_tpcc', 'numa_memory': '150G', 'threads': 75, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(1823040.0, 75.6186), (1826750.0, 77.4802), (1821720.0, 74.7569)])]
diff --git a/silo/benchmarks/results/istc11-3-13-13.py b/silo/benchmarks/results/istc11-3-13-13.py
new file mode 100644 (file)
index 0000000..0c389fa
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'scale_factor': 32, 'threads': 32, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (446207.0, 0.0)), ({'scale_factor': 32, 'threads': 32, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (238640.0, 3.41666)), ({'scale_factor': 28, 'threads': 28, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (382193.0, 0.0)), ({'scale_factor': 28, 'threads': 28, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (256238.0, 3.48332)), ({'scale_factor': 24, 'threads': 24, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (341648.0, 0.0)), ({'scale_factor': 24, 'threads': 24, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (225791.0, 3.16666)), ({'scale_factor': 20, 'threads': 20, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (299640.0, 0.0)), ({'scale_factor': 20, 'threads': 20, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (194373.0, 2.46666)), ({'scale_factor': 16, 'threads': 16, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (243529.0, 0.0)), ({'scale_factor': 16, 'threads': 16, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (159408.0, 2.16666)), ({'scale_factor': 12, 'threads': 12, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (185722.0, 0.0)), ({'scale_factor': 12, 'threads': 12, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (121866.0, 1.94999)), ({'scale_factor': 8, 'threads': 8, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (135299.0, 0.0)), ({'scale_factor': 8, 'threads': 8, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (85131.2, 0.966664)), ({'scale_factor': 4, 'threads': 4, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (73284.6, 0.0)), ({'scale_factor': 4, 'threads': 4, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (42715.4, 0.683332)), ({'scale_factor': 1, 'threads': 1, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (23663.7, 0.0)), ({'scale_factor': 1, 'threads': 1, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (11229.9, 0.0))]
diff --git a/silo/benchmarks/results/istc11-3-14-13.py b/silo/benchmarks/results/istc11-3-14-13.py
new file mode 100644 (file)
index 0000000..4e4cf30
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'scale_factor': 1000, 'threads': 1, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (559456.0, 0.0)), ({'scale_factor': 1000, 'threads': 1, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (208605.0, 0.0)), ({'scale_factor': 4000, 'threads': 4, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (1772190.0, 0.0)), ({'scale_factor': 4000, 'threads': 4, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (869710.0, 0.0)), ({'scale_factor': 8000, 'threads': 8, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (3070970.0, 0.0)), ({'scale_factor': 8000, 'threads': 8, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (1703070.0, 0.0)), ({'scale_factor': 12000, 'threads': 12, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (3899520.0, 0.0)), ({'scale_factor': 12000, 'threads': 12, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (2412830.0, 0.0)), ({'scale_factor': 16000, 'threads': 16, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (4281320.0, 0.0)), ({'scale_factor': 16000, 'threads': 16, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (2834350.0, 0.0)), ({'scale_factor': 20000, 'threads': 20, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (4407900.0, 0.0)), ({'scale_factor': 20000, 'threads': 20, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (3180140.0, 0.0)), ({'scale_factor': 24000, 'threads': 24, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (4469700.0, 0.0)), ({'scale_factor': 24000, 'threads': 24, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (3413230.0, 0.0)), ({'scale_factor': 28000, 'threads': 28, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (4511650.0, 0.0)), ({'scale_factor': 28000, 'threads': 28, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (4222430.0, 0.0)), ({'scale_factor': 32000, 'threads': 32, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (4969290.0, 0.0)), ({'scale_factor': 32000, 'threads': 32, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (3812400.0, 0.0166666)), ({'scale_factor': 1, 'threads': 1, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (28786.0, 0.0)), ({'scale_factor': 1, 'threads': 1, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (11423.1, 0.0)), ({'scale_factor': 4, 'threads': 4, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (101236.0, 0.0)), ({'scale_factor': 4, 'threads': 4, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (43745.5, 0.583332)), ({'scale_factor': 8, 'threads': 8, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (200612.0, 0.0)), ({'scale_factor': 8, 'threads': 8, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (88838.5, 1.24999)), ({'scale_factor': 12, 'threads': 12, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (287726.0, 0.0)), ({'scale_factor': 12, 'threads': 12, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (124150.0, 1.63333)), ({'scale_factor': 16, 'threads': 16, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (373223.0, 0.0)), ({'scale_factor': 16, 'threads': 16, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (165641.0, 2.25)), ({'scale_factor': 20, 'threads': 20, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (469325.0, 0.0)), ({'scale_factor': 20, 'threads': 20, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (203462.0, 2.63333)), ({'scale_factor': 24, 'threads': 24, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (542229.0, 0.0)), ({'scale_factor': 24, 'threads': 24, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (237899.0, 2.84999)), ({'scale_factor': 28, 'threads': 28, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (604902.0, 0.0)), ({'scale_factor': 28, 'threads': 28, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (268282.0, 3.06666)), ({'scale_factor': 32, 'threads': 32, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (649687.0, 0.0)), ({'scale_factor': 32, 'threads': 32, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (245272.0, 2.76666))]
diff --git a/silo/benchmarks/results/istc11-3-16-13.py b/silo/benchmarks/results/istc11-3-16-13.py
new file mode 100644 (file)
index 0000000..bcc9780
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'scale_factor': 1000, 'threads': 1, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (455923.0, 0.0)), ({'scale_factor': 1000, 'threads': 1, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (392189.0, 0.0)), ({'scale_factor': 4000, 'threads': 4, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (1837830.0, 0.0)), ({'scale_factor': 4000, 'threads': 4, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (1386150.0, 0.0)), ({'scale_factor': 8000, 'threads': 8, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (3117300.0, 0.0)), ({'scale_factor': 8000, 'threads': 8, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (2378310.0, 0.0)), ({'scale_factor': 12000, 'threads': 12, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (3941100.0, 0.0)), ({'scale_factor': 12000, 'threads': 12, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (3129000.0, 0.0)), ({'scale_factor': 16000, 'threads': 16, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (4299420.0, 0.0)), ({'scale_factor': 16000, 'threads': 16, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (3477480.0, 0.0)), ({'scale_factor': 20000, 'threads': 20, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (4436690.0, 0.0)), ({'scale_factor': 20000, 'threads': 20, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (3591450.0, 0.0)), ({'scale_factor': 24000, 'threads': 24, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (4492090.0, 0.0)), ({'scale_factor': 24000, 'threads': 24, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (3583380.0, 0.0)), ({'scale_factor': 28000, 'threads': 28, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (4523280.0, 0.0)), ({'scale_factor': 28000, 'threads': 28, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (3737430.0, 0.0)), ({'scale_factor': 32000, 'threads': 32, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, (4557360.0, 0.0)), ({'scale_factor': 32000, 'threads': 32, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, (4139190.0, 0.0)), ({'scale_factor': 1, 'threads': 1, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (28194.3, 0.0)), ({'scale_factor': 1, 'threads': 1, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (15643.4, 0.0)), ({'scale_factor': 4, 'threads': 4, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (103030.0, 0.0)), ({'scale_factor': 4, 'threads': 4, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (58260.7, 0.866664)), ({'scale_factor': 8, 'threads': 8, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (199311.0, 0.0)), ({'scale_factor': 8, 'threads': 8, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (115993.0, 1.83333)), ({'scale_factor': 12, 'threads': 12, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (288046.0, 0.0)), ({'scale_factor': 12, 'threads': 12, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (161253.0, 2.68333)), ({'scale_factor': 16, 'threads': 16, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (369982.0, 0.0)), ({'scale_factor': 16, 'threads': 16, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (214555.0, 3.24999)), ({'scale_factor': 20, 'threads': 20, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (458774.0, 0.0)), ({'scale_factor': 20, 'threads': 20, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (260806.0, 3.78332)), ({'scale_factor': 24, 'threads': 24, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (544124.0, 0.0)), ({'scale_factor': 24, 'threads': 24, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (296078.0, 4.59998)), ({'scale_factor': 28, 'threads': 28, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (616619.0, 0.0)), ({'scale_factor': 28, 'threads': 28, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (320886.0, 5.46665)), ({'scale_factor': 32, 'threads': 32, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, (646355.0, 0.0)), ({'scale_factor': 32, 'threads': 32, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, (295248.0, 4.09999))]
diff --git a/silo/benchmarks/results/istc11-3-18-13.py b/silo/benchmarks/results/istc11-3-18-13.py
new file mode 100644 (file)
index 0000000..dfdcdb0
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'scale_factor': 1000, 'threads': 1, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(436120.0, 0.0), (418455.0, 0.0), (450830.0, 0.0)]), ({'scale_factor': 1000, 'threads': 1, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(278658.0, 0.0), (358839.0, 0.0), (326228.0, 0.0)]), ({'scale_factor': 4000, 'threads': 4, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(1830520.0, 0.0), (1811250.0, 0.0), (1811350.0, 0.0)]), ({'scale_factor': 4000, 'threads': 4, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(1155860.0, 0.0), (1131700.0, 0.0), (1180550.0, 0.0)]), ({'scale_factor': 8000, 'threads': 8, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(3094700.0, 0.0), (3015630.0, 0.0), (3017340.0, 0.0)]), ({'scale_factor': 8000, 'threads': 8, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(2166540.0, 0.0), (2206350.0, 0.0), (2134760.0, 0.0)]), ({'scale_factor': 12000, 'threads': 12, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(3916050.0, 0.0), (3915280.0, 0.0), (3921000.0, 0.0)]), ({'scale_factor': 12000, 'threads': 12, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(2957350.0, 0.0), (2979110.0, 0.0), (2964590.0, 0.0)]), ({'scale_factor': 16000, 'threads': 16, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(4322820.0, 0.0), (4304250.0, 0.0), (4326410.0, 0.0)]), ({'scale_factor': 16000, 'threads': 16, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(3465220.0, 0.0), (3494080.0, 0.0), (3851230.0, 0.0)]), ({'scale_factor': 20000, 'threads': 20, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(4448970.0, 0.0), (4432920.0, 0.0), (4451670.0, 0.0)]), ({'scale_factor': 20000, 'threads': 20, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(4660560.0, 0.0), (3694510.0, 0.0), (3621290.0, 0.0)]), ({'scale_factor': 24000, 'threads': 24, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(4504350.0, 0.0), (6451530.0, 0.0), (4504910.0, 0.0)]), ({'scale_factor': 24000, 'threads': 24, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(3701890.0, 0.0), (4056880.0, 0.0), (5237840.0, 0.0)]), ({'scale_factor': 28000, 'threads': 28, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(4549070.0, 0.0), (4551480.0, 0.0), (7400250.0, 0.0)]), ({'scale_factor': 28000, 'threads': 28, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(3981770.0, 0.0), (3546130.0, 0.0), (3529950.0, 0.0)]), ({'scale_factor': 32000, 'threads': 32, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(7948560.0, 0.0), (7945880.0, 0.0), (4566300.0, 0.0)]), ({'scale_factor': 32000, 'threads': 32, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(3898920.0, 0.0166666), (3907880.0, 0.0), (3321670.0, 0.0)]), ({'scale_factor': 1, 'threads': 1, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, [(30405.5, 0.0), (30499.0, 0.0), (30028.5, 0.0)]), ({'scale_factor': 1, 'threads': 1, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(16356.8, 0.433332), (15986.1, 0.283333), (16439.4, 0.399999)]), ({'scale_factor': 4, 'threads': 4, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, [(111137.0, 0.0), (108277.0, 0.0), (109730.0, 0.0)]), ({'scale_factor': 4, 'threads': 4, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(66322.5, 1.75), (66222.7, 2.03333), (63792.9, 1.64999)]), ({'scale_factor': 8, 'threads': 8, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, [(214859.0, 0.0), (214484.0, 0.0), (215524.0, 0.0)]), ({'scale_factor': 8, 'threads': 8, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(128448.0, 3.14999), (129981.0, 3.06666), (129171.0, 3.04999)]), ({'scale_factor': 12, 'threads': 12, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, [(300235.0, 0.0), (306062.0, 0.0), (307826.0, 0.0)]), ({'scale_factor': 12, 'threads': 12, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(187376.0, 4.38332), (188755.0, 4.48332), (187961.0, 4.49999)]), ({'scale_factor': 16, 'threads': 16, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, [(404846.0, 0.0), (396609.0, 0.0), (407262.0, 0.0)]), ({'scale_factor': 16, 'threads': 16, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(249271.0, 5.71665), (246597.0, 4.98331), (243792.0, 5.83332)]), ({'scale_factor': 20, 'threads': 20, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, [(496558.0, 0.0), (503799.0, 0.0), (503256.0, 0.0)]), ({'scale_factor': 20, 'threads': 20, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(304026.0, 6.29998), (304226.0, 6.81666), (295475.0, 5.99998)]), ({'scale_factor': 24, 'threads': 24, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, [(587429.0, 0.0), (584843.0, 0.0), (590804.0, 0.0)]), ({'scale_factor': 24, 'threads': 24, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(351511.0, 6.81664), (361679.0, 8.11663), (358653.0, 7.74997)]), ({'scale_factor': 28, 'threads': 28, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, [(670600.0, 0.0), (662400.0, 0.0), (668818.0, 0.0)]), ({'scale_factor': 28, 'threads': 28, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(409829.0, 8.28332), (408729.0, 8.54998), (406639.0, 7.51665)]), ({'scale_factor': 32, 'threads': 32, 'txn_flags': 1, 'db': 'kvdb', 'bench': 'tpcc'}, [(694132.0, 0.0), (701495.0, 0.0), (707058.0, 0.0)]), ({'scale_factor': 32, 'threads': 32, 'txn_flags': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(390649.0, 5.61666), (390995.0, 6.08332), (387345.0, 5.94999)])]
diff --git a/silo/benchmarks/results/istc11-3-21-13.py b/silo/benchmarks/results/istc11-3-21-13.py
new file mode 100644 (file)
index 0000000..e63b1a4
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'bench_opts': '', 'scale_factor': 320000, 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 1}, [(341977.0, 0.0), (367991.0, 0.0), (342608.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 4}, [(1565190.0, 0.0), (1565550.0, 0.0), (1563210.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 8}, [(3193760.0, 0.0), (3182240.0, 0.0), (3188560.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 12}, [(4780000.0, 0.0), (4767620.0, 0.0), (4771070.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 16}, [(6332840.0, 0.0), (6328970.0, 0.0), (6334500.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 20}, [(7872050.0, 0.0), (7871110.0, 0.0), (7845550.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 24}, [(9363600.0, 0.0), (9368290.0, 0.0), (9366990.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 28}, [(10832500.0, 0.0), (10770300.0, 0.0), (10818600.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 32}, [(11856400.0, 0.0), (11855900.0, 0.0), (11865400.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 1}, [(323784.0, 0.0), (321806.0, 0.0), (322916.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 4}, [(1385090.0, 0.0), (1391820.0, 0.0), (1344820.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 8}, [(2827340.0, 0.0), (2732100.0, 0.0), (2758880.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 12}, [(4209050.0, 0.0), (4182500.0, 0.0), (4193630.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 16}, [(5485600.0, 0.0), (5500570.0, 0.0333328), (5532810.0, 0.0166665)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 20}, [(6959520.0, 0.0), (6969320.0, 0.0166664), (6948200.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 24}, [(8319120.0, 0.0), (8340050.0, 0.0333328), (8297860.0, 0.0333328)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 28}, [(9631680.0, 0.0), (9588000.0, 0.0333328), (9622120.0, 0.0333327)]), ({'bench_opts': '', 'scale_factor': 320000, 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 32}, [(10263300.0, 0.0166629), (10300700.0, 0.0333262), (10163800.0, 0.0499888)]), ({'bench_opts': '--new-order-remote-item-pct 0', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(440703.0, 0.0), (435462.0, 0.0), (449485.0, 0.0)]), ({'bench_opts': '--new-order-remote-item-pct 1', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(434779.0, 68.3486), (438273.0, 69.6653), (442467.0, 69.2987)]), ({'bench_opts': '--new-order-remote-item-pct 2', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(445738.0, 142.23), (435539.0, 136.43), (430208.0, 135.364)]), ({'bench_opts': '--new-order-remote-item-pct 3', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(435363.0, 202.596), (431492.0, 204.33), (447837.0, 213.629)]), ({'bench_opts': '--new-order-remote-item-pct 4', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(430948.0, 266.161), (441064.0, 273.478), (431624.0, 272.662)]), ({'bench_opts': '--new-order-remote-item-pct 5', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(436018.0, 340.293), (438748.0, 339.76), (438044.0, 338.56)]), ({'bench_opts': '--new-order-remote-item-pct 6', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(431446.0, 400.741), (434324.0, 402.438), (436072.0, 405.976)]), ({'bench_opts': '--new-order-remote-item-pct 7', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(429735.0, 463.173), (440026.0, 472.789), (426122.0, 457.674)]), ({'bench_opts': '--new-order-remote-item-pct 8', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(425216.0, 521.456), (438042.0, 535.771), (430484.0, 529.554)]), ({'bench_opts': '--new-order-remote-item-pct 9', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(439448.0, 602.687), (436484.0, 596.338), (442301.0, 608.353)]), ({'bench_opts': '--new-order-remote-item-pct 10', 'scale_factor': 28, 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(434582.0, 661.104), (424904.0, 634.071), (434322.0, 665.07)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 0', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(758259.0, 0.0), (771913.0, 0.0), (763892.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 1', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(645656.0, 0.0), (650949.0, 0.0), (627824.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 2', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(536405.0, 0.0), (531694.0, 0.0), (537912.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 3', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(443490.0, 0.0), (432826.0, 0.0), (441318.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 4', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(368602.0, 0.0), (352058.0, 0.0), (368116.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 5', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(306356.0, 0.0), (308941.0, 0.0), (310371.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 6', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(263430.0, 0.0), (250817.0, 0.0), (263369.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 7', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(227992.0, 0.0), (216511.0, 0.0), (226312.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 8', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(197707.0, 0.0), (196394.0, 0.0), (197256.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 9', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(177286.0, 0.0), (177743.0, 0.0), (175348.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 10', 'scale_factor': 28, 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(157529.0, 0.0), (159431.0, 0.0), (158633.0, 0.0)])]
diff --git a/silo/benchmarks/results/istc11-3-22-13.py b/silo/benchmarks/results/istc11-3-22-13.py
new file mode 100644 (file)
index 0000000..a51eeed
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 1}, [(344319.0, 0.0), (354514.0, 0.0), (342661.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 4}, [(1572150.0, 0.0), (1562970.0, 0.0), (1565110.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 8}, [(3194780.0, 0.0), (3192960.0, 0.0), (3188600.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 12}, [(4782170.0, 0.0), (4773360.0, 0.0), (4767710.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 16}, [(6333480.0, 0.0), (6326960.0, 0.0), (6349480.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 20}, [(7879620.0, 0.0), (7876960.0, 0.0), (7868610.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 24}, [(9375300.0, 0.0), (9369260.0, 0.0), (9355660.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 28}, [(10824800.0, 0.0), (10814600.0, 0.0), (10805100.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 32}, [(11893900.0, 0.0), (11970300.0, 0.0), (11848300.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 1}, [(344057.0, 0.0), (330148.0, 0.0), (333267.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 4}, [(1501350.0, 0.0), (1481720.0, 0.0), (1491190.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 8}, [(3041380.0, 0.0), (3022010.0, 0.0), (3054820.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 12}, [(4566850.0, 0.0), (4575880.0, 0.0), (4575180.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 16}, [(6081740.0, 0.0), (6057220.0, 0.0166665), (6088750.0, 0.0166665)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 20}, [(7521460.0, 0.0), (7519680.0, 0.0), (7541440.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 24}, [(8985640.0, 0.0), (8971310.0, 0.0), (8973110.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 28}, [(10429500.0, 0.0833324), (10437100.0, 0.0), (10428400.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 32}, [(11046300.0, 0.0), (11080000.0, 0.0166646), (11123100.0, 0.016663)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 0', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(505953.0, 0.0), (508367.0, 0.0), (531330.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 1', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(539975.0, 83.5486), (539597.0, 83.1168), (530897.0, 84.1982)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 2', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(529145.0, 163.396), (537027.0, 169.68), (531671.0, 165.198)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 3', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(526006.0, 243.896), (531250.0, 245.114), (515408.0, 241.297)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 4', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(526523.0, 326.51), (519784.0, 320.029), (534266.0, 329.362)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 5', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(533564.0, 408.844), (530472.0, 406.311), (532288.0, 407.412)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 6', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(525542.0, 479.861), (533309.0, 491.876), (536782.0, 486.96)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 7', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(531937.0, 564.39), (518706.0, 553.174), (526912.0, 561.458)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 8', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(523326.0, 631.139), (521117.0, 626.808), (519460.0, 629.224)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 9', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(531315.0, 720.686), (518967.0, 704.337), (518784.0, 696.975)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 10', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(525105.0, 781.123), (517552.0, 777.807), (527545.0, 785.624)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 0', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(832667.0, 0.0), (812928.0, 0.0), (828543.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 1', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(664056.0, 0.0), (671050.0, 0.0), (700404.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 2', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(562333.0, 0.0), (586266.0, 0.0), (560772.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 3', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(484997.0, 0.0), (458707.0, 0.0), (482848.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 4', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(383788.0, 0.0), (385848.0, 0.0), (383601.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 5', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(318259.0, 0.0), (318550.0, 0.0), (320540.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 6', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(274341.0, 0.0), (284535.0, 0.0), (266393.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 7', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(243409.0, 0.0), (235239.0, 0.0), (245459.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 8', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(212585.0, 0.0), (206563.0, 0.0), (202268.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 9', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(191315.0, 0.0), (191117.0, 0.0), (183958.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 10', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(171544.0, 0.0), (161109.0, 0.0), (161529.0, 0.0)]), ({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks', 'scale_factor': 8, 'name': 'multipart:cpu', 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 8}, [(222715.0, 0.0), (232206.0, 0.0), (223868.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 8, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 8}, [(193922.0, 9.41657), (192451.0, 9.36656), (194744.0, 9.98324)]), ({'bench_opts': '', 'scale_factor': 12, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 8}, [(190925.0, 5.73328), (190402.0, 5.54995), (184899.0, 5.91661)]), ({'bench_opts': '', 'scale_factor': 16, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 8}, [(186043.0, 4.2333), (191044.0, 4.29997), (193370.0, 4.98329)]), ({'bench_opts': '', 'scale_factor': 20, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 8}, [(192382.0, 3.21664), (193473.0, 3.53331), (188681.0, 3.49997)]), ({'bench_opts': '', 'scale_factor': 24, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 8}, [(194884.0, 2.89997), (192628.0, 3.09996), (190728.0, 3.04998)]), ({'bench_opts': '', 'scale_factor': 28, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 8}, [(188494.0, 2.39998), (190250.0, 2.21664), (188596.0, 2.66664)]), ({'bench_opts': '', 'scale_factor': 32, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 8}, [(187125.0, 2.14998), (190069.0, 2.14998), (182439.0, 2.01665)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 0', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(171620.0, 2134.06), (173529.0, 2186.03), (173225.0, 2138.29)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 20', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(169040.0, 2289.85), (171705.0, 2262.18), (170010.0, 2311.37)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 40', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(171233.0, 2310.86), (169888.0, 2288.3), (169092.0, 2317.81)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 60', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(167489.0, 2295.77), (168658.0, 2328.69), (167674.0, 2283.77)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 80', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(166622.0, 2321.01), (168422.0, 2335.13), (167353.0, 2352.83)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 100', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(166810.0, 2291.52), (167038.0, 2285.16), (167169.0, 2331.86)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 0', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(150297.0, 13787.1), (150142.0, 13767.5), (150083.0, 13777.7)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 20', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(148402.0, 15224.0), (147885.0, 15174.4), (147474.0, 15163.6)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 40', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(146138.0, 16536.9), (147086.0, 16641.2), (146483.0, 16522.5)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 60', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(144554.0, 17776.3), (142998.0, 17571.6), (144150.0, 17711.9)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 80', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(142847.0, 18846.9), (141997.0, 18745.8), (142227.0, 18762.5)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 100', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(140923.0, 19884.2), (140449.0, 19816.0), (140712.0, 19868.4)])]
diff --git a/silo/benchmarks/results/istc11-3-23-13.py b/silo/benchmarks/results/istc11-3-23-13.py
new file mode 100644 (file)
index 0000000..a1da02a
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'bench_opts': '--enable-separate-tree-per-partition --enable-partition-locks', 'scale_factor': 8, 'name': 'multipart:cpu', 'db': 'kvdb', 'bench': 'tpcc', 'par_load': True, 'threads': 8}, [(222921.0, 0.0), (227359.0, 0.0), (229843.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 8, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 8}, [(195168.0, 9.73322), (194644.0, 9.84993), (194702.0, 9.44992)]), ({'bench_opts': '', 'scale_factor': 8, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 12}, [(237444.0, 37277.3), (234301.0, 36610.4), (236327.0, 36780.5)]), ({'bench_opts': '', 'scale_factor': 8, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(284964.0, 73789.8), (290414.0, 74756.3), (276865.0, 71355.9)]), ({'bench_opts': '', 'scale_factor': 8, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 20}, [(301047.0, 123422.0), (282959.0, 115540.0), (287034.0, 115244.0)]), ({'bench_opts': '', 'scale_factor': 8, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 24}, [(296876.0, 159299.0), (298336.0, 159218.0), (302464.0, 162004.0)]), ({'bench_opts': '', 'scale_factor': 8, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(246765.0, 157871.0), (270421.0, 171978.0), (254094.0, 160962.0)]), ({'bench_opts': '', 'scale_factor': 8, 'name': 'multipart:cpu', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 32}, [(230114.0, 167878.0), (226383.0, 165009.0), (227876.0, 165982.0)])]
diff --git a/silo/benchmarks/results/istc11-3-26-13.py b/silo/benchmarks/results/istc11-3-26-13.py
new file mode 100644 (file)
index 0000000..febf830
--- /dev/null
@@ -0,0 +1,4 @@
+RESULTS = [({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 1}, [(368896.0, 0.0), (370812.0, 0.0), (340529.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 4}, [(1557670.0, 0.0), (1557680.0, 0.0), (1558510.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 8}, [(3182470.0, 0.0), (3181050.0, 0.0), (3177240.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 12}, [(4754210.0, 0.0), (4758890.0, 0.0), (4768010.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 16}, [(6327650.0, 0.0), (6335970.0, 0.0), (6323000.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 20}, [(7651490.0, 0.0), (7859290.0, 0.0), (7851350.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 24}, [(9338320.0, 0.0), (9334100.0, 0.0), (9337990.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 28}, [(10809400.0, 0.0), (10762300.0, 0.0), (10782400.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'threads': 32}, [(11635500.0, 0.0), (11909600.0, 0.0), (11829800.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 1}, [(362783.0, 0.0), (362939.0, 0.0), (362555.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 4}, [(1530310.0, 0.0), (1547110.0, 0.0), (1562350.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 8}, [(3147020.0, 0.0), (3154120.0, 0.0), (3156800.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 12}, [(4703160.0, 0.0), (4718940.0, 0.0), (4615850.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 16}, [(6252960.0, 0.0), (6272330.0, 0.0), (6262620.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 20}, [(7775340.0, 0.033333), (7805900.0, 0.0), (7790730.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 24}, [(9292160.0, 0.0), (9296380.0, 0.0), (9289300.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 28}, [(10734600.0, 0.0), (10742600.0, 0.0), (10724200.0, 0.0)]), ({'bench_opts': '', 'scale_factor': 320000, 'name': 'scale', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'threads': 32}, [(11442700.0, 0.0), (11409800.0, 0.0), (11418000.0, 0.0166631)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 0', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(559985.0, 0.0), (554159.0, 0.0), (560124.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 1', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(563669.0, 86.8307), (550329.0, 81.4322), (558763.0, 83.9809)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 2', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(552469.0, 168.415), (560887.0, 171.246), (558669.0, 169.694)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 3', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(536695.0, 248.114), (559353.0, 256.428), (549388.0, 252.111)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 4', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(551636.0, 332.724), (557507.0, 332.662), (554321.0, 331.291)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 5', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(553094.0, 415.344), (553564.0, 411.806), (556768.0, 413.706)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 6', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(539732.0, 483.26), (551578.0, 493.237), (523114.0, 471.342)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 7', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(550531.0, 569.523), (539723.0, 562.572), (551360.0, 572.741)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 8', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(542719.0, 643.342), (549563.0, 643.558), (546139.0, 648.14)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 9', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(548901.0, 730.787), (540353.0, 715.709), (542625.0, 724.837)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 10', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 28}, [(547367.0, 796.404), (550785.0, 803.884), (539808.0, 785.229)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 0', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(842114.0, 0.0), (838839.0, 0.0), (845235.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 1', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(667442.0, 0.0), (665713.0, 0.0), (675465.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 2', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(536509.0, 0.0), (539068.0, 0.0), (546692.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 3', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(437646.0, 0.0), (437500.0, 0.0), (444910.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 4', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(342401.0, 0.0), (348083.0, 0.0), (351640.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 5', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(307548.0, 0.0), (311420.0, 0.0), (308924.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 6', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(255155.0, 0.0), (265231.0, 0.0), (264143.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 7', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(232640.0, 0.0), (230824.0, 0.0), (228088.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 8', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(204345.0, 0.0), (206614.0, 0.0), (192869.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 9', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(180656.0, 0.0), (185980.0, 0.0), (184886.0, 0.0)]), ({'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 10', 'scale_factor': 28, 'name': 'multipart:pct', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': True, 'threads': 28}, [(166456.0, 0.0), (160836.0, 0.0), (161666.0, 0.0)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 0', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(178026.0, 2137.24), (178581.0, 2116.92), (177426.0, 2175.65)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 20', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(176774.0, 2222.03), (176332.0, 2189.11), (176691.0, 2223.81)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 40', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(174556.0, 2272.04), (175010.0, 2263.7), (172122.0, 2313.65)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 60', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(172754.0, 2280.72), (173202.0, 2300.94), (173661.0, 2303.13)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 80', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(173194.0, 2308.66), (171923.0, 2312.56), (172893.0, 2318.47)]), ({'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 100', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(172705.0, 2295.76), (171586.0, 2302.47), (172432.0, 2308.46)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 0', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(155424.0, 14688.1), (154900.0, 14657.8), (153882.0, 14555.3)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 20', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(152169.0, 16301.0), (151600.0, 16152.8), (153404.0, 16359.3)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 40', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(151897.0, 17950.7), (150753.0, 17881.1), (148796.0, 17610.6)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 60', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(146694.0, 18958.8), (146309.0, 18870.3), (146731.0, 18757.5)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 80', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(146141.0, 20348.6), (145702.0, 20284.8), (146323.0, 20411.8)]), ({'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 100', 'scale_factor': 8, 'name': 'readonly', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'threads': 16}, [(142882.0, 21250.3), (144235.0, 21529.0), (143130.0, 21315.2)])]
+
+
+
diff --git a/silo/benchmarks/results/istc11-4-10-13.py b/silo/benchmarks/results/istc11-4-10-13.py
new file mode 100644 (file)
index 0000000..6dfc5f3
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 0', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(804585.0, 0.0), (801148.0, 0.0), (807541.0, 0.0)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 1', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(801033.0, 122.895), (799989.0, 122.113), (803801.0, 122.846)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 2', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(799259.0, 242.918), (797091.0, 242.774), (794599.0, 242.152)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 3', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(790597.0, 357.701), (790143.0, 361.526), (789851.0, 355.109)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 4', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(784611.0, 470.576), (785424.0, 475.99), (784797.0, 475.866)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 5', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(776102.0, 578.822), (782605.0, 587.097), (784011.0, 591.513)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 6', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(775516.0, 695.638), (777636.0, 694.746), (774385.0, 692.662)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 7', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(776174.0, 812.69), (769456.0, 800.863), (769434.0, 798.308)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 8', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(772895.0, 918.994), (772724.0, 916.723), (775404.0, 916.713)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 9', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(766380.0, 1014.59), (772520.0, 1021.4), (769013.0, 1013.95)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 10', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(764523.0, 1123.01), (769060.0, 1128.28), (762434.0, 1117.84)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 0', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(1094020.0, 0.0), (1110840.0, 0.0), (1075520.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 1', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(826353.0, 0.0), (852781.0, 0.0), (845913.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 2', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(671993.0, 0.0), (706678.0, 0.0), (656195.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 3', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(550780.0, 0.0), (554407.0, 0.0), (536970.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 4', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(440937.0, 0.0), (458112.0, 0.0), (460816.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 5', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(389108.0, 0.0), (391405.0, 0.0), (390824.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 6', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(337935.0, 0.0), (336006.0, 0.0), (342643.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 7', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(300376.0, 0.0), (288345.0, 0.0), (305941.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 8', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(261991.0, 0.0), (269196.0, 0.0), (261985.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 9', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(237309.0, 0.0), (235877.0, 0.0), (231598.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 10', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(214308.0, 0.0), (221298.0, 0.0), (213673.0, 0.0)])]
diff --git a/silo/benchmarks/results/istc11-5-18-13-tpcc-chains.txt b/silo/benchmarks/results/istc11-5-18-13-tpcc-chains.txt
new file mode 100644 (file)
index 0000000..d4af9af
--- /dev/null
@@ -0,0 +1,108 @@
+chain_1 : 80781843
+chain_10 : 69583
+chain_100 : 30
+chain_101 : 27
+chain_102 : 21
+chain_103 : 14
+chain_104 : 14
+chain_105 : 5
+chain_106 : 5
+chain_107 : 3
+chain_108 : 1
+chain_11 : 54797
+chain_12 : 50165
+chain_13 : 53632
+chain_14 : 62206
+chain_15 : 72109
+chain_16 : 79712
+chain_17 : 82721
+chain_18 : 80659
+chain_19 : 73692
+chain_2 : 210630340
+chain_20 : 62250
+chain_21 : 50632
+chain_22 : 37955
+chain_23 : 28385
+chain_24 : 20306
+chain_25 : 14883
+chain_26 : 11299
+chain_27 : 9796
+chain_28 : 9530
+chain_29 : 10319
+chain_3 : 229266
+chain_30 : 12767
+chain_31 : 15921
+chain_32 : 20561
+chain_33 : 26589
+chain_34 : 33385
+chain_35 : 39834
+chain_36 : 46231
+chain_37 : 50744
+chain_38 : 52893
+chain_39 : 51505
+chain_4 : 184648
+chain_40 : 47786
+chain_41 : 42079
+chain_42 : 34178
+chain_43 : 27086
+chain_44 : 19801
+chain_45 : 14068
+chain_46 : 9711
+chain_47 : 6562
+chain_48 : 4925
+chain_49 : 4063
+chain_5 : 159018
+chain_50 : 3799
+chain_51 : 4126
+chain_52 : 5216
+chain_53 : 6829
+chain_54 : 10044
+chain_55 : 15948
+chain_56 : 26110
+chain_57 : 38423
+chain_58 : 49675
+chain_59 : 53167
+chain_6 : 148064
+chain_60 : 45919
+chain_61 : 33058
+chain_62 : 33117
+chain_63 : 36589
+chain_64 : 31232
+chain_65 : 21209
+chain_66 : 12718
+chain_67 : 8052
+chain_68 : 5531
+chain_69 : 3822
+chain_7 : 136580
+chain_70 : 2612
+chain_71 : 1669
+chain_72 : 959
+chain_73 : 622
+chain_74 : 489
+chain_75 : 456
+chain_76 : 500
+chain_77 : 506
+chain_78 : 499
+chain_79 : 439
+chain_8 : 116110
+chain_80 : 347
+chain_81 : 272
+chain_82 : 199
+chain_83 : 127
+chain_84 : 87
+chain_85 : 50
+chain_86 : 22
+chain_87 : 10
+chain_88 : 8
+chain_89 : 9
+chain_9 : 92385
+chain_90 : 4
+chain_91 : 3
+chain_92 : 8
+chain_93 : 15
+chain_94 : 25
+chain_95 : 27
+chain_96 : 24
+chain_97 : 29
+chain_98 : 39
+chain_99 : 35
diff --git a/silo/benchmarks/results/istc11-5-18-13-ycsb-chains.txt b/silo/benchmarks/results/istc11-5-18-13-ycsb-chains.txt
new file mode 100644 (file)
index 0000000..e59bbe0
--- /dev/null
@@ -0,0 +1,9 @@
+chain_1 : 205228249
+chain_2 : 91357162
+chain_3 : 20138902
+chain_4 : 2929173
+chain_5 : 317410
+chain_6 : 27081
+chain_7 : 1901
+chain_8 : 113
+chain_9 : 9
diff --git a/silo/benchmarks/results/istc11-5-18-13.py b/silo/benchmarks/results/istc11-5-18-13.py
new file mode 100644 (file)
index 0000000..e6c4ec9
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '101G', 'threads': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(620600.0, 0.0), (621420.0, 0.0), (622727.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '101G', 'threads': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(605937.0, 0.0), (606707.0, 0.0), (615925.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '101G', 'threads': 1, 'db': 'kvdb', 'bench': 'ycsb'}, [(518197.0, 0.0), (518351.0, 0.0), (517762.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '101G', 'threads': 1, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(516004.0, 0.0), (515056.0, 0.0), (515394.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '105G', 'threads': 4, 'db': 'kvdb', 'bench': 'ycsb'}, [(2507000.0, 0.0), (2515440.0, 0.0), (2515880.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '105G', 'threads': 4, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(2440110.0, 0.0), (2438170.0, 0.0), (2444660.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '105G', 'threads': 4, 'db': 'kvdb', 'bench': 'ycsb'}, [(2103950.0, 0.0), (2108650.0, 0.0), (2101390.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '105G', 'threads': 4, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(2021630.0, 0.0), (2051260.0, 0.0), (2062360.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '111G', 'threads': 8, 'db': 'kvdb', 'bench': 'ycsb'}, [(4698460.0, 0.0), (4701020.0, 0.0), (4697040.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '111G', 'threads': 8, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(4594410.0, 0.0), (4585480.0, 0.0), (4585570.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '111G', 'threads': 8, 'db': 'kvdb', 'bench': 'ycsb'}, [(3953090.0, 0.0), (3952270.0, 0.0), (3956260.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '111G', 'threads': 8, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(3893480.0, 0.0166664), (3832850.0, 0.0), (3888720.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '116G', 'threads': 12, 'db': 'kvdb', 'bench': 'ycsb'}, [(6420760.0, 0.0), (6438670.0, 0.0), (6433960.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '116G', 'threads': 12, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(6363770.0, 0.0), (6379600.0, 0.0), (6389300.0, 0.0166661)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '116G', 'threads': 12, 'db': 'kvdb', 'bench': 'ycsb'}, [(5401450.0, 0.0), (5407930.0, 0.0), (5392230.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '116G', 'threads': 12, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(5402250.0, 0.0333321), (5376760.0, 0.0166661), (5390240.0, 0.0333322)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '122G', 'threads': 16, 'db': 'kvdb', 'bench': 'ycsb'}, [(8338980.0, 0.0), (8334610.0, 0.0), (8328680.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '122G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(8257480.0, 0.0), (8226600.0, 0.0), (8277980.0, 0.0333317)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '122G', 'threads': 16, 'db': 'kvdb', 'bench': 'ycsb'}, [(6984660.0, 0.0), (6980250.0, 0.0), (6980670.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '122G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(6999110.0, 0.0166657), (6994190.0, 0.0166658), (6998980.0, 0.0166659)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '128G', 'threads': 20, 'db': 'kvdb', 'bench': 'ycsb'}, [(10199100.0, 0.0), (10189900.0, 0.0), (10186000.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '128G', 'threads': 20, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(10127800.0, 0.0), (10161500.0, 0.0), (10109000.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '128G', 'threads': 20, 'db': 'kvdb', 'bench': 'ycsb'}, [(8543690.0, 0.0), (8551340.0, 0.0), (8535590.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '128G', 'threads': 20, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(8579520.0, 0.049996), (8561890.0, 0.0333303), (8576020.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '133G', 'threads': 24, 'db': 'kvdb', 'bench': 'ycsb'}, [(11904400.0, 0.0), (11904800.0, 0.0), (11895800.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '133G', 'threads': 24, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(11820400.0, 0.0), (11836000.0, 0.0166648), (11816400.0, 0.0166651)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '133G', 'threads': 24, 'db': 'kvdb', 'bench': 'ycsb'}, [(9960240.0, 0.0), (9946770.0, 0.0), (9967100.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '133G', 'threads': 24, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(10030400.0, 0.0999886), (10022700.0, 0.0499943), (10023500.0, 0.0166643)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '139G', 'threads': 28, 'db': 'kvdb', 'bench': 'ycsb'}, [(14055700.0, 0.0), (14064700.0, 0.0), (14048200.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '139G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(13991000.0, 0.0), (13987400.0, 0.0), (13974900.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '139G', 'threads': 28, 'db': 'kvdb', 'bench': 'ycsb'}, [(11775200.0, 0.0), (11773500.0, 0.0), (11763400.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '139G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(11841300.0, 0.0333278), (11859000.0, 0.099985), (11843500.0, 0.0499928)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '144G', 'threads': 32, 'db': 'kvdb', 'bench': 'ycsb'}, [(15886600.0, 0.0), (15883900.0, 0.0), (15914600.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '144G', 'threads': 32, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(15709800.0, 0.0166588), (15721400.0, 0.0166599), (15791500.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '144G', 'threads': 32, 'db': 'kvdb', 'bench': 'ycsb'}, [(13298200.0, 0.0), (13284200.0, 0.0), (13316600.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '144G', 'threads': 32, 'db': 'ndb-proto2', 'bench': 'ycsb'}, [(13258000.0, 0.133309), (13318500.0, 0.116649), (13318900.0, 0.14997)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 1, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 1, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(30985.9, 0.0), (29673.8, 0.0166664), (32070.4, 0.0)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 4, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 4, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(112760.0, 5.03329), (112690.0, 5.29995), (113504.0, 4.89996)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 8, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 8, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(208462.0, 8.96661), (212875.0, 10.0832), (212539.0, 9.33326)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 12, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 12, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(325661.0, 14.4332), (328256.0, 13.6332), (327681.0, 14.5498)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 16, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(430089.0, 19.7165), (421372.0, 18.4498), (432434.0, 17.8832)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 20, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 20, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(543340.0, 23.1331), (545883.0, 23.9497), (546608.0, 23.5831)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 24, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 24, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(648722.0, 29.233), (633469.0, 26.3663), (644658.0, 27.2329)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 28, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(750691.0, 34.5494), (743953.0, 32.9328), (741685.0, 32.2494)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 32, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 32, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(810975.0, 35.2974), (813899.0, 36.0823), (803711.0, 35.4822)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 0', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(787305.0, 0.0), (783427.0, 0.0), (787891.0, 0.0)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 1', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(757735.0, 114.1), (773002.0, 118.563), (772284.0, 117.997)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 2', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(765908.0, 233.027), (766292.0, 235.925), (772907.0, 233.54)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 3', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(767204.0, 348.752), (757182.0, 345.413), (762173.0, 347.066)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 4', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(762240.0, 465.634), (766427.0, 461.286), (764470.0, 463.978)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 5', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(758053.0, 569.597), (755356.0, 568.032), (749486.0, 562.348)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 6', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(750449.0, 675.393), (760504.0, 671.979), (753789.0, 676.568)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 7', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(757352.0, 795.228), (754869.0, 782.752), (733751.0, 770.558)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 8', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(750816.0, 890.491), (733219.0, 858.385), (753169.0, 902.858)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 9', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(744790.0, 988.435), (748771.0, 990.238), (745841.0, 975.928)]), ({'par_load': False, 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-remote-item-pct 10', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(745825.0, 1092.56), (743188.0, 1079.22), (749344.0, 1090.5)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 0', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(1098950.0, 0.0), (1119710.0, 0.0), (1072420.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 1', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(889236.0, 0.0), (898120.0, 0.0), (900607.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 2', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(722596.0, 0.0), (711485.0, 0.0), (712563.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 3', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(582426.0, 0.0), (578095.0, 0.0), (583767.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 4', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(482736.0, 0.0), (483404.0, 0.0), (487373.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 5', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(414524.0, 0.0), (415143.0, 0.0), (415969.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 6', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(350162.0, 0.0), (352123.0, 0.0), (352476.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 7', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(311676.0, 0.0), (311529.0, 0.0), (307683.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 8', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(274936.0, 0.0), (274880.0, 0.0), (269893.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 9', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(240224.0, 0.0), (244346.0, 0.0), (244626.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks --new-order-remote-item-pct 10', 'retry': False, 'scale_factor': 28, 'name': 'multipart:pct', 'numa_memory': '112G', 'threads': 28, 'db': 'kvdb-st', 'bench': 'tpcc'}, [(220897.0, 0.0), (224565.0, 0.0), (224131.0, 0.0)]), ({'par_load': False, 'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 0', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(200114.0, 2302.91), (199003.0, 2297.07), (200227.0, 2319.16)]), ({'par_load': False, 'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 20', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(194843.0, 2323.13), (186419.0, 2159.79), (194520.0, 2306.21)]), ({'par_load': False, 'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 40', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(192514.0, 2365.37), (193027.0, 2379.28), (193225.0, 2340.44)]), ({'par_load': False, 'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 60', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(191380.0, 2385.91), (191342.0, 2390.18), (190192.0, 2357.07)]), ({'par_load': False, 'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 80', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(191257.0, 2400.22), (180790.0, 2180.2), (190691.0, 2383.46)]), ({'par_load': False, 'bench_opts': '--workload-mix 50,0,0,0,50 --new-order-remote-item-pct 100', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(189927.0, 2360.62), (180441.0, 2180.87), (190903.0, 2394.66)]), ({'par_load': False, 'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 0', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(162328.0, 14288.5), (165077.0, 14635.6), (165270.0, 14658.5)]), ({'par_load': False, 'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 20', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(158432.0, 15909.9), (158501.0, 15990.8), (156767.0, 15640.1)]), ({'par_load': False, 'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 40', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(153417.0, 17102.2), (154920.0, 17297.1), (153161.0, 16958.5)]), ({'par_load': False, 'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 60', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(150880.0, 18313.4), (143189.0, 17586.6), (152049.0, 18577.0)]), ({'par_load': False, 'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 80', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(149056.0, 19671.2), (150192.0, 19849.1), (150495.0, 19815.7)]), ({'par_load': False, 'bench_opts': '--disable-read-only-snapshots --workload-mix 50,0,0,0,50 --new-order-remote-item-pct 100', 'retry': True, 'scale_factor': 8, 'name': 'readonly', 'numa_memory': '64G', 'threads': 16, 'db': 'ndb-proto2', 'bench': 'tpcc'}, [(147858.0, 20842.0), (146716.0, 20584.7), (147927.0, 20903.4)])] + [({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 1, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 1, 'db': 'ndb-proto1', 'bench': 'tpcc'}, [(32240.8, 0.0), (31026.7, 0.0), (30438.4, 0.0)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 4, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 4, 'db': 'ndb-proto1', 'bench': 'tpcc'}, [(112148.0, 4.91663), (113832.0, 5.29995), (113486.0, 5.19994)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 8, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 8, 'db': 'ndb-proto1', 'bench': 'tpcc'}, [(212410.0, 8.81654), (212020.0, 9.64986), (213780.0, 8.94986)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 12, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 12, 'db': 'ndb-proto1', 'bench': 'tpcc'}, [(320426.0, 13.3998), (327475.0, 14.4498), (321080.0, 14.6498)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 16, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 16, 'db': 'ndb-proto1', 'bench': 'tpcc'}, [(431773.0, 18.8163), (432635.0, 18.3997), (430719.0, 18.383)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 20, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 20, 'db': 'ndb-proto1', 'bench': 'tpcc'}, [(542721.0, 23.7831), (529936.0, 21.7331), (538936.0, 23.8329)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 24, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 24, 'db': 'ndb-proto1', 'bench': 'tpcc'}, [(642353.0, 28.483), (643512.0, 28.7329), (643497.0, 29.6495)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 28, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 28, 'db': 'ndb-proto1', 'bench': 'tpcc'}, [(743009.0, 32.7986), (729192.0, 32.7657), (728048.0, 31.4827)]), ({'par_load': False, 'bench_opts': '', 'retry': False, 'scale_factor': 32, 'name': 'scale_tpcc', 'numa_memory': '112G', 'threads': 32, 'db': 'ndb-proto1', 'bench': 'tpcc'}, [(790212.0, 34.2826), (805566.0, 35.166), (804736.0, 34.3825)])] + [({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '101G', 'threads': 1, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(614240.0, 0.0), (616696.0, 0.0), (616061.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '101G', 'threads': 1, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(521324.0, 0.0), (519604.0, 0.0), (516847.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '105G', 'threads': 4, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(2463990.0, 0.0), (2465270.0, 0.0), (2467840.0, 0.0166664)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '105G', 'threads': 4, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(2064040.0, 0.0), (2035160.0, 0.0), (2014690.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '111G', 'threads': 8, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(4632640.0, 0.0), (4628850.0, 0.0), (4642110.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '111G', 'threads': 8, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(3917340.0, 0.0), (3918600.0, 0.0166663), (3906720.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '116G', 'threads': 12, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(6392020.0, 0.0), (6261500.0, 0.0166661), (6373530.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '116G', 'threads': 12, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(5383630.0, 0.0), (5386750.0, 0.0), (5349580.0, 0.0166662)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '122G', 'threads': 16, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(8197750.0, 0.0), (8202670.0, 0.0166657), (8212610.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '122G', 'threads': 16, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(6964480.0, 0.0), (6962350.0, 0.0), (6964480.0, 0.0333319)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '128G', 'threads': 20, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(9569340.0, 0.0), (9545470.0, 0.0), (9525760.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '128G', 'threads': 20, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(8327020.0, 0.016665), (8351850.0, 0.0666599), (8327510.0, 0.0499968)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '133G', 'threads': 24, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(9695090.0, 0.0), (9715240.0, 0.0), (9725800.0, 0.0166652)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '133G', 'threads': 24, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(9238990.0, 0.0333301), (9226620.0, 0.0666602), (9170780.0, 0.0999898)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '139G', 'threads': 28, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(8925020.0, 0.0166638), (8880120.0, 0.0), (9184000.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '139G', 'threads': 28, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(9286140.0, 0.0666553), (8793640.0, 0.049994), (9385870.0, 0.11665)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,20,0,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale', 'numa_memory': '144G', 'threads': 32, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(5234880.0, 0.0), (8694640.0, 0.0), (8797910.0, 0.0)]), ({'par_load': True, 'bench_opts': '--workload-mix 80,0,20,0', 'retry': False, 'scale_factor': 320000, 'name': 'scale_rmw', 'numa_memory': '144G', 'threads': 32, 'db': 'ndb-proto1', 'bench': 'ycsb'}, [(8860080.0, 0.0666507), (8879010.0, 0.0833041), (8945930.0, 0.0)])]
diff --git a/silo/benchmarks/results/istc11-8-28-13_cameraready.py b/silo/benchmarks/results/istc11-8-28-13_cameraready.py
new file mode 100644 (file)
index 0000000..e8cc6cd
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'binary': '../out-perf/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --enable-separate-tree-per-partition --enable-partition-locks', 'db': 'kvdb-st', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 1, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False}, [(38179.9, 38179.9, 0.0261386, 0.0, 0.0), (38455.4, 38455.4, 0.0259527, 0.0, 0.0), (38349.3, 38349.3, 0.0260178, 0.0, 0.0)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 1, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(27279.2, 27279.2, 0.0365973, 0.0, 0.0), (27155.6, 27155.6, 0.0367648, 0.0, 0.0), (26796.8, 26796.8, 0.037253, 0.0, 0.0)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 1, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(26321.0, 26321.0, 0.0379286, 0.0, 0.0), (26569.2, 26569.2, 0.037573, 0.0, 0.0), (27140.4, 27140.4, 0.0367824, 0.0, 0.0)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 1, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(26820.0, 26820.0, 0.0372239, 0.0, 0.0), (26198.6, 26198.6, 0.0381046, 0.0, 0.0), (26721.0, 26721.0, 0.0373651, 0.0, 0.0)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 1, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(27636.2, 27636.2, 0.0361241, 0.0, 0.0), (27896.6, 27896.6, 0.0357849, 0.0, 0.0), (27195.4, 27195.4, 0.0367132, 0.0, 0.0)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 2, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(53665.2, 53665.2, 0.0371825, 0.0, 2.33332), (55335.5, 55335.5, 0.0360387, 0.0, 2.99998), (55456.1, 55456.1, 0.0359656, 0.0, 2.44999)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 2, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(54570.7, 54570.7, 0.0365389, 0.0, 2.76665), (55027.4, 55027.4, 0.0362424, 0.0, 2.64998), (52970.9, 52970.9, 0.0376617, 0.0, 2.29999)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 2, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(54740.4, 54740.4, 0.0364358, 0.0, 2.51665), (53974.4, 53974.4, 0.0369523, 0.0, 2.79998), (53956.9, 53956.9, 0.0369649, 0.0, 2.66665)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 2, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(55583.4, 55583.4, 0.0358752, 0.0, 2.74998), (55511.9, 55511.9, 0.0359357, 0.0, 2.81665), (55076.5, 55076.5, 0.0362123, 0.0, 2.83332)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 4, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(102115.0, 102115.0, 0.0389772, 0.0, 14.9832), (102483.0, 102483.0, 0.0388438, 0.0, 15.1499), (99394.2, 99394.2, 0.0400376, 0.0, 15.4666)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 4, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(99742.6, 99742.6, 0.0399078, 0.0, 14.7833), (99686.9, 99686.9, 0.0399313, 0.0, 15.0999), (98806.6, 98806.6, 0.0402783, 0.0, 15.0666)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 4, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(101562.0, 101562.0, 0.0391926, 0.0, 14.7999), (101148.0, 101148.0, 0.03935, 0.0, 14.8499), (100588.0, 100588.0, 0.0395722, 0.0, 14.3666)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 4, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(101855.0, 101855.0, 0.0390631, 0.0, 16.1166), (103506.0, 103506.0, 0.0384577, 0.0, 15.6666), (104612.0, 104612.0, 0.0380519, 0.0, 14.6166)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 6, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(105894.0, 105894.0, 0.0402846, 0.0, 1781.74), (106271.0, 106271.0, 0.0401367, 0.0, 1796.52), (103814.0, 103814.0, 0.0411498, 0.0, 1772.05)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 6, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(103324.0, 103324.0, 0.0413357, 0.0, 1784.36), (107888.0, 107888.0, 0.0394036, 0.0, 1793.97), (105044.0, 105044.0, 0.0406493, 0.0, 1787.03)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 6, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(104675.0, 104675.0, 0.0407454, 0.0, 1819.53), (103649.0, 103649.0, 0.0411788, 0.0, 1792.34), (105401.0, 105401.0, 0.0404608, 0.0, 1828.0)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 6, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(118134.0, 118134.0, 0.0462966, 0.0, 459.179), (116671.0, 116671.0, 0.0467614, 0.0, 451.031), (120292.0, 120292.0, 0.0458435, 0.0, 503.747)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 8, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(110164.0, 110164.0, 0.0415078, 0.0, 3593.76), (109447.0, 109447.0, 0.0417149, 0.0, 3590.73), (109431.0, 109431.0, 0.0418349, 0.0, 3584.31)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 8, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(107558.0, 107558.0, 0.0427503, 0.0, 3538.26), (108211.0, 108211.0, 0.042309, 0.0, 3571.77), (108623.0, 108623.0, 0.0421955, 0.0, 3573.84)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 8, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(103702.0, 103702.0, 0.0444855, 0.0, 3527.93), (107269.0, 107269.0, 0.0427647, 0.0, 3571.43), (110737.0, 110737.0, 0.041177, 0.0, 3588.79)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 8, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(142348.0, 142348.0, 0.0479053, 0.0, 939.884), (137373.0, 137373.0, 0.0501871, 0.0, 917.892), (138177.0, 138177.0, 0.0498929, 0.0, 916.069)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 10, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(109780.0, 109780.0, 0.0442741, 0.0, 5086.42), (107663.0, 107663.0, 0.0452148, 0.0, 5028.67), (108948.0, 108948.0, 0.0446894, 0.0, 5072.1)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 10, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(109759.0, 109759.0, 0.0442411, 0.0, 5083.12), (108137.0, 108137.0, 0.0450479, 0.0, 5057.78), (108815.0, 108815.0, 0.04471, 0.0, 5038.11)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 10, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(106691.0, 106691.0, 0.0458682, 0.0, 5043.55), (108021.0, 108021.0, 0.0450373, 0.0, 5041.45), (110638.0, 110638.0, 0.0437823, 0.0, 5068.65)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 10, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(129149.0, 129149.0, 0.0540999, 0.0, 1050.48), (109476.0, 109476.0, 0.0503589, 0.0, 924.406), (142261.0, 142261.0, 0.0537856, 0.0, 1222.93)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 12, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(112102.0, 112102.0, 0.045725, 0.0, 6523.81), (112269.0, 112269.0, 0.0455701, 0.0, 6531.66), (111602.0, 111602.0, 0.0459453, 0.0, 6530.73)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 12, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(109293.0, 109293.0, 0.0469943, 0.0, 6478.34), (111680.0, 111680.0, 0.0460389, 0.0, 6533.16), (110390.0, 110390.0, 0.0465508, 0.0, 6495.78)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 12, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(107479.0, 107479.0, 0.0480774, 0.0, 6462.35), (111586.0, 111586.0, 0.0459079, 0.0, 6531.83), (110096.0, 110096.0, 0.0466755, 0.0, 6489.14)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 12, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(151740.0, 151740.0, 0.056124, 0.0, 1667.71), (102389.0, 102389.0, 0.0534389, 0.0, 1073.26), (147175.0, 147175.0, 0.0557127, 0.0, 1616.25)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 16, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(112078.0, 112078.0, 0.0503686, 0.0, 9258.67), (110439.0, 110439.0, 0.0512938, 0.0, 9228.7), (112589.0, 112589.0, 0.0498881, 0.0, 9275.0)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 16, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(110793.0, 110793.0, 0.0509917, 0.0, 9266.3), (111479.0, 111479.0, 0.050596, 0.0, 9230.4), (113947.0, 113947.0, 0.0492867, 0.0, 9307.76)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 16, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(114086.0, 114086.0, 0.0490479, 0.0, 9354.82), (112389.0, 112389.0, 0.0500887, 0.0, 9263.79), (112203.0, 112203.0, 0.0501601, 0.0, 9268.97)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 16, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(96140.3, 96140.3, 0.0602456, 0.0, 1317.04), (123833.0, 123833.0, 0.0586249, 0.0, 1612.86), (91066.7, 91066.7, 0.0622132, 0.0, 1227.0)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 20, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(113260.0, 113260.0, 0.053017, 0.0, 11754.7), (112459.0, 112459.0, 0.053476, 0.0, 11714.3), (112940.0, 112940.0, 0.0533785, 0.0, 11758.2)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 20, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(112123.0, 112123.0, 0.0534119, 0.0, 11666.5), (115343.0, 115343.0, 0.0518274, 0.0, 11819.3), (110106.0, 110106.0, 0.0551375, 0.0, 11655.7)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 20, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(111807.0, 111807.0, 0.0539485, 0.0, 11719.9), (112420.0, 112420.0, 0.0538304, 0.0, 11787.5), (113152.0, 113152.0, 0.052745, 0.0, 11688.3)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 20, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(129850.0, 129850.0, 0.0655325, 0.0, 1906.86), (113485.0, 113485.0, 0.0637675, 0.0, 1613.24), (129069.0, 129069.0, 0.0640064, 0.0, 1774.91)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 24, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(112045.0, 112045.0, 0.0562702, 0.0, 13864.4), (112644.0, 112644.0, 0.0561196, 0.0, 13896.3), (109792.0, 109792.0, 0.0558557, 0.0, 13456.0)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 24, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(112941.0, 112941.0, 0.0558932, 0.0, 13915.8), (113446.0, 113446.0, 0.0542462, 0.0, 13645.3), (112769.0, 112769.0, 0.0559335, 0.0, 13895.2)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 24, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(112793.0, 112793.0, 0.0559056, 0.0, 13849.6), (112508.0, 112508.0, 0.0558038, 0.0, 13815.1), (111499.0, 111499.0, 0.0569646, 0.0, 13887.4)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 24, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(120387.0, 120387.0, 0.064223, 0.0, 1863.88), (92974.0, 92974.0, 0.0662328, 0.0, 1458.06), (142175.0, 142175.0, 0.0656398, 0.0, 2178.4)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 28, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(111017.0, 111017.0, 0.0584187, 0.0, 15620.5), (115832.0, 115832.0, 0.056032, 0.0, 16005.3), (109617.0, 109617.0, 0.0594124, 0.0, 15484.4)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 28, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(96515.9, 96515.9, 0.0568733, 0.0, 13313.0), (111291.0, 111291.0, 0.057934, 0.0, 15575.5), (112729.0, 112729.0, 0.0574871, 0.0, 15752.4)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 28, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(111314.0, 111314.0, 0.0587607, 0.0, 15708.9), (102549.0, 102549.0, 0.0573524, 0.0, 14308.9), (112734.0, 112734.0, 0.0576216, 0.0, 15792.8)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 28, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(125184.0, 125184.0, 0.0663509, 0.0, 1955.04), (94220.5, 94220.5, 0.0677441, 0.0, 1598.4), (105873.0, 105873.0, 0.0695081, 0.0, 1697.33)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 32, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(93351.6, 93351.6, 0.060823, 0.0, 13923.2), (107609.0, 107609.0, 0.0615199, 0.0, 16512.1), (102195.0, 102195.0, 0.0653834, 0.0, 15340.9)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 32, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(103391.0, 103391.0, 0.0650066, 0.0, 15606.9), (90638.3, 90638.3, 0.0607784, 0.0, 13671.9), (106724.0, 106724.0, 0.0613764, 0.0, 16335.3)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 32, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(106892.0, 106892.0, 0.0621241, 0.0, 16275.5), (102397.0, 102397.0, 0.0621106, 0.0, 15317.1), (107323.0, 107323.0, 0.0606884, 0.0, 16274.8)]), ({'binary': '../out-backoff/benchmarks/dbtest', 'log_fake_writes': False, 'retry': True, 'scale_factor': 4, 'name': 'multipart:skew', 'bench_opts': '--workload-mix 100,0,0,0,0 --new-order-fast-id-gen', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 32, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': True, 'log_compress': False}, [(95339.6, 95339.6, 0.0722419, 0.0, 1606.52), (132200.0, 132200.0, 0.074819, 0.0, 2214.72), (89102.4, 89102.4, 0.0709545, 0.0, 1390.29)])]
diff --git a/silo/benchmarks/results/istc12-8-30-13_cameraready.py b/silo/benchmarks/results/istc12-8-30-13_cameraready.py
new file mode 100644 (file)
index 0000000..e3348b1
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'binary': '../out-factor-gc-nowriteinplace/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 28, 'name': 'factoranalysis', 'bench_opts': '--workload-mix 39,37,4,10,10 --disable-read-only-snapshots', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 28, 'numa_memory': None, 'persist': 'persist-none', 'disable_snapshots': True, 'log_nofsync': False, 'backoff': False, 'log_compress': False}, [(398905.0, 398905.0, 0.0700164, 0.0, 69.9142), (402620.0, 402620.0, 0.069386, 0.0, 70.782), (401382.0, 401382.0, 0.0695872, 0.0, 71.7488)]), ({'binary': '../out-factor-gc-nowriteinplace/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 28, 'name': 'factoranalysis', 'bench_opts': '--workload-mix 39,37,4,10,10 --disable-read-only-snapshots', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 28, 'numa_memory': '112G', 'persist': 'persist-none', 'disable_snapshots': True, 'log_nofsync': False, 'backoff': False, 'log_compress': False}, [(453830.0, 453830.0, 0.0615368, 0.0, 86.2485), (451226.0, 451226.0, 0.0618907, 0.0, 84.082), (450126.0, 450126.0, 0.0620415, 0.0, 85.2653)]), ({'binary': '../out-factor-gc/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 28, 'name': 'factoranalysis', 'bench_opts': '--workload-mix 39,37,4,10,10 --disable-read-only-snapshots', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 28, 'numa_memory': '112G', 'persist': 'persist-none', 'disable_snapshots': True, 'log_nofsync': False, 'backoff': False, 'log_compress': False}, [(596865.0, 596865.0, 0.0467633, 0.0, 110.447), (604516.0, 604516.0, 0.0461746, 0.0, 113.597), (600628.0, 600628.0, 0.0464617, 0.0, 112.809)]), ({'binary': '../out-factor-gc/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 28, 'name': 'factoranalysis', 'bench_opts': '--workload-mix 39,37,4,10,10', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 28, 'numa_memory': '112G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False}, [(566476.0, 566476.0, 0.0493026, 0.0, 15.8496), (563466.0, 563466.0, 0.0495645, 0.0, 15.9314), (566009.0, 566009.0, 0.0493417, 0.0, 15.7497)]), ({'binary': '../out-factor-gc/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 28, 'name': 'factoranalysis', 'bench_opts': '--workload-mix 39,37,4,10,10', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': True, 'threads': 28, 'numa_memory': '112G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False}, [(589524.0, 589524.0, 0.0473696, 0.0, 16.4164), (596908.0, 596908.0, 0.0467816, 0.0, 17.8163), (591850.0, 591850.0, 0.047182, 0.0, 17.0831)])]
diff --git a/silo/benchmarks/results/istc3-10-23-13.py b/silo/benchmarks/results/istc3-10-23-13.py
new file mode 100644 (file)
index 0000000..ed9bdee
--- /dev/null
@@ -0,0 +1 @@
+RESULTS = [({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 1, 'numa_memory': '42G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(665194.0, 665194.0, 0.00145799, 0.0, 0.0), (664321.0, 664321.0, 0.00145999, 0.0, 0.0), (659362.0, 659362.0, 0.00147133, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto1', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 1, 'numa_memory': '42G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(627665.0, 627665.0, 0.00154717, 0.0, 0.0), (638707.0, 638707.0, 0.00151958, 0.0, 0.0), (630758.0, 630758.0, 0.00153936, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 1, 'numa_memory': '42G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(632883.0, 632883.0, 0.00153415, 0.0, 0.0), (633225.0, 633225.0, 0.00153232, 0.0, 0.0), (616378.0, 616378.0, 0.00157641, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 4, 'numa_memory': '48G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(2672640.0, 2672640.0, 0.00144922, 0.0, 0.0), (2675660.0, 2675660.0, 0.00144759, 0.0, 0.0), (2673970.0, 2673970.0, 0.00144849, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto1', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 4, 'numa_memory': '48G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(2527320.0, 2527320.0, 0.00153448, 0.0, 0.0166666), (2513740.0, 2513740.0, 0.0015435, 0.0, 0.0), (2517120.0, 2517120.0, 0.00154078, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 4, 'numa_memory': '48G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(2524500.0, 2524500.0, 0.00153619, 0.0, 0.0), (2517640.0, 2517640.0, 0.00154114, 0.0, 0.0), (2525360.0, 2525360.0, 0.0015354, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 8, 'numa_memory': '56G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(5064130.0, 5064130.0, 0.00153162, 0.0, 0.0), (5062450.0, 5062450.0, 0.00153251, 0.0, 0.0), (5073880.0, 5073880.0, 0.00152869, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto1', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 8, 'numa_memory': '56G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(4745030.0, 4745030.0, 0.00163794, 0.0, 0.0), (4746190.0, 4746190.0, 0.00163751, 0.0, 0.033333), (4758670.0, 4758670.0, 0.00163252, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 8, 'numa_memory': '56G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(4743920.0, 4743920.0, 0.00163778, 0.0, 0.033333), (4782210.0, 4782210.0, 0.00162426, 0.0, 0.0333331), (4760970.0, 4760970.0, 0.00163172, 0.0, 0.0166665)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 12, 'numa_memory': '64G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(7086380.0, 7086380.0, 0.00164577, 0.0, 0.0), (7042810.0, 7042810.0, 0.00165601, 0.0, 0.0), (7082990.0, 7082990.0, 0.00164658, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto1', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 12, 'numa_memory': '64G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(6686180.0, 6686180.0, 0.00174688, 0.0, 0.0166665), (6692920.0, 6692920.0, 0.00174363, 0.0, 0.0), (6713280.0, 6713280.0, 0.00173967, 0.0, 0.0166665)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 12, 'numa_memory': '64G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(6762270.0, 6762270.0, 0.00172609, 0.0, 0.0), (6782020.0, 6782020.0, 0.00172096, 0.0, 0.0), (6786750.0, 6786750.0, 0.00172036, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 16, 'numa_memory': '72G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(9181960.0, 9181960.0, 0.0016948, 0.0, 0.0), (9168390.0, 9168390.0, 0.00169683, 0.0, 0.0), (9171090.0, 9171090.0, 0.00169678, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto1', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 16, 'numa_memory': '72G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(8634840.0, 8634840.0, 0.00180441, 0.0, 0.033333), (8622440.0, 8622440.0, 0.0018062, 0.0, 0.0), (8564850.0, 8564850.0, 0.0018196, 0.0, 0.0166665)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 16, 'numa_memory': '72G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(8795810.0, 8795810.0, 0.00176914, 0.0, 0.033333), (8803920.0, 8803920.0, 0.00176931, 0.0, 0.0), (8799200.0, 8799200.0, 0.00176973, 0.0, 0.0333329)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 20, 'numa_memory': '80G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(11387900.0, 11387900.0, 0.00170838, 0.0, 0.0), (11496800.0, 11496800.0, 0.00169184, 0.0, 0.0), (11488500.0, 11488500.0, 0.00169307, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto1', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 20, 'numa_memory': '80G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(9738990.0, 9738990.0, 0.00200578, 0.0, 0.0333329), (9760700.0, 9760700.0, 0.00200063, 0.0, 0.0666657), (9651980.0, 9651980.0, 0.0020237, 0.0, 0.0166665)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 20, 'numa_memory': '80G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(10726600.0, 10726600.0, 0.00181605, 0.0, 0.0333329), (10946000.0, 10946000.0, 0.00177867, 0.0, 0.0166665), (11034900.0, 11034900.0, 0.00176453, 0.0, 0.0166664)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 24, 'numa_memory': '88G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(13516700.0, 13516700.0, 0.00172772, 0.0, 0.0), (13501900.0, 13501900.0, 0.00172956, 0.0, 0.0), (13495600.0, 13495600.0, 0.00173061, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto1', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 24, 'numa_memory': '88G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(9087760.0, 9087760.0, 0.00259311, 0.0, 0.0166664), (9163000.0, 9163000.0, 0.00257069, 0.0, 0.0), (9060470.0, 9060470.0, 0.00260104, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 24, 'numa_memory': '88G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(12933300.0, 12933300.0, 0.00180766, 0.0, 0.0), (12992900.0, 12992900.0, 0.00179912, 0.0, 0.0666659), (12976100.0, 12976100.0, 0.00180094, 0.0, 0.0166663)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 28, 'numa_memory': '96G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(15893600.0, 15893600.0, 0.00171395, 0.0, 0.0), (15900000.0, 15900000.0, 0.00171336, 0.0, 0.0), (15939600.0, 15939600.0, 0.0017089, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto1', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 28, 'numa_memory': '96G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(8755330.0, 8755330.0, 0.00315022, 0.0, 0.0), (8801710.0, 8801710.0, 0.0031334, 0.0, 0.0), (8809090.0, 8809090.0, 0.00312979, 0.0, 0.0166662)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 28, 'numa_memory': '96G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(15263600.0, 15263600.0, 0.00178589, 0.0, 0.0666651), (15260000.0, 15260000.0, 0.00178694, 0.0, 0.0333326), (15193000.0, 15193000.0, 0.00179443, 0.0, 0.0499989)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'kvdb', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 32, 'numa_memory': '104G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(17624800.0, 17624800.0, 0.00176737, 0.0, 0.0), (17596700.0, 17596700.0, 0.00177021, 0.0, 0.0), (17591600.0, 17591600.0, 0.00177088, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto1', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 32, 'numa_memory': '104G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(8651780.0, 8651780.0, 0.00364947, 0.0, 0.0166665), (8609210.0, 8609210.0, 0.00366802, 0.0, 0.0499984), (8626100.0, 8626100.0, 0.00366151, 0.0, 0.0166658)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 160000, 'name': 'scale_rmw', 'bench_opts': '--workload-mix 80,0,20,0', 'db': 'ndb-proto2', 'bench': 'ycsb', 'par_load': True, 'disable_gc': False, 'threads': 32, 'numa_memory': '104G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(16785800.0, 16785800.0, 0.00185811, 0.0, 0.0833316), (16885600.0, 16885600.0, 0.00184669, 0.0, 0.0999984), (16856700.0, 16856700.0, 0.0018493, 0.0, 0.0499987)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 1, 'name': 'scale_tpcc', 'bench_opts': '', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 1, 'numa_memory': '4G', 'persist': 'persist-real', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(33646.5, 33646.5, 0.029612, 80.1205, 0.0), (34026.1, 34026.1, 0.0292766, 84.0236, 0.0), (33634.0, 33634.0, 0.0296285, 81.7065, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 1, 'name': 'scale_tpcc', 'bench_opts': '', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 1, 'numa_memory': '4G', 'persist': 'persist-temp', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(33999.7, 33999.7, 0.0292969, 79.9259, 0.0), (33163.8, 33163.8, 0.0300449, 79.375, 0.0), (33467.8, 33467.8, 0.0297745, 80.003, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 1, 'name': 'scale_tpcc', 'bench_opts': '', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 1, 'numa_memory': '4G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(36249.2, 36249.2, 0.0275061, 0.0, 0.0), (36970.8, 36970.8, 0.0269678, 0.0, 0.0), (36277.1, 36277.1, 0.0274837, 0.0, 0.0)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 4, 'name': 'scale_tpcc', 'bench_opts': '', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 4, 'numa_memory': '16G', 'persist': 'persist-real', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(121583.0, 121583.0, 0.0327675, 106.508, 4.52726), (121542.0, 121542.0, 0.0327998, 94.6702, 4.01465), (121066.0, 121066.0, 0.0329226, 96.6235, 4.6125)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 4, 'name': 'scale_tpcc', 'bench_opts': '', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 4, 'numa_memory': '16G', 'persist': 'persist-temp', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(124093.0, 124093.0, 0.0321134, 94.2461, 4.76184), (123089.0, 123089.0, 0.032393, 90.4293, 4.79816), (122826.0, 122826.0, 0.0324568, 92.4991, 4.92956)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 4, 'name': 'scale_tpcc', 'bench_opts': '', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 4, 'numa_memory': '16G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(130342.0, 130342.0, 0.0306012, 0.0, 5.96663), (134389.0, 134389.0, 0.0296727, 0.0, 5.03329), (133669.0, 133669.0, 0.0298368, 0.0, 5.59994)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 8, 'name': 'scale_tpcc', 'bench_opts': '', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 8, 'numa_memory': '32G', 'persist': 'persist-real', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(233347.0, 233347.0, 0.0341563, 140.331, 9.35607), (232957.0, 232957.0, 0.0342152, 176.826, 8.90821), (231095.0, 231095.0, 0.0345125, 154.034, 8.71245)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 8, 'name': 'scale_tpcc', 'bench_opts': '', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 8, 'numa_memory': '32G', 'persist': 'persist-temp', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(230754.0, 230754.0, 0.0345627, 101.877, 9.39432), (228740.0, 228740.0, 0.0348503, 95.3754, 9.69039), (230134.0, 230134.0, 0.034648, 106.236, 9.50989)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 8, 'name': 'scale_tpcc', 'bench_opts': '', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 8, 'numa_memory': '32G', 'persist': 'persist-none', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(249296.0, 249296.0, 0.0320019, 0.0, 10.1333), (251357.0, 251357.0, 0.0317386, 0.0, 11.1499), (252833.0, 252833.0, 0.0315527, 0.0, 10.5499)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': False, 'scale_factor': 12, 'name': 'scale_tpcc', 'bench_opts': '', 'db': 'ndb-proto2', 'bench': 'tpcc', 'par_load': False, 'disable_gc': False, 'threads': 12, 'numa_memory': '48G', 'persist': 'persist-real', 'disable_snapshots': False, 'log_nofsync': False, 'backoff': False, 'log_compress': False, 'disable_madv_willneed': True}, [(345270.0, 345270.0, 0.0346358, 181.773, 12.6565), (347677.0, 347677.0, 0.0343883, 225.347, 13.6364), (349664.0, 349664.0, 0.0341994, 163.489, 13.8387)]), ({'binary': '../out-perf.masstree/benchmarks/dbtest', 'log_fake_writes': False, 'retry': Fa