From: Greg Farnum Date: Thu, 10 Jul 2014 00:09:51 +0000 (-0700) Subject: MDS: add operator==() and compare() for inode_backtrace_t X-Git-Tag: v0.89~50^2~27 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7795a4e113d450912a1bdb029f89c1d234654666;p=ceph.git MDS: add operator==() and compare() for inode_backtrace_t The compare() function checks one backtrace against another and indicates if they're equivalent (or divergent!) and the relative freshness. Signed-off-by: Greg Farnum --- diff --git a/src/mds/inode_backtrace.cc b/src/mds/inode_backtrace.cc index e2ab809db100..bde2145ebf24 100644 --- a/src/mds/inode_backtrace.cc +++ b/src/mds/inode_backtrace.cc @@ -118,3 +118,51 @@ void inode_backtrace_t::generate_test_instances(list& ls) ls.back()->old_pools.insert(7); } +int inode_backtrace_t::compare(const inode_backtrace_t& other, + bool *equivalent, bool *divergent) const +{ + int min_size = MIN(ancestors.size(),other.ancestors.size()); + *divergent = false; + if (min_size == 0) + return 0; + int comparator = 0; + if (ancestors[0].version > other.ancestors[0].version) + comparator = 1; + else if (ancestors[0].version < other.ancestors[0].version) + comparator = -1; + for (int i = 1; i < min_size; ++i) { + if (*divergent) { + /** + * we already know the dentries and versions are + * incompatible; no point checking farther + */ + break; + } + if (ancestors[i].dirino != other.ancestors[i].dirino) { + *equivalent = false; + if (ancestors[i-1].version < other.ancestors[i-1].version) { + if (comparator > 0) + *divergent = true; + return -1; + } else if (ancestors[i-1].version > other.ancestors[i-1].version) { + if (comparator < 0) + *divergent = true; + return 1; + } else { + assert(ancestors[i-1].version == other.ancestors[i-1].version); + return 0; + } + } else if (ancestors[i].version > other.ancestors[i].version) { + if (comparator < 0) + *divergent = true; + comparator = 1; + } else if (ancestors[i].version < other.ancestors[i].version) { + if (comparator > 0) + *divergent = true; + comparator = -1; + } + } + if (!*divergent) + *equivalent = true; + return comparator; +} diff --git a/src/mds/inode_backtrace.h b/src/mds/inode_backtrace.h index 2d80ae3efada..08cbf65af908 100644 --- a/src/mds/inode_backtrace.h +++ b/src/mds/inode_backtrace.h @@ -61,6 +61,21 @@ struct inode_backtrace_t { void decode(bufferlist::iterator &bl); void dump(Formatter *f) const; static void generate_test_instances(list& ls); + + /** + * Compare two backtraces *for the same inode*. + * @pre The backtraces are for the same inode + * + * @param other The backtrace to compare ourselves with + * @param equivalent A bool pointer which will be set to true if + * the other backtrace is equivalent to our own (has the same dentries) + * @param divergent A bool pointer which will be set to true if + * the backtraces have differing entries without versions supporting them + * + * @returns 1 if we are newer than the other, 0 if equal, -1 if older + */ + int compare(const inode_backtrace_t& other, + bool *equivalent, bool *divergent) const; }; WRITE_CLASS_ENCODER(inode_backtrace_t) @@ -68,6 +83,13 @@ inline ostream& operator<<(ostream& out, const inode_backtrace_t& it) { return out << "(" << it.pool << ")" << it.ino << ":" << it.ancestors << "//" << it.old_pools; } +inline bool operator==(const inode_backtrace_t& l, + const inode_backtrace_t& r) { + return l.ino == r.ino && + l.pool == r.pool && + l.old_pools == r.old_pools && + l.ancestors == r.ancestors; +} #endif