OverlayKey Class Reference

#include <OverlayKey.h>

List of all members.


Detailed Description

A common overlay key class.

Wraps common functions from Gnu MP library.

Author:
Sebastian Mies.

Public Member Functions

 OverlayKey ()
 Default constructor.
 OverlayKey (uint32_t num)
 Constructs an overlay key initialized with a common integer.
 OverlayKey (const unsigned char *buffer, uint size)
 Constructs a key out of a buffer.
 OverlayKey (const std::string &str, uint base=16)
 Constructs a key out of a string number.
 OverlayKey (const OverlayKey &rhs)
 Copy constructor.
 ~OverlayKey ()
 Default destructor.
std::string toString (uint base=16) const
 Returns a string representation of this key.
bool isUnspecified () const
 Returns true, if the key is unspecified.
bool operator< (const OverlayKey &compKey) const
 compares this to a given OverlayKey
bool operator> (const OverlayKey &compKey) const
 compares this to a given OverlayKey
bool operator<= (const OverlayKey &compKey) const
 compares this to a given OverlayKey
bool operator>= (const OverlayKey &compKey) const
 compares this to a given OverlayKey
bool operator== (const OverlayKey &compKey) const
 compares this to a given OverlayKey
bool operator!= (const OverlayKey &compKey) const
 compares this to a given OverlayKey
int compareTo (const OverlayKey &compKey) const
 Unifies all compare operations in one method.
OverlayKeyoperator= (const OverlayKey &rhs)
 assigns OverlayKey of rhs to this->key
OverlayKeyoperator-- ()
 substracts 1 from this->key
OverlayKeyoperator++ ()
 adds 1 to this->key
OverlayKeyoperator+= (const OverlayKey &rhs)
 adds rhs->key to this->key
OverlayKeyoperator-= (const OverlayKey &rhs)
 substracts rhs->key from this->key
OverlayKey operator+ (const OverlayKey &rhs) const
 adds rhs->key to this->key
OverlayKey operator- (const OverlayKey &rhs) const
 substracts rhs->key from this->key
OverlayKey operator-- (int)
 substracts 1 from this->key
OverlayKey operator++ (int)
 adds 1 to this->key
OverlayKey operator>> (uint num) const
 bitwise shift right
OverlayKey operator<< (uint num) const
 bitwise shift left
OverlayKey operator & (const OverlayKey &rhs) const
 bitwise AND of rhs->key and this->key
OverlayKey operator| (const OverlayKey &rhs) const
 bitwise OR of rhs->key and this->key
OverlayKey operator^ (const OverlayKey &rhs) const
 bitwise XOR of rhs->key and this->key
OverlayKey operator~ () const
 bitwise NOT of this->key
OverlayKeyBit operator[] (uint n)
 returns the n-th bit of this->key
OverlayKeysetBit (uint pos, bool value)
 sets a bit of this->key
uint32_t getBitRange (uint p, uint n) const
 Returns a sub integer at position p with n-bits.
bool getBit (uint p) const
size_t hash () const
 Returns a hash value for the key.
int log_2 () const
 Returns the position of the msb in this key, which represents just the logarithm to base 2.
OverlayKey randomSuffix (uint pos) const
 Fills the suffix starting at pos with random bits to lsb.
OverlayKey randomPrefix (uint pos) const
 Fills the prefix starting at pos with random bits to msb.
uint sharedPrefixLength (const OverlayKey &compKey, uint bitsPerDigit=1) const
 Calculates the number of equal bits (digits) from the left with another Key (shared prefix length).
bool isBetween (const OverlayKey &keyA, const OverlayKey &keyB) const
 Returns true, if this key is element of the interval (keyA, keyB) on the ring.
bool isBetweenR (const OverlayKey &keyA, const OverlayKey &keyB) const
 Returns true, if this key is element of the interval (keyA, keyB] on the ring.
bool isBetweenL (const OverlayKey &keyA, const OverlayKey &keyB) const
 Returns true, if this key is element of the interval [keyA, keyB) on the ring.
bool isBetweenLR (const OverlayKey &keyA, const OverlayKey &keyB) const
 Returns true, if this key is element of the interval [keyA, keyB] on the ring.
void netPack (cCommBuffer *b)
 serializes the object into a buffer
void netUnpack (cCommBuffer *b)
 deserializes the object from a buffer

Static Public Member Functions

static void setKeyLength (uint length)
 Set the length of an OverlayKey.
static uint getLength ()
 Returns the length in number of bits.
static OverlayKey random ()
 Returns a random key.
static OverlayKey max ()
 Returns the maximum key, i.e.
static OverlayKey sha1 (const BinaryValue &value)
 Returns a key with the SHA1 cryptographic hash of a BinaryValue.
static OverlayKey pow2 (uint exponent)
 Returns a key 2^exponent.
static void test ()
 A pseudo regression test method.

Static Public Attributes

static const OverlayKey UNSPECIFIED_KEY
 OverlayKey without defined key.
static const OverlayKey ZERO
 OverlayKey with key initialized as 0.
static const OverlayKey ONE
 OverlayKey with key initialized as 1.

Private Member Functions

void trim ()
 trims key after key operations
void clear ()
 set this->key to 0 and isUnspec to false

Private Attributes

bool isUnspec
 is this->key unspecified?
mp_limb_t key [MAX_KEYLENGTH/(8 *sizeof(mp_limb_t))+(MAX_KEYLENGTH%(8 *sizeof(mp_limb_t))!=0?1:0)]
 the overlay key this object represents

Static Private Attributes

static const uint MAX_KEYLENGTH = 160
 maximum length of the key
