From 99c4fcf7b40ff73c1ca5bb5a8c9f11db98145985 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 20 May 2009 16:00:03 -0700 Subject: [PATCH] class: string class version can be specified --- src/Makefile.am | 1 + src/common/ClassVersion.h | 100 +++++++++++++++++++++++++++++++++++++ src/include/ClassLibrary.h | 10 ++-- src/mon/ClassMonitor.cc | 11 ++-- 4 files changed, 113 insertions(+), 9 deletions(-) create mode 100644 src/common/ClassVersion.h diff --git a/src/Makefile.am b/src/Makefile.am index c06f1a481c063..e8488233d4f53 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -315,6 +315,7 @@ noinst_HEADERS = \ common/debug.h\ common/lockdep.h\ common/BackTrace.h\ + common/ClassVersion.h\ common/Clock.h\ common/common_init.h\ common/Cond.h\ diff --git a/src/common/ClassVersion.h b/src/common/ClassVersion.h new file mode 100644 index 0000000000000..2734693c048b2 --- /dev/null +++ b/src/common/ClassVersion.h @@ -0,0 +1,100 @@ +#ifndef __CLASSVERSION_H +#define __CLASSVERSION_H + +#include "include/types.h" + + +class ClassVersion +{ +protected: + std::string ver; + +public: + ClassVersion(string& v) : ver(v) {} + ClassVersion(const char *s) : ver(s) {} + ClassVersion() {} + + void operator=(const char *s) { ver = s; } + void operator=(string& v) { ver = v; } + + friend bool operator==(ClassVersion& v1, ClassVersion& v2); + friend bool operator<(ClassVersion& v1, ClassVersion& v2); + friend std::ostream& operator<<(std::ostream& out, const ClassVersion& v); + void encode(bufferlist& bl) const { + ::encode(ver, bl); + } + void decode(bufferlist::iterator& bl) { + ::decode(ver, bl); + } + + const char *str() { return ver.c_str(); }; +}; +WRITE_CLASS_ENCODER(ClassVersion) + +static int compare_single(const char *v1, const char *v2) +{ + int i1 = atoi(v1); + int i2 = atoi(v2); + + if (i1 != i2) + return (i1-i2); + + const char *p1 = v1; + const char *p2 = v2; + + while (isdigit(*p1)) + p1++; + while (isdigit(*p2)) + p2++; + + return strcmp(p1, p2); +} + +inline std::ostream& operator<<(std::ostream& out, const ClassVersion& v) +{ + out << v.ver; + + return out; +} +inline bool operator==(ClassVersion& v1, ClassVersion& v2) +{ + return (v1.ver == v2.ver); +} + +inline bool operator<(ClassVersion& v1, ClassVersion& v2) +{ + const char *_s1 = v1.ver.c_str(); + const char *_s2 = v2.ver.c_str(); + int l1 = strlen(_s1); + int l2 = strlen(_s2); + char s1[l1 + 1]; + char s2[l2 + 1]; + char *p1 = s1; + char *p2 = s2; + + const char *tok1, *tok2; + + memcpy(s1, _s1, l1 + 1); + memcpy(s2, _s2, l2 + 1); + + + while (true) { + tok1 = strsep(&p1, "."); + tok2 = strsep(&p2, "."); + if (!tok1 || !tok2) { + if (!tok1 && !tok2) + return false; + if (!tok1) + return true; + return false; + } + int r = compare_single(tok1, tok2); + if (r < 0) + return true; + if (r > 0) + return false; + } +} + + +#endif diff --git a/src/include/ClassLibrary.h b/src/include/ClassLibrary.h index b429c57a465ae..34d7cd731a526 100644 --- a/src/include/ClassLibrary.h +++ b/src/include/ClassLibrary.h @@ -18,6 +18,8 @@ #include "include/types.h" #include "include/encoding.h" +#include "common/ClassVersion.h" + struct ClassImpl { bufferlist binary; utime_t stamp; @@ -39,7 +41,7 @@ WRITE_CLASS_ENCODER(ClassImpl) struct ClassInfo { string name; - version_t version; + ClassVersion version; void encode(bufferlist& bl) const { ::encode(name, bl); @@ -88,7 +90,7 @@ struct ClassLibrary { ClassLibrary() : version(0) {} - void add(const string& name, const version_t version) { + void add(const string& name, const ClassVersion& version) { ClassInfo library; library.version = version; library.name = name; @@ -99,7 +101,7 @@ struct ClassLibrary { library_map[library.name] = library; } - void remove(const string& name, const version_t version) { + void remove(const string& name, const ClassVersion& version) { /* fixme */ } @@ -107,7 +109,7 @@ struct ClassLibrary { return (library_map.find(name) != library_map.end()); } - bool get_ver(string& name, version_t *ver) { + bool get_ver(string& name, ClassVersion *ver) { map::iterator iter = library_map.find(name); if (iter == library_map.end()) return false; diff --git a/src/mon/ClassMonitor.cc b/src/mon/ClassMonitor.cc index 354a3b2106a42..e3c3a3a55553d 100644 --- a/src/mon/ClassMonitor.cc +++ b/src/mon/ClassMonitor.cc @@ -21,6 +21,7 @@ #include "messages/MClass.h" #include "messages/MClassAck.h" +#include "common/ClassVersion.h" #include "common/Timer.h" #include "osd/osd_types.h" @@ -67,7 +68,7 @@ void ClassMonitor::create_initial(bufferlist& bl) ClassImpl i; ClassInfo l; l.name = "test"; - l.version = 12; + l.version = "0.1"; i.seq = 0; i.stamp = g_clock.now(); bufferptr ptr(1024); @@ -85,7 +86,7 @@ bool ClassMonitor::store_impl(ClassInfo& info, ClassImpl& impl) int len = info.name.length() + 16; char store_name[len]; - snprintf(store_name, len, "%s.%d", info.name.c_str(), (int)info.version); + snprintf(store_name, len, "%s.%s", info.name.c_str(), info.version.str()); dout(0) << "storing inc.impl length=" << impl.binary.length() << dendl; mon->store->put_bl_ss(impl.binary, "class_impl", store_name); bufferlist bl; @@ -291,7 +292,7 @@ bool ClassMonitor::prepare_command(MMonCommand *m) if (m->cmd.size() > 1) { if (m->cmd[1] == "add" && m->cmd.size() >= 4) { string name = m->cmd[2]; - version_t ver = atoi(m->cmd[3].c_str()); + string ver = m->cmd[3]; ClassInfo& info = list.library_map[name]; ClassImpl impl; impl.binary = m->get_data(); @@ -377,7 +378,7 @@ void ClassMonitor::handle_request(MClass *m) p != m->info.end(); p++) { ClassImpl impl; - version_t ver; + ClassVersion ver; reply->info.push_back(*p); switch (m->action) { @@ -386,7 +387,7 @@ void ClassMonitor::handle_request(MClass *m) int len = (*p).name.length() + 16; int bin_len; char store_name[len]; - snprintf(store_name, len, "%s.%d", (*p).name.c_str(), (int)ver); + snprintf(store_name, len, "%s.%d", (*p).name.c_str(), ver.str()); bin_len = mon->store->get_bl_ss(impl.binary, "class_impl", store_name); assert(bin_len > 0); dout(0) << "replying with name=" << (*p).name << " version=" << ver << " store_name=" << store_name << dendl; -- 2.39.5