From 89f920492d2f3dd16057af9dab3d9d3cd0f5d44e Mon Sep 17 00:00:00 2001 From: Joao Eduardo Luis Date: Wed, 30 Jan 2013 17:54:11 +0000 Subject: [PATCH] test: ObjectMap: add a generic leveldb store tool Signed-off-by: Joao Eduardo Luis --- src/.gitignore | 1 + src/Makefile.am | 7 + .../test_store_tool/test_store_tool.cc | 164 ++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 src/test/ObjectMap/test_store_tool/test_store_tool.cc diff --git a/src/.gitignore b/src/.gitignore index 82c302ddecf68..c59fc930a930d 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -56,6 +56,7 @@ /rest-bench /rbd-fuse /mon_store_converter +/test_store_tool dev mondata mnt diff --git a/src/Makefile.am b/src/Makefile.am index 45efa85544a78..933140f4fb063 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1025,6 +1025,13 @@ test_keyvaluedb_iterators_LDADD = ${UNITTEST_STATIC_LDADD} $(LIBOS_LDA) $(LIBGL test_keyvaluedb_iterators_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} $(LEVELDB_INCLUDE) ${CRYPTO_CXXFLAGS} bin_DEBUGPROGRAMS += test_keyvaluedb_iterators +test_store_tool_SOURCES = test/ObjectMap/test_store_tool/test_store_tool.cc \ + os/LevelDBStore.cc +test_store_tool_LDFLAGS = ${AM_LDFLAGS} +test_store_tool_LDADD = $(LIBOS_LDA) $(LIBGLOBAL_LDA) +test_store_tool_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} $(LEVELDB_INCLUDE) +bin_DEBUGPROGRAMS += test_store_tool + test_cfuse_cache_invalidate_SOURCES = test/test_cfuse_cache_invalidate.cc test_cfuse_cache_invalidate_LDFLAGS = ${AM_LDFLAGS} test_cfuse_cache_invalidate_LDADD = diff --git a/src/test/ObjectMap/test_store_tool/test_store_tool.cc b/src/test/ObjectMap/test_store_tool/test_store_tool.cc new file mode 100644 index 0000000000000..10ebe1f3eb3b8 --- /dev/null +++ b/src/test/ObjectMap/test_store_tool/test_store_tool.cc @@ -0,0 +1,164 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* +* Ceph - scalable distributed file system +* +* Copyright (C) 2012 Inktank, Inc. +* +* This is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License version 2.1, as published by the Free Software +* Foundation. See file COPYING. +*/ +#include +#include +#include +#include +#include +#include + +#include "os/LevelDBStore.h" + +using namespace std; + +class StoreTool +{ + boost::scoped_ptr db; + + public: + StoreTool(const string &path) { + LevelDBStore *db_ptr = new LevelDBStore(path); + assert(!db_ptr->open(std::cerr)); + db.reset(db_ptr); + } + + void list(const string &prefix) { + KeyValueDB::WholeSpaceIterator iter = db->get_iterator(); + + if (prefix.empty()) + iter->seek_to_first(); + else + iter->seek_to_first(prefix); + + while (iter->valid()) { + pair rk = iter->raw_key(); + if (!prefix.empty() && (rk.first != prefix)) + break; + + std::cout << rk.first << ":" << rk.second << std::endl; + iter->next(); + } + } + + bool exists(const string &prefix) { + assert(!prefix.empty()); + KeyValueDB::WholeSpaceIterator iter = db->get_iterator(); + iter->seek_to_first(prefix); + return (iter->valid() && (iter->raw_key().first == prefix)); + } + + bool exists(const string &prefix, const string &key) { + assert(!prefix.empty()); + + if (key.empty()) { + return exists(prefix); + } + + bool exists = false; + get(prefix, key, exists); + return exists; + } + + bufferlist get(const string &prefix, const string &key, bool &exists) { + assert(!prefix.empty() && !key.empty()); + + map result; + set keys; + keys.insert(key); + db->get(prefix, keys, &result); + + if (result.count(key) > 0) { + exists = true; + return result[key]; + } + exists = false; + return bufferlist(); + } +}; + +void usage(const char *pname) +{ + std::cerr << "Usage: " << pname << " command [args...]\n" + << "\n" + << "Commands:\n" + << " list [prefix]\n" + << " exists [key]\n" + << " get \n" + << " verify \n" + << std::endl; +} + +int main(int argc, char *argv[]) +{ + if (argc < 3) { + usage(argv[0]); + return 1; + } + + string path(argv[1]); + string cmd(argv[2]); + + StoreTool st(path); + + if (cmd == "list") { + string prefix; + if (argc > 3) + prefix = argv[3]; + + st.list(prefix); + + } else if (cmd == "exists") { + string key; + if (argc < 4) { + usage(argv[0]); + return 1; + } + string prefix(argv[3]); + if (argc > 4) + key = argv[4]; + + bool ret = st.exists(prefix, key); + std::cout << "(" << prefix << ", " << key << ") " + << (ret ? "exists" : "does not exist") + << std::endl; + return (ret ? 0 : 1); + + } else if (cmd == "get") { + if (argc < 5) { + usage(argv[0]); + return 1; + } + string prefix(argv[3]); + string key(argv[4]); + + bool exists = false; + bufferlist bl = st.get(prefix, key, exists); + std::cout << "(" << prefix << ", " << key << ")"; + if (!exists) { + std::cout << " does not exist" << std::endl; + return 1; + } + std::cout << std::endl; + ostringstream os; + bl.hexdump(os); + std::cout << os.str() << std::endl; + + } else if (cmd == "verify") { + assert(0); + } else { + std::cerr << "Unrecognized command: " << cmd << std::endl; + return 1; + } + + return 0; +} -- 2.39.5