static uint keyLength = MAX_KEYLENGTH
 actual length of the key
static uint aSize
 number of needed machine words to hold the key
static mp_limb_t GMP_MSB_MASK
 bits to fill up if key does not exactly fit in one or more machine words

Friends

std::ostream & operator<< (std::ostream &os, const OverlayKey &c)
 Common stdc++ console output method.

Constructor & Destructor Documentation

OverlayKey::OverlayKey (  ) 

Default constructor.

Contructs an unspecified overlay key

Referenced by sha1().

00068 {
00069     isUnspec = true;
00070 }

OverlayKey::OverlayKey ( uint32_t  num  ) 

Constructs an overlay key initialized with a common integer.

Parameters:
num The integer to initialize this key with
00074 {
00075     clear();
00076     key[0] = num;
00077     trim();
00078 }

OverlayKey::OverlayKey ( const unsigned char *  buffer,
uint  size 
)

Constructs a key out of a buffer.

Parameters:
buffer Source buffer
size Buffer size (in bytes)
00082 {
00083     int trimSize, offset;
00084     clear();
00085     trimSize = (int)min(aSize * sizeof(mp_limb_t), size);
00086     offset = aSize * sizeof(mp_limb_t) - trimSize;
00087     memcpy( ((char*)key) + offset, buf, trimSize);
00088     trim();
00089 }

OverlayKey::OverlayKey ( const std::string &  str,
uint  base = 16 
)

Constructs a key out of a string number.

00093 {
00094     if ((base < 2) || (base > 16)) {
00095         throw new cRuntimeError("OverlayKey::OverlayKey(): Invalid base!");
00096     }
00097 
00098     string s(str);
00099     clear();
00100 
00101     for (uint i=0; i<s.size(); i++) {
00102         if ((s[i] >= '0') && (s[i] <= '9')) {
00103             s[i] -= '0';
00104         } else if ((s[i] >= 'a') && (s[i] <= 'f')) {
00105             s[i] -= ('a' - 10);
00106         } else if ((s[i] >= 'A') & (s[i] <= 'F')) {
00107             s[i] -= ('A' - 10);
00108         } else {
00109             throw new cRuntimeError("OverlayKey::OverlayKey(): "
00110                                     "Invalid character in string!");
00111         }
00112     }
00113 
00114     mpn_set_str ((mp_limb_t*)this->key, (const unsigned char*)s.c_str(),
00115                  str.size(), base);
00116     trim();
00117 }

OverlayKey::OverlayKey ( const OverlayKey rhs  ) 

Copy constructor.

Parameters:
rhs The key to copy.
00121 {
00122     (*this) = rhs;
00123 }

OverlayKey::~OverlayKey (  ) 

Default destructor.

Does nothing ATM.

00127 {}


Member Function Documentation

std::string OverlayKey::toString ( uint  base = 16  )  const

Returns a string representation of this key.

Returns:
String representation of this key

Referenced by BaseOverlay::bindToPort(), BaseApp::callRoute(), BaseOverlay::callUpdate(), Chord::changeState(), Pastry::checkProxCache(), Chord::closestPreceedingNode(), KBRTestApp::deliver(), Broose::displayBucketState(), BaseOverlay::findNodeRpc(), BrooseBucket::getClosestNode(), BaseOverlay::handleBaseOverlayMessage(), BaseApp::handleCommonAPIMessage(), Koorde::handleDeBruijnTimerExpired(), Scribe::handleJoinMessage(), Scribe::handleJoinResponse(), KBRTestApp::handleLookupResponse(), BootstrapList::handleLookupResponse(), XmlRpcInterface::handleMessage(), BaseOverlay::handleMessage(), BaseApp::handleMessage(), Scribe::handlePublishCall(), Scribe::handlePublishResponse(), Koorde::handleRpcNotifyResponse(), Chord::handleRpcNotifyResponse(), Scribe::handleRpcResponse(), PubSubMMOG::handleRpcResponse(), Koorde::handleRpcResponse(), KBRTestApp::handleRpcResponse(), Chord::handleRpcResponse(), Broose::handleRpcResponse(), BootstrapList::handleRpcResponse(), PubSubMMOG::handleRpcTimeout(), PubSubLobby::handleRpcTimeout(), Koorde::handleRpcTimeout(), Chord::handleRpcTimeout(), Broose::handleRpcTimeout(), Pastry::handleStateMessage(), Scribe::handleTimerEvent(), DHT::handleTimerEvent(), Pastry::handleUDPMessage(), Scribe::handleUpperMessage(), BaseRpc::internalHandleRpcMessage(), IterativeLookup::lookup(), SendToKeyListener::lookupFinished(), operator<<(), BrooseBucket::output(), P2pns::p2pnsRegisterRpc(), Chord::pingResponse(), Chord::pingTimeout(), BasePastry::pingTimeout(), BaseOverlay::route(), BaseOverlay::sendMessageToUDP(), BaseApp::sendMessageToUDP(), BaseOverlay::sendToKey(), Scribe::subscribeToGroup(), and test().

