From 6be0c2b306e7a9b3fa9f9fa8f56b805eb50458c8 Mon Sep 17 00:00:00 2001 From: Adam Crume Date: Wed, 6 Aug 2014 17:37:10 -0700 Subject: [PATCH] rbd-replay: Switch ImageNameMap from regex to plain string matching Signed-off-by: Adam Crume --- src/rbd_replay/ImageNameMap.cc | 65 +++++++++++++++++++++------------ src/rbd_replay/ImageNameMap.hpp | 22 +++-------- src/rbd_replay/Makefile.am | 2 - src/rbd_replay/NameMap.cc | 52 -------------------------- src/rbd_replay/NameMap.hpp | 53 --------------------------- src/rbd_replay/Replayer.cc | 4 +- src/rbd_replay/Replayer.hpp | 2 +- src/rbd_replay/actions.cc | 6 +-- src/rbd_replay/actions.hpp | 4 +- src/rbd_replay/rbd-replay.cc | 6 --- src/test/test_rbd_replay.cc | 50 +++++++------------------ 11 files changed, 68 insertions(+), 198 deletions(-) delete mode 100644 src/rbd_replay/NameMap.cc delete mode 100644 src/rbd_replay/NameMap.hpp diff --git a/src/rbd_replay/ImageNameMap.cc b/src/rbd_replay/ImageNameMap.cc index 336f7c6aad47a..f542657185fbb 100644 --- a/src/rbd_replay/ImageNameMap.cc +++ b/src/rbd_replay/ImageNameMap.cc @@ -13,40 +13,57 @@ */ #include "ImageNameMap.hpp" -#include -#include "include/assert.h" using namespace std; using namespace rbd_replay; -static ImageName bad_mapping_abort(ImageName input, string output) { - assertf(false, "Bad value returned from mapping. Image: '%s', snap: '%s', output: '%s'", input.image().c_str(), input.snap().c_str(), output.c_str()); -} - -ImageNameMap::ImageNameMap() - : m_bad_mapping_fallback(bad_mapping_abort) { -} - bool ImageNameMap::parse_mapping(string mapping_string, Mapping *mapping) const { - return m_map.parse_mapping(mapping_string, mapping); + string fields[2]; + int field = 0; + for (size_t i = 0, n = mapping_string.length(); i < n; i++) { + char c = mapping_string[i]; + switch (c) { + case '\\': + if (i != n - 1 && mapping_string[i + 1] == '=') { + i++; + fields[field].push_back('='); + } else { + fields[field].push_back('\\'); + } + break; + case '=': + if (field == 1) { + return false; + } + field = 1; + break; + default: + fields[field].push_back(c); + } + } + if (field == 0) { + return false; + } + if (!mapping->first.parse(fields[0])) { + return false; + } + if (!mapping->second.parse(fields[1])) { + return false; + } + return true; } -void ImageNameMap::add_mapping(Mapping mapping) { - m_map.add_mapping(mapping); +void ImageNameMap::add_mapping(const Mapping& mapping) { + m_map.insert(mapping); } -ImageName ImageNameMap::map(const ImageName& name) const { - string in_string(name.str()); - string out_string(m_map.map(in_string)); - ImageName out; - if (!out.parse(out_string)) { - return m_bad_mapping_fallback(name, out_string); +rbd_loc ImageNameMap::map(const rbd_loc& name) const { + std::map::const_iterator p(m_map.find(name)); + if (p == m_map.end()) { + return name; + } else { + return p->second; } - return out; -} - -void ImageNameMap::set_bad_mapping_fallback(BadMappingFallback bad_mapping_fallback) { - m_bad_mapping_fallback = bad_mapping_fallback; } diff --git a/src/rbd_replay/ImageNameMap.hpp b/src/rbd_replay/ImageNameMap.hpp index c360db7f0ee44..00de76552cdf8 100644 --- a/src/rbd_replay/ImageNameMap.hpp +++ b/src/rbd_replay/ImageNameMap.hpp @@ -17,34 +17,22 @@ #include #include -#include -#include -#include -#include "ImageName.hpp" -#include "NameMap.hpp" +#include "rbd_loc.hpp" namespace rbd_replay { class ImageNameMap { public: - typedef std::pair Mapping; - - typedef boost::function BadMappingFallback; - - ImageNameMap(); + typedef std::pair Mapping; bool parse_mapping(std::string mapping_string, Mapping *mapping) const; - void add_mapping(Mapping mapping); + void add_mapping(const Mapping& mapping); - rbd_replay::ImageName map(const rbd_replay::ImageName& name) const; - - void set_bad_mapping_fallback(BadMappingFallback bad_mapping_fallback); + rbd_loc map(const rbd_loc& name) const; private: - NameMap m_map; - - BadMappingFallback m_bad_mapping_fallback; + std::map m_map; }; } diff --git a/src/rbd_replay/Makefile.am b/src/rbd_replay/Makefile.am index 58c7de3070f0b..6b2f6806b714c 100644 --- a/src/rbd_replay/Makefile.am +++ b/src/rbd_replay/Makefile.am @@ -2,7 +2,6 @@ librbd_replay_la_SOURCES = rbd_replay/actions.cc \ rbd_replay/Deser.cc \ rbd_replay/ImageNameMap.cc \ - rbd_replay/NameMap.cc \ rbd_replay/PendingIO.cc \ rbd_replay/rbd_loc.cc \ rbd_replay/Replayer.cc @@ -15,7 +14,6 @@ noinst_HEADERS += rbd_replay/BoundedBuffer.hpp \ rbd_replay/actions.hpp \ rbd_replay/Deser.hpp \ rbd_replay/ImageNameMap.hpp \ - rbd_replay/NameMap.hpp \ rbd_replay/PendingIO.hpp \ rbd_replay/rbd_loc.hpp \ rbd_replay/rbd_replay_debug.hpp \ diff --git a/src/rbd_replay/NameMap.cc b/src/rbd_replay/NameMap.cc deleted file mode 100644 index 6496878a18180..0000000000000 --- a/src/rbd_replay/NameMap.cc +++ /dev/null @@ -1,52 +0,0 @@ -// -*- 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) 2014 Adam Crume - * - * 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 "NameMap.hpp" -#include -#include "include/assert.h" - - -using namespace std; -using namespace rbd_replay; - - -bool NameMap::parse_mapping(string mapping_string, Mapping *mapping) const { - boost::smatch what; - if (boost::regex_match(mapping_string, what, m_keyval)) { - string pattern(what[1]); - string replacement(what[2]); - - pattern = boost::regex_replace(pattern, m_escaped_equals, "="); - replacement = boost::regex_replace(replacement, m_escaped_equals, "="); - - *mapping = Mapping(boost::regex(pattern), replacement); - return true; - } else { - return false; - } -} - -void NameMap::add_mapping(Mapping mapping) { - m_mappings.push_back(mapping); -} - -string NameMap::map(string name) const { - BOOST_FOREACH(const Mapping &m, m_mappings) { - boost::smatch what; - if (boost::regex_match(name, what, m.first)) { - return what.format(m.second); - } - } - return name; -} diff --git a/src/rbd_replay/NameMap.hpp b/src/rbd_replay/NameMap.hpp deleted file mode 100644 index 68b0b6522bbd6..0000000000000 --- a/src/rbd_replay/NameMap.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// -*- 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) 2014 Adam Crume - * - * 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. - * - */ - -#ifndef _INCLUDED_RBD_REPLAY_NAMEMAP_HPP -#define _INCLUDED_RBD_REPLAY_NAMEMAP_HPP - -#include -#include -#include -#include - -namespace rbd_replay { - -class NameMap { -public: - typedef std::pair Mapping; - - NameMap() - : m_keyval("((?:[^=\\\\]|\\\\.)*)=((?:[^=\\\\]|\\\\.)*)"), - m_escaped_equals("\\\\=") { - } - - bool parse_mapping(std::string mapping_string, Mapping *mapping) const; - - void add_mapping(Mapping mapping); - - std::string map(std::string name) const; - -private: - std::vector m_mappings; - - // Split "a=b" into "a" and "b", allowing for escaped equal signs - boost::regex m_keyval; - - // We don't have to worry about an even number of backslahes followed by an equal sign, - // because that equal sign would have already been matched and removed. - boost::regex m_escaped_equals; -}; - -} - -#endif diff --git a/src/rbd_replay/Replayer.cc b/src/rbd_replay/Replayer.cc index eeb40297571fb..275017c1fa9cf 100644 --- a/src/rbd_replay/Replayer.cc +++ b/src/rbd_replay/Replayer.cc @@ -128,8 +128,8 @@ bool Worker::readonly() const { return m_replayer.readonly(); } -ImageName Worker::map_image_name(string image_name, string snap_name) const { - return m_replayer.image_name_map().map(ImageName("", image_name, snap_name)); +rbd_loc Worker::map_image_name(string image_name, string snap_name) const { + return m_replayer.image_name_map().map(rbd_loc("", image_name, snap_name)); } diff --git a/src/rbd_replay/Replayer.hpp b/src/rbd_replay/Replayer.hpp index f16d8e39215f9..53a838d3769d7 100644 --- a/src/rbd_replay/Replayer.hpp +++ b/src/rbd_replay/Replayer.hpp @@ -56,7 +56,7 @@ public: bool readonly() const; - rbd_replay::ImageName map_image_name(std::string image_name, std::string snap_name) const; + rbd_loc map_image_name(std::string image_name, std::string snap_name) const; private: void run(); diff --git a/src/rbd_replay/actions.cc b/src/rbd_replay/actions.cc index cf12ba349d39c..d9e143dcf88c9 100644 --- a/src/rbd_replay/actions.cc +++ b/src/rbd_replay/actions.cc @@ -330,12 +330,12 @@ void OpenImageAction::perform(ActionCtx &worker) { worker.add_pending(io); librbd::Image *image = new librbd::Image(); librbd::RBD *rbd = worker.rbd(); - ImageName name(worker.map_image_name(m_name, m_snap_name)); + rbd_loc name(worker.map_image_name(m_name, m_snap_name)); int r; if (m_readonly || worker.readonly()) { - r = rbd->open_read_only(*worker.ioctx(), *image, name.image().c_str(), name.snap().c_str()); + r = rbd->open_read_only(*worker.ioctx(), *image, name.image.c_str(), name.snap.c_str()); } else { - r = rbd->open(*worker.ioctx(), *image, name.image().c_str(), name.snap().c_str()); + r = rbd->open(*worker.ioctx(), *image, name.image.c_str(), name.snap.c_str()); } if (r) { cerr << "Unable to open image '" << m_name diff --git a/src/rbd_replay/actions.hpp b/src/rbd_replay/actions.hpp index f3f365203ae44..fdc9eaa517483 100644 --- a/src/rbd_replay/actions.hpp +++ b/src/rbd_replay/actions.hpp @@ -18,7 +18,7 @@ #include #include "include/rbd/librbd.hpp" #include "Deser.hpp" -#include "ImageName.hpp" +#include "rbd_loc.hpp" namespace rbd_replay { @@ -69,7 +69,7 @@ public: virtual void stop() = 0; - virtual rbd_replay::ImageName map_image_name(std::string image_name, std::string snap_name) const = 0; + virtual rbd_loc map_image_name(std::string image_name, std::string snap_name) const = 0; }; diff --git a/src/rbd_replay/rbd-replay.cc b/src/rbd_replay/rbd-replay.cc index a48c4fea52cae..b2ff0061a8672 100644 --- a/src/rbd_replay/rbd-replay.cc +++ b/src/rbd_replay/rbd-replay.cc @@ -49,11 +49,6 @@ static void usage(const char* program) { cout << "image@snap_1 to image_1." << std::endl; } -static ImageName bad_mapping(ImageName input, string output) { - dout(0) << "Bad value returned from mapping. Input: '" << input.str() << "', output: '" << output << "'. Using image: '" << output << ", snap ''." << dendl; - return ImageName("", output, ""); -} - int main(int argc, const char **argv) { vector args; @@ -66,7 +61,6 @@ int main(int argc, const char **argv) { float latency_multiplier = 1; bool readonly = false; ImageNameMap image_name_map; - image_name_map.set_bad_mapping_fallback(bad_mapping); std::string val; std::ostringstream err; for (i = args.begin(); i != args.end(); ) { diff --git a/src/test/test_rbd_replay.cc b/src/test/test_rbd_replay.cc index d8b3a664970c7..e413282d17ce5 100644 --- a/src/test/test_rbd_replay.cc +++ b/src/test/test_rbd_replay.cc @@ -22,15 +22,10 @@ using rbd_replay::ImageNameMap; -using rbd_replay::NameMap; using rbd_replay::rbd_loc; -std::ostream& operator<<(std::ostream& o, const ImageName& name) { - return o << "('" << name.pool() << "', '" << name.image() << "', '" << name.snap() << "')"; -} - -static ImageName bad_mapping(ImageName input, std::string output) { - return ImageName("xxx", "xxx", "xxx"); +std::ostream& operator<<(std::ostream& o, const rbd_loc& name) { + return o << "('" << name.pool << "', '" << name.image << "', '" << name.snap << "')"; } static void add_mapping(ImageNameMap *map, std::string mapping_string) { @@ -41,14 +36,6 @@ static void add_mapping(ImageNameMap *map, std::string mapping_string) { map->add_mapping(mapping); } -static void add_mapping(NameMap *map, std::string mapping_string) { - NameMap::Mapping mapping; - if (!map->parse_mapping(mapping_string, &mapping)) { - ASSERT_TRUE(false) << "Failed to parse mapping string '" << mapping_string << "'"; - } - map->add_mapping(mapping); -} - TEST(RBDReplay, Deser) { const char data[] = {1, 2, 3, 4, 0, 0, 0, 5, 'h', 'e', 'l', 'l', 'o', 1, 0}; const std::string s(data, sizeof(data)); @@ -69,30 +56,21 @@ TEST(RBDReplay, Deser) { TEST(RBDReplay, ImageNameMap) { ImageNameMap m; - m.set_bad_mapping_fallback(bad_mapping); add_mapping(&m, "x@y=y@x"); add_mapping(&m, "a\\=b@c=h@i"); add_mapping(&m, "a@b\\=c=j@k"); - add_mapping(&m, "a\\\\@b@c=d@e"); - add_mapping(&m, "a@b\\\\@c=f@g"); - add_mapping(&m, "image@snap_(.*)=image_$1@"); - add_mapping(&m, "bad=@@@"); - EXPECT_EQ(ImageName("", "y", "x"), m.map(ImageName("", "x", "y"))); - EXPECT_EQ(ImageName("", "h", "i"), m.map(ImageName("", "a=b", "c"))); - EXPECT_EQ(ImageName("", "j", "k"), m.map(ImageName("", "a", "b=c"))); - EXPECT_EQ(ImageName("", "d", "e"), m.map(ImageName("", "a@b", "c"))); - EXPECT_EQ(ImageName("", "f", "g"), m.map(ImageName("", "a", "b@c"))); - EXPECT_EQ(ImageName("", "image_1", ""), m.map(ImageName("", "image", "snap_1"))); - EXPECT_EQ(ImageName("xxx", "xxx", "xxx"), m.map(ImageName("", "bad", ""))); -} - -TEST(RBDReplay, NameMap) { - NameMap m; - add_mapping(&m, "x=y"); - add_mapping(&m, "image_(.*)=$1_image"); - EXPECT_EQ("y", m.map("x")); - EXPECT_EQ("ab_image", m.map("image_ab")); - EXPECT_EQ("asdf", m.map("asdf")); + add_mapping(&m, "a\\@b@c=d@e"); + add_mapping(&m, "a@b\\@c=f@g"); + add_mapping(&m, "image@snap_1=image_1"); + ImageNameMap::Mapping mapping; + EXPECT_EQ(false, m.parse_mapping("bad=@@@", &mapping)); + EXPECT_EQ(false, m.parse_mapping("bad==stuff", &mapping)); + EXPECT_EQ(rbd_loc("", "y", "x"), m.map(rbd_loc("", "x", "y"))); + EXPECT_EQ(rbd_loc("", "h", "i"), m.map(rbd_loc("", "a=b", "c"))); + EXPECT_EQ(rbd_loc("", "j", "k"), m.map(rbd_loc("", "a", "b=c"))); + EXPECT_EQ(rbd_loc("", "d", "e"), m.map(rbd_loc("", "a@b", "c"))); + EXPECT_EQ(rbd_loc("", "f", "g"), m.map(rbd_loc("", "a", "b@c"))); + EXPECT_EQ(rbd_loc("", "image_1", ""), m.map(rbd_loc("", "image", "snap_1"))); } TEST(RBDReplay, rbd_loc_str) { -- 2.39.5