]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-replay: Switch ImageNameMap from regex to plain string matching
authorAdam Crume <adamcrume@gmail.com>
Thu, 7 Aug 2014 00:37:10 +0000 (17:37 -0700)
committerAdam Crume <adamcrume@gmail.com>
Wed, 13 Aug 2014 20:58:20 +0000 (13:58 -0700)
Signed-off-by: Adam Crume <adamcrume@gmail.com>
src/rbd_replay/ImageNameMap.cc
src/rbd_replay/ImageNameMap.hpp
src/rbd_replay/Makefile.am
src/rbd_replay/NameMap.cc [deleted file]
src/rbd_replay/NameMap.hpp [deleted file]
src/rbd_replay/Replayer.cc
src/rbd_replay/Replayer.hpp
src/rbd_replay/actions.cc
src/rbd_replay/actions.hpp
src/rbd_replay/rbd-replay.cc
src/test/test_rbd_replay.cc

index 336f7c6aad47a2d12dce5e1de8b3b02f957a3376..f542657185fbbe5e303a42a6877c406bdd213ad6 100644 (file)
  */
 
 #include "ImageNameMap.hpp"
-#include <boost/foreach.hpp>
-#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<rbd_loc, rbd_loc>::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;
 }
index c360db7f0ee44896a1ef8c94051192a2260a39dd..00de76552cdf88c4bcf0a47b15a01d552aec9725 100644 (file)
 
 #include <map>
 #include <string>
-#include <vector>
-#include <boost/function.hpp>
-#include <boost/regex.hpp>
-#include "ImageName.hpp"
-#include "NameMap.hpp"
+#include "rbd_loc.hpp"
 
 namespace rbd_replay {
 
 class ImageNameMap {
 public:
-  typedef std::pair<boost::regex, std::string> Mapping;
-
-  typedef boost::function<rbd_replay::ImageName (const rbd_replay::ImageName& input, std::string output)> BadMappingFallback;
-
-  ImageNameMap();
+  typedef std::pair<rbd_loc, rbd_loc> 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<rbd_loc, rbd_loc> m_map;
 };
 
 }
index 58c7de3070f0bd2fe049dccc08dcea1c5bb0bf29..6b2f6806b714c7e26d7afd8caf151144b0c8d4d6 100644 (file)
@@ -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 (file)
index 6496878..0000000
+++ /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 <adamcrume@gmail.com>
- *
- * 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 <boost/foreach.hpp>
-#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 (file)
index 68b0b65..0000000
+++ /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 <adamcrume@gmail.com>
- *
- * 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 <map>
-#include <string>
-#include <vector>
-#include <boost/regex.hpp>
-
-namespace rbd_replay {
-
-class NameMap {
-public:
-  typedef std::pair<boost::regex, std::string> 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<Mapping> 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
index eeb40297571fb845a6da0971abe35c4ffb7c680c..275017c1fa9cfbbdcb8f1febdc928d4f993fe2af 100644 (file)
@@ -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));
 }
 
 
index f16d8e39215f9d36137508dd4739a49945cdf39d..53a838d3769d725491d4d1ebde71e079c35948f0 100644 (file)
@@ -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();
index cf12ba349d39c342aa9286f1c499de9b75e74d3b..d9e143dcf88c9a4f8979b4f3c39cd5b8d0688ac5 100644 (file)
@@ -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
index f3f365203ae4461466fde99ae541d102063a52c2..fdc9eaa517483e5d94e08d861f4d1e5299f5e3e1 100644 (file)
@@ -18,7 +18,7 @@
 #include <boost/shared_ptr.hpp>
 #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;
 };
 
 
index a48c4fea52cae13405e4cf6dfe7ee1fc6710a772..b2ff0061a86723de58c514b7402cd935ae388402 100644 (file)
@@ -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<const char*> 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(); ) {
index d8b3a664970c73f00aeb741f66734df9535b5f36..e413282d17ce5574f2bbeb60ef3eb555a60ecf11 100644 (file)
 
 
 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) {