00164 {
00165     if ((base != 2) && (base != 16)) {
00166         throw new cRuntimeError("OverlayKey::OverlayKey(): Invalid base!");
00167     }
00168 
00169     if (isUnspec)
00170         return std::string("<unspec>");
00171     else {
00172         char temp[MAX_KEYLENGTH+1];
00173 
00174         if (base==16) {
00175             int k=0;
00176             for (int i=(keyLength-1)/4; i>=0; i--, k++)
00177                 temp[k] = HEX[this->getBitRange
00178                               (4*i,4)];
00179 
00180             temp[k] = 0;
00181             return std::string((const char*)temp);
00182         } else if (base==2) {
00183             int k=0;
00184             for (int i=keyLength-1; i>=0; i-=1, k++)
00185                 temp[k] = HEX[this->getBit(i)];
00186             temp[k] = 0;
00187             return std::string((const char*)temp);
00188         } else {
00189             throw new cRuntimeError("OverlayKey::OverlayKey(): Invalid base!");
00190         }
00191 
00192 // the following native libgmp code doesn't work with leading zeros
00193 #if 0
00194         mp_size_t last = mpn_get_str((unsigned char*)temp, base,
00195                                      (mp_limb_t*)this->key, aSize);
00196         for (int i=0; i<last; i++) {
00197             temp[i] = HEX[temp[i]];
00198         }
00199         temp[last] = 0;
00200         return std::string((const char*)temp);
00201 #endif
00202 
00203     }
00204 }

bool OverlayKey::isUnspecified (  )  const

bool OverlayKey::operator< ( const OverlayKey compKey  )  const

compares this to a given OverlayKey

Parameters:
compKey the the OverlayKey to compare this to
Returns:
true if compKey->key is smaller than this->key, else false
00282 {
00283     return compareTo(compKey) < 0;
00284 }

bool OverlayKey::operator> ( const OverlayKey compKey  )  const

compares this to a given OverlayKey

Parameters:
compKey the the OverlayKey to compare this to
Returns:
true if compKey->key is greater than this->key, else false
00286 {
00287     return compareTo(compKey) > 0;
00288 }

bool OverlayKey::operator<= ( const OverlayKey compKey  )  const

compares this to a given OverlayKey

Parameters:
compKey the the OverlayKey to compare this to
Returns:
true if compKey->key is smaller than or equal to this->key, else false
00290 {
00291     return compareTo(compKey) <=0;
00292 }

bool OverlayKey::operator>= ( const OverlayKey compKey  )  const

compares this to a given OverlayKey

Parameters:
compKey the the OverlayKey to compare this to
Returns:
true if compKey->key is greater than or equal to this->key, else false
00294 {
00295     return compareTo(compKey) >=0;
00296 }

bool OverlayKey::operator== ( const OverlayKey compKey  )  const

compares this to a given OverlayKey

Parameters:
compKey the the OverlayKey to compare this to
Returns:
true if compKey->key is equal to this->key, else false
00298 {
00299     return compareTo(compKey) ==0;
00300 }

bool OverlayKey::operator!= ( const OverlayKey compKey  )  const

compares this to a given OverlayKey

Parameters:
compKey the the OverlayKey to compare this to
Returns:
true if compKey->key is not equal to this->key, else false
00302 {
00303     return compareTo(compKey) !=0;
00304 }

int OverlayKey::compareTo ( const OverlayKey compKey  )  const

Unifies all compare operations in one method.

Parameters:
compKey key to compare with
Returns:
int -1 if smaller, 0 if equal, 1 if greater

Referenced by IterativeLookup::compare(), operator!=(), operator<(), operator<=(), operator==(), operator>(), operator>=(), and sharedPrefixLength().

00797 {
00798     if (compKey.isUnspec || isUnspec)
00799         opp_error("OverlayKey::compareTo(): key is unspecified!");
00800     return mpn_cmp(key,compKey.key,aSize);
00801 }

OverlayKey & OverlayKey::operator= ( const OverlayKey rhs  ) 

assigns OverlayKey of rhs to this->key

Parameters:
rhs the OverlayKey with the defined key
Returns:
this OverlayKey object
00212 {
00213     isUnspec = rhs.isUnspec;
00214     memcpy( key, rhs.key, aSize*sizeof(mp_limb_t) );
00215     return *this;
00216 }

OverlayKey & OverlayKey::operator-- (  ) 

substracts 1 from this->key

Returns:
this OverlayKey object
00220 {
00221     return (*this -= ONE);
00222 }

OverlayKey & OverlayKey::operator++ (  ) 

adds 1 to this->key

Returns:
this OverlayKey object
00234 {
00235     return (*this += ONE);
00236 }

OverlayKey & OverlayKey::operator+= ( const OverlayKey rhs  ) 

adds rhs->key to this->key

Parameters:
rhs the OverlayKey with the defined key
Returns:
this OverlayKey object
00248 {
00249     mpn_add_n((mp_limb_t*)key, (mp_limb_t*)key, (mp_limb_t*)rhs.key, aSize);
00250     trim();
00251     isUnspec = false;
00252     return *this;
00253 }

OverlayKey & OverlayKey::operator-= ( const OverlayKey rhs  ) 

substracts rhs->key from this->key

Parameters:
rhs the OverlayKey with the defined key
Returns:
this OverlayKey object
00257 {
00258     mpn_sub_n((mp_limb_t*)key, (mp_limb_t*)key, (mp_limb_t*)rhs.key, aSize);
00259     trim();
00260     isUnspec = false;
00261     return *this;
00262 }

OverlayKey OverlayKey::operator+ ( const OverlayKey rhs  )  const

adds rhs->key to this->key

Parameters:
rhs the OverlayKey with the defined key
Returns:
this OverlayKey object
00266 {
00267     OverlayKey result = *this;
00268     result += rhs;
00269     return result;
00270 }

OverlayKey OverlayKey::operator- ( const OverlayKey rhs  )  const

substracts rhs->key from this->key

Parameters:
rhs the OverlayKey with the defined key
Returns:
this OverlayKey object
00274 {
00275     OverlayKey result = *this;
00276     result -= rhs;
00277     return result;
00278 }

