]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-replay: Add rbd_replay::rbd_loc
authorAdam Crume <adamcrume@gmail.com>
Wed, 6 Aug 2014 23:39:56 +0000 (16:39 -0700)
committerSage Weil <sage@redhat.com>
Thu, 21 Aug 2014 17:57:32 +0000 (10:57 -0700)
Signed-off-by: Adam Crume <adamcrume@gmail.com>
src/rbd_replay/Makefile.am
src/rbd_replay/rbd_loc.cc [new file with mode: 0644]
src/rbd_replay/rbd_loc.hpp [new file with mode: 0644]
src/test/test_rbd_replay.cc

index aa9be69c523362d629a092dc56a47890dda113d0..58c7de3070f0bd2fe049dccc08dcea1c5bb0bf29 100644 (file)
@@ -4,6 +4,7 @@ librbd_replay_la_SOURCES = rbd_replay/actions.cc \
        rbd_replay/ImageNameMap.cc \
        rbd_replay/NameMap.cc \
        rbd_replay/PendingIO.cc \
+       rbd_replay/rbd_loc.cc \
        rbd_replay/Replayer.cc
 librbd_replay_la_LIBADD = $(LIBRBD) \
        $(LIBRADOS) \
@@ -16,6 +17,7 @@ noinst_HEADERS += rbd_replay/BoundedBuffer.hpp \
        rbd_replay/ImageNameMap.hpp \
        rbd_replay/NameMap.hpp \
        rbd_replay/PendingIO.hpp \
+       rbd_replay/rbd_loc.hpp \
        rbd_replay/rbd_replay_debug.hpp \
        rbd_replay/Replayer.hpp
 
diff --git a/src/rbd_replay/rbd_loc.cc b/src/rbd_replay/rbd_loc.cc
new file mode 100644 (file)
index 0000000..86c50ae
--- /dev/null
@@ -0,0 +1,130 @@
+// -*- 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 "rbd_loc.hpp"
+#include "include/assert.h"
+
+
+using namespace std;
+using namespace rbd_replay;
+
+
+rbd_loc::rbd_loc() {
+}
+
+rbd_loc::rbd_loc(string pool, string image, string snap)
+  : pool(pool),
+    image(image),
+    snap(snap) {
+}
+
+bool rbd_loc::parse(string name_string) {
+  int field = 0;
+  string fields[3];
+  bool read_slash = false;
+  bool read_at = false;
+  for (size_t i = 0, n = name_string.length(); i < n; i++) {
+    char c = name_string[i];
+    switch (c) {
+    case '/':
+      if (read_slash || read_at) {
+       return false;
+      }
+      assert(field == 0);
+      field++;
+      read_slash = true;
+      break;
+    case '@':
+      if (read_at) {
+       return false;
+      }
+      assert(field < 2);
+      field++;
+      read_at = true;
+      break;
+    case '\\':
+      if (i == n - 1) {
+       return false;
+      }
+      fields[field].push_back(name_string[++i]);
+      break;
+    default:
+      fields[field].push_back(c);
+    }
+  }
+
+  if (read_slash) {
+    pool = fields[0];
+    image = fields[1];
+    // note that if read_at is false, then fields[2] is the empty string,
+    // so this is still correct
+    snap = fields[2];
+  } else {
+    pool = "";
+    image = fields[0];
+    // note that if read_at is false, then fields[1] is the empty string,
+    // so this is still correct
+    snap = fields[1];
+  }
+  return true;
+}
+
+
+static void write(const string &in, string *out) {
+  for (size_t i = 0, n = in.length(); i < n; i++) {
+    char c = in[i];
+    if (c == '@' || c == '/' || c == '\\') {
+      out->push_back('\\');
+    }
+    out->push_back(c);
+  }
+}
+
+string rbd_loc::str() const {
+  string out;
+  if (!pool.empty()) {
+    write(pool, &out);
+    out.push_back('/');
+  }
+  write(image, &out);
+  if (!snap.empty()) {
+    out.push_back('@');
+    write(snap, &out);
+  }
+  return out;
+}
+
+int rbd_loc::compare(const rbd_loc& rhs) const {
+  int c = pool.compare(rhs.pool);
+  if (c) {
+    return c;
+  }
+  c = image.compare(rhs.image);
+  if (c) {
+    return c;
+  }
+  c = snap.compare(rhs.snap);
+  if (c) {
+    return c;
+  }
+  return 0;
+}
+
+bool rbd_loc::operator==(const rbd_loc& rhs) const {
+  return compare(rhs) == 0;
+}
+
+bool rbd_loc::operator<(const rbd_loc& rhs) const {
+  return compare(rhs) < 0;
+}
diff --git a/src/rbd_replay/rbd_loc.hpp b/src/rbd_replay/rbd_loc.hpp
new file mode 100644 (file)
index 0000000..fab159a
--- /dev/null
@@ -0,0 +1,46 @@
+// -*- 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_RBD_LOC_HPP
+#define _INCLUDED_RBD_REPLAY_RBD_LOC_HPP
+
+#include <string>
+
+namespace rbd_replay {
+
+struct rbd_loc {
+  rbd_loc();
+
+  rbd_loc(std::string pool, std::string image, std::string snap);
+
+  bool parse(std::string name_string);
+
+  std::string str() const;
+
+  int compare(const rbd_loc& rhs) const;
+
+  bool operator==(const rbd_loc& rhs) const;
+
+  bool operator<(const rbd_loc& rhs) const;
+
+  std::string pool;
+
+  std::string image;
+
+  std::string snap;
+};
+
+}
+
+#endif
index 66b476f5528cd37322242e1b626e1d4e744be9fb..e41a6b09a891657accbc851fa05d7b8910f3d619 100644 (file)
 #include <boost/foreach.hpp>
 #include "rbd_replay/Deser.hpp"
 #include "rbd_replay/ImageNameMap.hpp"
