Comparator.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #ifndef __COMPARATOR_H
00025 #define __COMPARATOR_H
00026
00027 #include <OverlayKey.h>
00028 #include <ProxNodeHandle.h>
00029
00033 template<class T>
00034 class Comparator
00035 {
00036 public:
00040 virtual ~Comparator()
00041 {}
00042
00052 virtual int compare( const T& lhs, const T& rhs ) const
00053 {
00054 return lhs.compareTo(rhs);
00055 }
00056 };
00057
00061
00062
00063
00064
00065 typedef Comparator<OverlayKey> KeyComparator;
00066
00070 class KeyStdMetric
00071 {
00072 public:
00080 inline OverlayKey distance(const OverlayKey& x,
00081 const OverlayKey& y) const
00082 {
00083 return x > y ? (x-y) : (y-x);
00084 }
00085 };
00086
00090 class KeyXorMetric
00091 {
00092 public:
00100 inline OverlayKey distance(const OverlayKey& x,
00101 const OverlayKey& y) const
00102 {
00103 return x^y;
00104 }
00105 };
00106
00107
00111 class KeyRingMetric
00112 {
00113 public:
00121 static inline OverlayKey distance(const OverlayKey& x,
00122 const OverlayKey& y)
00123 {
00124 OverlayKey dist1(x - y);
00125 OverlayKey dist2(y - x);
00126
00127 if (dist1 > dist2)
00128 return dist2;
00129 else
00130 return dist1;
00131 }
00132 };
00133
00134
00138 class KeyUniRingMetric
00139 {
00140 public:
00148 inline OverlayKey distance(const OverlayKey& x,
00149 const OverlayKey& y) const
00150 {
00151 return y-x;
00152 }
00153 };
00154
00155
00159 class KeyPrefixMetric
00160 {
00161 public:
00162 KeyPrefixMetric()
00163 {
00164 bitsPerDigit = 1;
00165 }
00166
00174 inline OverlayKey distance(const OverlayKey& x,
00175 const OverlayKey& y) const
00176 {
00177 return OverlayKey::getLength() / bitsPerDigit
00178 - x.sharedPrefixLength(y, bitsPerDigit);
00179 }
00180
00181 inline void setBitsPerDigit(uint8_t bitsPerDigit)
00182 {
00183 this->bitsPerDigit = bitsPerDigit;
00184 }
00185
00186 private:
00187 uint8_t bitsPerDigit;
00188 };
00189
00193 template<class Metric = KeyStdMetric>
00194 class KeyDistanceComparator : public Comparator<OverlayKey>
00195 {
00196 private:
00197 Metric m;
00198 OverlayKey key;
00199 public:
00200
00204 KeyDistanceComparator( const OverlayKey& relativeKey )
00205 {
00206 this->key = relativeKey;
00207 }
00208
00218 int compare( const OverlayKey& lhs, const OverlayKey& rhs ) const
00219 {
00220 return m.distance(lhs, key).compareTo(m.distance(rhs, key));
00221 }
00222 };
00223
00224 template<>
00225 class KeyDistanceComparator<KeyPrefixMetric> : public Comparator<OverlayKey>
00226 {
00227 private:
00228 KeyPrefixMetric m;
00229 OverlayKey key;
00230 public:
00231
00235 KeyDistanceComparator(const OverlayKey& relativeKey, uint32_t bitsPerDigit = 1)
00236 {
00237 key = relativeKey;
00238 m.setBitsPerDigit(bitsPerDigit);
00239 }
00249 int compare( const OverlayKey& lhs, const OverlayKey& rhs ) const
00250 {
00251 return m.distance(lhs, key).compareTo(m.distance(rhs, key));
00252 }
00253 };
00254
00255 class AbstractProxComparator
00256 {
00257 public:
00258 virtual ~AbstractProxComparator() {};
00259
00268 virtual int compare(const Prox& lhs, const Prox& rhs) const = 0;
00269 };
00270
00271 class StdProxComparator : public AbstractProxComparator
00272 {
00273 public:
00274 int compare(const Prox& lhs, const Prox& rhs) const
00275 {
00276
00277 if (lhs.accuracy < 0.5 || rhs.accuracy < 0.5) return 0;
00278
00279 if (lhs.proximity < rhs.proximity) return -1;
00280 if (lhs.proximity > rhs.proximity) return 1;
00281 return 0;
00282 }
00283 };
00284
00285 class AbstractProxKeyComparator
00286 {
00287 public:
00288 virtual ~AbstractProxKeyComparator() {};
00289
00299 virtual int compare(const ProxKey& lhs, const ProxKey& rhs) const = 0;
00300 };
00301
00302 template<class Metric, class ProxComp = StdProxComparator>
00303 class ProxKeyComparator : public AbstractProxKeyComparator
00304 {
00305 protected:
00306 Metric m;
00307 ProxComp pc;
00308 OverlayKey key;
00310 public:
00314 ProxKeyComparator(const OverlayKey& relativeKey)
00315 {
00316 this->key = relativeKey;
00317 }
00318 };
00319
00320
00321 template<>
00322 class ProxKeyComparator<KeyPrefixMetric> : public AbstractProxKeyComparator
00323 {
00324 protected:
00325 KeyPrefixMetric m;
00326 StdProxComparator pc;
00327 OverlayKey key;
00329 public:
00333 ProxKeyComparator(const OverlayKey& relativeKey, uint32_t bitsPerDigit = 1)
00334 {
00335 this->key = relativeKey;
00336 m.setBitsPerDigit(bitsPerDigit);
00337 }
00338 };
00339
00340 class KademliaPRComparator : public ProxKeyComparator<KeyPrefixMetric>
00341 {
00342 public:
00343 KademliaPRComparator(const OverlayKey& relativeKey, uint32_t bitsPerDigit = 1)
00344 : ProxKeyComparator<KeyPrefixMetric, StdProxComparator>(relativeKey, bitsPerDigit) { }
00345
00346 int compare(const ProxKey& lhs, const ProxKey& rhs) const
00347 {
00348 int temp = m.distance(lhs.key, key).compareTo(m.distance(rhs.key, key));
00349 if (temp != 0) {
00350 return temp;
00351 }
00352 return pc.compare(lhs.prox, rhs.prox);
00353 }
00354 };
00355
00356 #endif
00357