OverlayKey OverlayKey::operator-- ( int   ) 

substracts 1 from this->key

Returns:
this OverlayKey object
00226 {
00227     OverlayKey clone = *this;
00228     *this -= ONE;
00229     return clone;
00230 }

OverlayKey OverlayKey::operator++ ( int   ) 

adds 1 to this->key

Returns:
this OverlayKey object
00240 {
00241     OverlayKey clone = *this;
00242     *this += ONE;
00243     return clone;
00244 }

OverlayKey OverlayKey::operator>> ( uint  num  )  const

bitwise shift right

Parameters:
num number of bits to shift
Returns:
this OverlayKey object
00353 {
00354     OverlayKey result = ZERO;
00355     int i = num/GMP_LIMB_BITS;
00356 
00357     num %= GMP_LIMB_BITS;
00358 
00359     if (i>=(int)aSize)
00360         return result;
00361 
00362     for (int j=0; j<(int)aSize-i; j++) {
00363         result.key[j] = key[j+i];
00364     }
00365     mpn_rshift(result.key,result.key,aSize,num);
00366     result.isUnspec = false;
00367     result.trim();
00368 
00369     return result;
00370 }

OverlayKey OverlayKey::operator<< ( uint  num  )  const

bitwise shift left

Parameters:
num number of bits to shift
Returns:
this OverlayKey object
00374 {
00375     OverlayKey result = ZERO;
00376     int i = num/GMP_LIMB_BITS;
00377 
00378     num %= GMP_LIMB_BITS;
00379 
00380     if (i>=(int)aSize)
00381         return result;
00382 
00383     for (int j=0; j<(int)aSize-i; j++) {
00384         result.key[j+i] = key[j];
00385     }
00386     mpn_lshift(result.key,result.key,aSize,num);
00387     result.isUnspec = false;
00388     result.trim();
00389 
00390     return result;
00391 }

OverlayKey OverlayKey::operator & ( const OverlayKey rhs  )  const

bitwise AND of rhs->key and this->key

Parameters:
rhs the OverlayKey AND is calculated with
Returns:
this OverlayKey object
00330 {
00331     OverlayKey result = *this;
00332     for (uint i=0; i<aSize; i++) {
00333         result.key[i] &= rhs.key[i];
00334     }
00335 
00336     return result;
00337 }

OverlayKey OverlayKey::operator| ( const OverlayKey rhs  )  const

bitwise OR of rhs->key and this->key

Parameters:
rhs the OverlayKey OR is calculated with
Returns:
this OverlayKey object
00319 {
00320     OverlayKey result = *this;
00321     for (uint i=0; i<aSize; i++) {
00322         result.key[i] |= rhs.key[i];
00323     }
00324 
00325     return result;
00326 }

OverlayKey OverlayKey::operator^ ( const OverlayKey rhs  )  const

bitwise XOR of rhs->key and this->key

Parameters:
rhs the OverlayKey XOR is calculated with
Returns:
this OverlayKey object
00308 {
00309     OverlayKey result = *this;
00310     for (uint i=0; i<aSize; i++) {
00311         result.key[i] ^= rhs.key[i];
00312     }
00313 
00314     return result;
00315 }

OverlayKey OverlayKey::operator~ (  )  const

bitwise NOT of this->key

Returns:
this OverlayKey object
00341 {
00342     OverlayKey result = *this;
00343     for (uint i=0; i<aSize; i++) {
00344         result.key[i] = ~key[i];
00345     }
00346     result.trim();
00347 
00348     return result;
00349 }

OverlayKeyBit OverlayKey::operator[] ( uint  n  ) 

returns the n-th bit of this->key

Parameters:
n the position of the returned bit
Returns:
the bit on position n in this->key
00395 {
00396     return OverlayKeyBit(getBit(n), n, this);
00397 }

OverlayKey & OverlayKey::setBit ( uint  pos,
bool  value 
)

sets a bit of this->key

Parameters:
pos the position of the bit to set
value new value for bit at position pos
Returns:
*this

Referenced by OverlayKeyBit::operator=(), and OverlayKeyBit::operator^=().

00400 {
00401     if (pos >= keyLength) {
00402         throw new cRuntimeError("OverlayKey::setBitAt(): "
00403                                 "pos >= keyLength!");
00404     }
00405 
00406     mp_limb_t digit = 1;
00407     digit = digit << (pos % GMP_LIMB_BITS);
00408 
00409     if (value) {
00410         key[pos / GMP_LIMB_BITS] |= digit;
00411     } else {
00412         //key[pos / GMP_LIMB_BITS] = key[pos / GMP_LIMB_BITS] & ~digit;
00413         key[pos / GMP_LIMB_BITS] &= ~digit;
00414     }
00415 
00416     return *this;
00417 };

uint32_t OverlayKey::getBitRange ( uint  p,
uint  n 
) const

Returns a sub integer at position p with n-bits.

p is counted starting from the least significant bit of the key as bit 0. Bit p of the key becomes bit 0 of the returned integer.

Parameters:
p the position of the sub-integer
n the number of bits to be returned (max.32)
Returns:
The sub-integer.

Referenced by PastryRoutingTable::digitAt(), Broose::findNode(), getBit(), Kademlia::routingBucketIndex(), test(), and toString().