+#include "rbd_replay/rbd_loc.hpp"
 
 
 using rbd_replay::ImageNameMap;
 using rbd_replay::NameMap;
+using rbd_replay::rbd_loc;
 
 std::ostream& operator<<(std::ostream& o, const ImageNameMap::Name& name) {
   return o << "('" << name.first << "', '" << name.second << "')";
@@ -93,3 +95,80 @@ TEST(RBDReplay, NameMap) {
   EXPECT_EQ("ab_image", m.map("image_ab"));
   EXPECT_EQ("asdf", m.map("asdf"));
 }
+
+TEST(RBDReplay, rbd_loc_str) {
+  EXPECT_EQ("", rbd_loc("", "", "").str());
+  EXPECT_EQ("a/", rbd_loc("a", "", "").str());
+  EXPECT_EQ("b", rbd_loc("", "b", "").str());
+  EXPECT_EQ("a/b", rbd_loc("a", "b", "").str());
+  EXPECT_EQ("@c", rbd_loc("", "", "c").str());
+  EXPECT_EQ("a/@c", rbd_loc("a", "", "c").str());
+  EXPECT_EQ("b@c", rbd_loc("", "b", "c").str());
+  EXPECT_EQ("a/b@c", rbd_loc("a", "b", "c").str());
+  EXPECT_EQ("a\\@x/b\\@y@c\\@z", rbd_loc("a@x", "b@y", "c@z").str());
+  EXPECT_EQ("a\\/x/b\\/y@c\\/z", rbd_loc("a/x", "b/y", "c/z").str());
+  EXPECT_EQ("a\\\\x/b\\\\y@c\\\\z", rbd_loc("a\\x", "b\\y", "c\\z").str());
+}
+
+TEST(RBDReplay, rbd_loc_parse) {
+  rbd_loc m("x", "y", "z");
+
+  EXPECT_EQ(true, m.parse(""));
+  EXPECT_EQ("", m.pool);
+  EXPECT_EQ("", m.image);
+  EXPECT_EQ("", m.snap);
+
+  EXPECT_EQ(true, m.parse("a/"));
+  EXPECT_EQ("a", m.pool);
+  EXPECT_EQ("", m.image);
+  EXPECT_EQ("", m.snap);
+
+  EXPECT_EQ(true, m.parse("b"));
+  EXPECT_EQ("", m.pool);
+  EXPECT_EQ("b", m.image);
+  EXPECT_EQ("", m.snap);
+
+  EXPECT_EQ(true, m.parse("a/b"));
+  EXPECT_EQ("a", m.pool);
+  EXPECT_EQ("b", m.image);
+  EXPECT_EQ("", m.snap);
+
+  EXPECT_EQ(true, m.parse("@c"));
+  EXPECT_EQ("", m.pool);
+  EXPECT_EQ("", m.image);
+  EXPECT_EQ("c", m.snap);
+
+  EXPECT_EQ(true, m.parse("a/@c"));
+  EXPECT_EQ("a", m.pool);
+  EXPECT_EQ("", m.image);
+  EXPECT_EQ("c", m.snap);
+
+  EXPECT_EQ(true, m.parse("b@c"));
+  EXPECT_EQ("", m.pool);
+  EXPECT_EQ("b", m.image);
+  EXPECT_EQ("c", m.snap);
+
+  EXPECT_EQ(true, m.parse("a/b@c"));
+  EXPECT_EQ("a", m.pool);
+  EXPECT_EQ("b", m.image);
+  EXPECT_EQ("c", m.snap);
+
+  EXPECT_EQ(true, m.parse("a\\@x/b\\@y@c\\@z"));
+  EXPECT_EQ("a@x", m.pool);
+  EXPECT_EQ("b@y", m.image);
+  EXPECT_EQ("c@z", m.snap);
+
+  EXPECT_EQ(true, m.parse("a\\/x/b\\/y@c\\/z"));
+  EXPECT_EQ("a/x", m.pool);
+  EXPECT_EQ("b/y", m.image);
+  EXPECT_EQ("c/z", m.snap);
+
+  EXPECT_EQ(true, m.parse("a\\\\x/b\\\\y@c\\\\z"));
+  EXPECT_EQ("a\\x", m.pool);
+  EXPECT_EQ("b\\y", m.image);
+  EXPECT_EQ("c\\z", m.snap);
+
+  EXPECT_EQ(false, m.parse("a@b@c"));
+  EXPECT_EQ(false, m.parse("a/b/c"));
+  EXPECT_EQ(false, m.parse("a@b/c"));
+}