00425 {
00426     int i = p / GMP_LIMB_BITS,      // index of starting bit
00427         f = p % GMP_LIMB_BITS,      // position of starting bit
00428         f2 = f + n - GMP_LIMB_BITS; // how many bits to take from next index
00429 
00430     if ((p + n > OverlayKey::keyLength) || (n > 32)) {
00431         throw new cRuntimeError("OverlayKey::get:  Invalid range");
00432     }
00433     if (GMP_LIMB_BITS < 32) {
00434         throw new cRuntimeError("OverlayKey::get:  GMP_LIMB_BITS too small!");
00435     }
00436 
00437     return ((key[i] >> f) |                                     // get the bits of key[i]
00438             (f2 > 0 ? (key[i+1] << (GMP_LIMB_BITS - f)) : 0)) & // the extra bits from key[i+1]
00439         (((uint32_t)(~0)) >> (GMP_LIMB_BITS - n));              // delete unused bits
00440 }

bool OverlayKey::getBit ( uint  p  )  const [inline]

size_t OverlayKey::hash (  )  const

Returns a hash value for the key.

Returns:
size_t The hash value
00538 {
00539     return (size_t)key[0];
00540 }

int OverlayKey::log_2 (  )  const

Returns the position of the msb in this key, which represents just the logarithm to base 2.

Returns:
The logarithm to base 2 of this key.

Referenced by Koorde::findStartKey().

00515 {
00516     int16_t i = aSize-1;
00517 
00518     while (i>=0 && key[i]==0) {
00519         i--;
00520     }
00521 
00522     if (i<0) {
00523         return -1;
00524     }
00525 
00526     mp_limb_t j = key[i];
00527     i *= GMP_LIMB_BITS;
00528     while (j!=0) {
00529         j >>= 1;
00530         i++;
00531     }
00532 
00533     return i-1;
00534 }

OverlayKey OverlayKey::randomSuffix ( uint  pos  )  const

Fills the suffix starting at pos with random bits to lsb.

Parameters:
pos 
Returns:
OverlayKey

Referenced by test().

00444 {
00445     OverlayKey newKey = *this;
00446     int i = pos/GMP_LIMB_BITS, j = pos%GMP_LIMB_BITS;
00447     mp_limb_t m = ((mp_limb_t)1 << j)-1;
00448     mp_limb_t rnd;
00449 
00450     //  mpn_random(&rnd,1);
00451     omnet_random(&rnd,1);
00452     newKey.key[i] &= ~m;
00453     newKey.key[i] |= (rnd&m);
00454     //  mpn_random(newKey.key,i);
00455     omnet_random(newKey.key,i);
00456     newKey.trim();
00457 
00458     return newKey;
00459 }

OverlayKey OverlayKey::randomPrefix ( uint  pos  )  const

Fills the prefix starting at pos with random bits to msb.

Parameters:
pos 
Returns:
OverlayKey

Referenced by test().

00463 {
00464     OverlayKey newKey = *this;
00465     int i = pos/GMP_LIMB_BITS, j = pos%GMP_LIMB_BITS;
00466     mp_limb_t m = ((mp_limb_t)1 << j)-1;
00467     mp_limb_t rnd;
00468 
00469     //  mpn_random(&rnd,1);
00470     omnet_random(&rnd,1);
00471 
00472     newKey.key[i] &= m;
00473     newKey.key[i] |= (rnd&~m);
00474     for (int k=aSize-1; k!=i; k--) {
00475         //        mpn_random( &newKey.key[k], 1 );
00476         omnet_random( &newKey.key[k], 1 );
00477     }
00478     newKey.trim();
00479 
00480     return newKey;
00481 }

uint OverlayKey::sharedPrefixLength ( const OverlayKey compKey,
uint  bitsPerDigit = 1 
) const

Calculates the number of equal bits (digits) from the left with another Key (shared prefix length).

Parameters:
compKey the Key to compare with
bitsPerDigit optional number of bits per digit, default is 1
Returns:
length of shared prefix

Referenced by KeyPrefixMetric::distance(), PastryRoutingTable::findCloserNode(), PastryRoutingTable::lookupNextHop(), PastryRoutingTable::mergeNode(), Kademlia::routingBucketIndex(), PastryStateObject::specialCloserCondition(), and test().

00486 {
00487     if (compareTo(compKey) == 0) return keyLength;
00488 
00489     uint length = 0;
00490     int i;
00491     uint j;
00492     bool msb = true;
00493 
00494     // count equal limbs first:
00495     for (i=aSize-1; i>=0; --i)
00496         {
00497             if (this->key[i] != compKey.key[i])
00498                 {
00499                     // XOR first differing limb for easy counting of the bits:
00500                     mp_limb_t d = this->key[i] ^ compKey.key[i];
00501                     if (msb) d <<= ( GMP_LIMB_BITS - (keyLength % GMP_LIMB_BITS) );
00502                     for (j = GMP_LIMB_BITS-1; d >>= 1; --j);
00503                     length += j;
00504                     break;
00505                 }
00506             length += GMP_LIMB_BITS;
00507             msb = false;
00508         }
00509 
00510     return length / bitsPerDigit;
00511 }

bool OverlayKey::isBetween ( const OverlayKey keyA,
const OverlayKey keyB 
) const

Returns true, if this key is element of the interval (keyA, keyB) on the ring.

Parameters:
keyA The left border of the interval
keyB The right border of the interval
Returns:
True, if the key is element of the interval (keyA, keyB)

Referenced by Chord::closestPreceedingNode(), Koorde::findDeBruijnHop(), Koorde::handleRpcStabilizeResponse(), Chord::handleRpcStabilizeResponse(), PastryLeafSet::mergeNode(), Koorde::rpcNotify(), Chord::rpcNotify(), and test().

00545 {
00546     if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00547         return false;
00548 
00549     if (*this == keyA)
00550         return false;
00551     else if (keyA < keyB)
00552         return ((*this > keyA) && (*this < keyB));
00553     else
00554         return ((*this > keyA) || (*this < keyB));
00555 }

bool OverlayKey::isBetweenR ( const OverlayKey keyA,
const OverlayKey keyB 
) const

Returns true, if this key is element of the interval (keyA, keyB] on the ring.

Parameters:
keyA The left border of the interval
keyB The right border of the interval
Returns:
True, if the key is element of the interval (keyA, keyB]

Referenced by Chord::closestPreceedingNode(), Koorde::findNode(), Chord::findNode(), Koorde::handleDeBruijnTimerExpired(), Chord::isSiblingFor(), test(), Koorde::walkDeBruijnList(), and Koorde::walkSuccessorList().

00560 {
00561     if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00562         return false;
00563 
00564     if ((keyA == keyB) && (*this == keyA))
00565         return true;
00566     else if (keyA <= keyB)
00567         return ((*this > keyA) && (*this <= keyB));
00568     else
00569         return ((*this > keyA) || (*this <= keyB));
00570 }

bool OverlayKey::isBetweenL ( const OverlayKey keyA,
const OverlayKey keyB 
) const

Returns true, if this key is element of the interval [keyA, keyB) on the ring.

Parameters:
keyA The left border of the interval
keyB The right border of the interval
Returns:
True, if the key is element of the interval [keyA, keyB)

Referenced by test().

00575 {
00576     if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00577         return false;
00578 
00579     if ((keyA == keyB) && (*this == keyA))
00580         return true;
00581     else if (keyA <= keyB)
00582         return ((*this >= keyA) && (*this < keyB));
00583     else
00584         return ((*this >= keyA) || (*this < keyB));
00585 }

bool OverlayKey::isBetweenLR ( const OverlayKey keyA,
const OverlayKey keyB 
) const

Returns true, if this key is element of the interval [keyA, keyB] on the ring.

Parameters:
keyA The left border of the interval
keyB The right border of the interval
Returns:
True, if the key is element of the interval [keyA, keyB]

Referenced by Chord::closestPreceedingNode(), PastryLeafSet::getDestinationNode(), ChordFingerTable::getFinger(), and ChordSuccessorList::updateList().

00590 {
00591     if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00592         return false;
00593 
00594     if ((keyA == keyB) && (*this == keyA))
00595         return true;
00596     else if (keyA <= keyB)
00597         return ((*this >= keyA) && (*this <= keyB));
00598     else
00599         return ((*this >= keyA) || (*this <= keyB));
00600 }

void OverlayKey::setKeyLength ( uint  length  )  [static]

Set the length of an OverlayKey.

Parameters:
length keylength in bits

Referenced by BaseOverlay::initialize().

00134 {
00135     if ((length < 1) || (length > OverlayKey::keyLength)) {
00136         opp_error("OverlayKey::setKeyLength(): length must be <= %i "
00137                   "and setKeyLength() must not be called twice "
00138                   "with different length!", MAX_KEYLENGTH);
00139     }
00140 
00141     keyLength = length;
00142 
00143     aSize = keyLength / (8*sizeof(mp_limb_t)) +
00144         (keyLength % (8*sizeof(mp_limb_t))!=0 ? 1 : 0);
00145 
00146     GMP_MSB_MASK = (keyLength % GMP_LIMB_BITS)
00147         != 0 ? (((mp_limb_t)1 << (keyLength % GMP_LIMB_BITS))-1)
00148         : (mp_limb_t)-1;
00149 }

uint OverlayKey::getLength (  )  [static]

OverlayKey OverlayKey::random (  )  [static]

OverlayKey OverlayKey::max (  )  [static]

Returns the maximum key, i.e.

a key filled with bit 1

Returns:
The maximum key, i.e. a key filled with bit 1

Referenced by BrooseBucket::getClosestNode(), PastryStateObject::keyDist(), BrooseBucket::keyInRange(), and test().

00616 {
00617     OverlayKey newKey;
00618 
00619     for (uint i=0; i<aSize; i++) {
00620         newKey.key[i] = ~0;
00621     }
00622     newKey.isUnspec = false;
00623     newKey.trim();
00624 
00625     return newKey;
00626 }

OverlayKey OverlayKey::sha1 ( const BinaryValue value  )  [static]

Returns a key with the SHA1 cryptographic hash of a BinaryValue.

Parameters:
value A BinaryValue object.
Returns:
SHA1 of value

Referenced by Broose::changeState(), XmlRpcInterface::get(), SimMud::handleMove(), DHTTestApp::handleTraceMessage(), RealWorldTestApp::handleUpperMessage(), XmlRpcInterface::joinOverlay(), XmlRpcInterface::localLookup(), XmlRpcInterface::lookup(), P2pns::p2pnsRegisterRpc(), P2pns::p2pnsResolveRpc(), XmlRpcInterface::put(), and test().

00642 {
00643     OverlayKey newKey = OverlayKey();
00644     uint8_t temp[20];
00645     CSHA1 sha1;
00646 
00647     sha1.Reset();
00648     sha1.Update((uint8_t*)(&(*input.begin())), input.size());
00649     sha1.Final();
00650     sha1.GetHash(temp);
00651     mpn_set_str(newKey.key, (const uint8_t*)temp,
00652                 (int)min(aSize * sizeof(mp_limb_t), 20), 256);
00653     newKey.isUnspec = false;
00654     newKey.trim();
00655 
00656     return newKey;
00657 }

OverlayKey OverlayKey::pow2 ( uint  exponent  )  [static]

Returns a key 2^exponent.

Parameters:
exponent The exponent.
Returns:
Key=2^exponent.

Referenced by Koorde::findStartKey(), Chord::handleFixFingersTimerExpired(), Chord::handleStabilizeTimerExpired(), and test().

00661 {
00662     if (exponent >= keyLength) {
00663         throw new cRuntimeError("OverlayKey::pow2(): "
00664                                 "exponent >= keyLength!");
00665     }
00666 
00667     OverlayKey newKey = ZERO;
00668 
00669     newKey.key[exponent/GMP_LIMB_BITS] =
00670         (mp_limb_t)1 << (exponent % GMP_LIMB_BITS);
00671 
00672     return newKey;
00673 }

void OverlayKey::test (  )  [static]

A pseudo regression test method.

Outputs report to standard output.

00677 {
00678     // add test
00679     cout << endl << "--- Add test ..." << endl;
00680     OverlayKey key = 123456789;
00681     cout << "    key=" << key << endl;
00682     cout << "    key += 987654321 = " << (key+=987654321) << endl;
00683     cout << "    prefix++  : " << (++key) << endl;
00684     cout << "    postfix++ : " << (key++) << endl;
00685     cout << "    key=" << key << endl;
00686 
00687     OverlayKey k1 = 256, k2 = 10, k3 = 3;
00688 
00689     // compare test
00690     cout << endl << "--- Compare test ..." << endl;
00691     cout << "    256 < 10 = "<< (k1 < k2) << " k1="<<k1<<endl;
00692     cout << "    256 > 10 = "<< (k1 > k2) << " k2="<<k2<<endl;
00693 
00694     cout << "    10 isBetween(3, 256)=" << k2.isBetween(k3, k1) << endl;
00695     cout << "    3 isBetween(10, 256)=" << k3.isBetween(k2, k1) << endl;
00696     cout << "    256 isBetween(10, 256)=" << k1.isBetween(k2, k1) << endl;
00697     cout << "    256 isBetweenR(10, 256)=" << k1.isBetweenR(k2, k1) << endl;
00698     cout << "    max isBetween(max-1,0)=" << OverlayKey::max().isBetween(
00699                                                                          OverlayKey::max()-1, OverlayKey::ZERO) << endl;
00700     cout << "    max-1 isBetween(max,1)=" << (OverlayKey::max()-1).isBetween(
00701                                                                              OverlayKey::max(), OverlayKey::ONE) << endl;
00702     cout << "    max-1 isBetweenL(max-1,1)=" << (OverlayKey::max()-1).
00703         isBetweenL(OverlayKey::max()-1, OverlayKey::ONE) << endl;
00704     cout << "    1 isBetweenL(max-1,1)=" << (OverlayKey::ONE).isBetweenL(
00705                                                                          OverlayKey::max()-1, OverlayKey::ONE) << endl;
00706     cout << "    1 isBetweenR(max-1,1)=" << OverlayKey::ONE.isBetweenR(
00707                                                                        OverlayKey::max()-1, OverlayKey::ONE) << endl;
00708     cout << "    1 isBetween(max-1,1)=" << OverlayKey::ONE.isBetween(
00709                                                                      OverlayKey::max()-1, OverlayKey::ONE) << endl;
00710     cout << "    1 isBetween(max-1,0)=" << OverlayKey::ONE.isBetween(
00711                                                                      OverlayKey::max()-1, OverlayKey::ZERO) << endl;
00712     cout << "    256 sharedPrefixLength(3)=" << k1.sharedPrefixLength(k3)
00713          << endl;
00714     cout << "    256 sharedPrefixLength(256)=" << k1.sharedPrefixLength(k1)
00715          << endl;
00716 
00717     // wrap around test
00718     cout << endl << "--- Warp around test ..." << endl;
00719 
00720     k1 = OverlayKey::max();
00721     cout << "k1=max= " << k1.toString(16) << endl;
00722     cout << "k1+1 = " << (k1 + 1).toString(16) << endl;
00723     cout << "k1+2 = " << (k1 + 2).toString(16) << endl;
00724 
00725     k1 = OverlayKey::ZERO;
00726     cout << "k1=0= " << k1.toString(16) << endl;
00727     cout << "k1-1 = " << (k1 - 1).toString(16) << endl;
00728     cout << "k1-2 = " << (k1 - 2).toString(16) << endl;
00729 
00730     cout << "max > ONE=" << (OverlayKey::max() > OverlayKey::ONE) << endl;
00731     cout << "max < ONE=" << (OverlayKey::max() < OverlayKey::ONE) << endl;
00732 
00733     // distance test
00734     cout << endl << "--- Distance test ..." << endl;
00735 
00736     cout << "KeyRingMetric::distance(1, max)="
00737          <<  KeyRingMetric().distance(OverlayKey::ONE, OverlayKey::max()) << endl;
00738     cout << "KeyUniRingMetric::distance(1, max)="
00739          <<  KeyUniRingMetric().distance(OverlayKey::ONE, OverlayKey::max()) << endl;
00740     cout << "KeyRingMetric::distance(max, 1)="
00741          <<  KeyRingMetric().distance(OverlayKey::max(), OverlayKey::ONE) << endl;
00742     cout << "KeyUniRingMetric::distance(max, 1)="
00743          <<  KeyUniRingMetric().distance(OverlayKey::max(), OverlayKey::ONE) << endl;
00744 
00745     // suffix and log2 test
00746     cout << endl << "--- RandomSuffix and log2 test ..." << endl;
00747     k1 = OverlayKey::ZERO;
00748     for (uint i=0; i<k1.getLength(); i++) {
00749         k2=k1.randomSuffix(i);
00750         cout << "    " << k2.toString(16) << " log2=" << k2.log_2() << endl;
00751     }
00752     cout << endl << "--- RandomPrefix and log2 test ..." << endl;
00753     k1 = OverlayKey::max();
00754     for (uint i=0; i<k1.getLength(); i++) {
00755         k2=k1.randomPrefix(i);
00756         cout << "    " << k2.toString(16) << " log2=" << k2.log_2() << endl;
00757     }
00758 
00759     cout << endl << "--- pow2 test..." << endl;
00760     for (uint i=0; i<k1.getLength(); i++) {
00761         k2=pow2(i);
00762         cout << " 2^" << i << " = " << k2.toString(16) << "   log2="
00763              << k2.log_2() << endl;
00764     }
00765 
00766     cout << endl << "--- Bits test ..." << endl << "    ";
00767     const char* BITS[] = { "000","001","010","011","100","101","110","111" };
00768     k1 = OverlayKey::random();
00769     for (int i=k1.getLength()-1; i>=0; i--)
00770         cout << k1[i];
00771     cout << " = " << endl << "    ";
00772     for (int i=k1.getLength()-3; i>=0; i-=3)
00773         cout << BITS[k1.getBitRange(i,3)];
00774     cout << endl;
00775 
00776     cout << endl << "--- SHA1 test ... (verified with test vectors)" << endl;
00777     cout << "    Empty string: " << OverlayKey::sha1("").toString(16)
00778          << " = da39a3ee5e6b4b0d3255bfef95601890afd80709" << endl;
00779     cout << "    'Hello World' string: "
00780          << OverlayKey::sha1("Hello World").toString(16)
00781          << " = 0a4d55a8d778e5022fab701977c5d840bbc486d0" << endl;
00782 }

void OverlayKey::trim (  )  [inline, private]

trims key after key operations

Referenced by max(), operator+=(), operator-=(), operator<<(), operator>>(), operator~(), OverlayKey(), random(), randomPrefix(), randomSuffix(), and sha1().

00790 {
00791     key[aSize-1] &= GMP_MSB_MASK;
00792 }

void OverlayKey::clear (  )  [inline, private]

set this->key to 0 and isUnspec to false

Referenced by OverlayKey().

00805 {
00806     memset( key, 0, aSize * sizeof(mp_limb_t) );
00807     isUnspec = false;
00808 }

void OverlayKey::netPack ( cCommBuffer *  b  ) 

serializes the object into a buffer

Parameters:
b the buffer

Referenced by doPacking().

00871 {
00872     doPacking(b,(GMP_TYPE*)this->key, MAX_KEYLENGTH / (8*sizeof(mp_limb_t)) +
00873               (MAX_KEYLENGTH % (8*sizeof(mp_limb_t))!=0 ? 1 : 0));
00874     doPacking(b,this->isUnspec);
00875 }

void OverlayKey::netUnpack ( cCommBuffer *  b  ) 

deserializes the object from a buffer

Parameters:
b the buffer

Referenced by doUnpacking().

00878 {
00879     doUnpacking(b,(GMP_TYPE*)this->key, MAX_KEYLENGTH / (8*sizeof(mp_limb_t)) +
00880                 (MAX_KEYLENGTH % (8*sizeof(mp_limb_t))!=0 ? 1 : 0));
00881     doUnpacking(b,this->isUnspec);
00882 
00883 }


Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  os,
const OverlayKey c 
) [friend]

Common stdc++ console output method.

00609 {
00610     os << c.toString(16);
00611     return os;
00612 };


Member Data Documentation

const OverlayKey OverlayKey::ZERO [static]

OverlayKey with key initialized as 0.

Referenced by operator<<(), operator>>(), pow2(), random(), and test().

const OverlayKey OverlayKey::ONE [static]

const uint OverlayKey::MAX_KEYLENGTH = 160 [static, private]

maximum length of the key

Referenced by netPack(), netUnpack(), setKeyLength(), and toString().

uint OverlayKey::keyLength = MAX_KEYLENGTH [static, private]

actual length of the key

Referenced by getBitRange(), getLength(), pow2(), setBit(), setKeyLength(), sharedPrefixLength(), and toString().

uint OverlayKey::aSize [static, private]

Initial value:

 OverlayKey::keyLength / (8*sizeof(mp_limb_t)) +
    (OverlayKey::keyLength % (8*sizeof(mp_limb_t))
     != 0 ? 1 : 0)
number of needed machine words to hold the key

Referenced by clear(), compareTo(), log_2(), max(), operator &(), operator+=(), operator-=(), operator<<(), operator=(), operator>>(), operator^(), operator|(), operator~(), OverlayKey(), random(), randomPrefix(), setKeyLength(), sha1(), sharedPrefixLength(), toString(), and trim().

mp_limb_t OverlayKey::GMP_MSB_MASK [static, private]

Initial value:

 (OverlayKey::keyLength % GMP_LIMB_BITS)
    != 0 ? (((mp_limb_t)1 << (OverlayKey::keyLength % GMP_LIMB_BITS))-1)
    : (mp_limb_t) - 1
bits to fill up if key does not exactly fit in one or more machine words

Referenced by setKeyLength(), and trim().

bool OverlayKey::isUnspec [private]

mp_limb_t OverlayKey::key[MAX_KEYLENGTH/(8 *sizeof(mp_limb_t))+(MAX_KEYLENGTH%(8 *sizeof(mp_limb_t))!=0?1:0)] [private]


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:07 2008 for ITM OverSim by  doxygen 1.5.5