source: source/ariba/utility/types/Identifier.h@ 4437

Last change on this file since 4437 was 4437, checked in by Christoph Mayer, 15 years ago

bei identifier random unspec false setzen

File size: 14.8 KB
Line 
1// [License]
2// The Ariba-Underlay Copyright
3//
4// Copyright (c) 2008-2009, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5//
6// Institute of Telematics
7// UniversitÀt Karlsruhe (TH)
8// Zirkel 2, 76128 Karlsruhe
9// Germany
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
22// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR
25// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The views and conclusions contained in the software and documentation
34// are those of the authors and should not be interpreted as representing
35// official policies, either expressed or implied, of the Institute of
36// Telematics.
37// [License]
38
39#ifndef IDENTIFIER_H_
40#define IDENTIFIER_H_
41
42#include <memory>
43#include <string>
44#include <cassert>
45#include <gmp.h>
46#include <boost/cstdint.hpp>
47#include "ariba/utility/logging/Logging.h"
48#include "ariba/utility/types/Address.h"
49#include "ariba/utility/serialization.h"
50
51/**< maximum length of the key */
52#define MAX_KEYLENGTH 192
53
54namespace ariba {
55namespace utility {
56
57using_serialization;
58
59class IdentifierBit;
60
61/**
62 * An abstract address class for identifier.<br/>
63 *
64 * This class is the base for all identifier classes.
65 */
66class Identifier: public Address {
67 VSERIALIZEABLE;
68 use_logging_h( Identifier );
69public:
70
71 //-------------------------------------------------------------------------
72 // virtual function from Address
73 //-------------------------------------------------------------------------
74
75 virtual void clearAddress();
76 virtual bool setAddress(string address);
77 virtual string getAddress() const;
78
79 //-------------------------------------------------------------------------
80 // constants
81 //-------------------------------------------------------------------------
82
83 static const Identifier UNSPECIFIED_KEY; /**< Identifier without defined key */
84 static const Identifier ZERO; /**< Identifier with key initialized as 0 */
85 static const Identifier ONE; /**< Identifier with key initialized as 1 */
86
87 //-------------------------------------------------------------------------
88 // construction and destruction
89 //-------------------------------------------------------------------------
90
91 /**
92 * Default constructor
93 *
94 * Contructs an unspecified overlay key
95 */
96 Identifier();
97
98 /**
99 * Constructs an overlay key initialized with a common integer
100 *
101 * @param num The integer to initialize this key with
102 */
103 Identifier(uint32_t num);
104
105 /**
106 * Constructs a key out of a buffer
107 * @param buffer Source buffer
108 * @param size Buffer size (in bytes)
109 */
110 Identifier(const unsigned char* buffer, uint size);
111
112 /**
113 * Constructs a key out of a string number.
114 */
115 Identifier(const std::string& str, uint base = 16);
116
117 /**
118 * Copy constructor.
119 *
120 * @param rhs The key to copy.
121 */
122 Identifier(const Identifier& rhs);
123
124 /**
125 * Default destructor.
126 *
127 * Does nothing ATM.
128 */
129 virtual ~Identifier();
130
131 //-------------------------------------------------------------------------
132 // string representations & node key attributes
133 //-------------------------------------------------------------------------
134
135 /**
136 * Returns a string representation of this key
137 *
138 * @return String representation of this key
139 */
140 virtual std::string toString(uint base = 16) const;
141
142 /**
143 * Common stdc++ console output method
144 */
145 friend std::ostream& operator<<(std::ostream& os, const Identifier& c);
146
147 /**
148 * Returns true, if the key is unspecified
149 *
150 * @return Returns true, if key is unspecified
151 */
152 bool isUnspecified() const;
153
154 //-------------------------------------------------------------------------
155 // operators
156 //-------------------------------------------------------------------------
157
158 /**
159 * compares this to a given Identifier
160 *
161 * @param compKey the the Identifier to compare this to
162 * @return true if compKey->key is smaller than this->key, else false
163 */
164 bool operator<(const Identifier& compKey) const;
165
166 /**
167 * compares this to a given Identifier
168 *
169 * @param compKey the the Identifier to compare this to
170 * @return true if compKey->key is greater than this->key, else false
171 */
172 bool operator>(const Identifier& compKey) const;
173
174 /**
175 * compares this to a given Identifier
176 *
177 * @param compKey the the Identifier to compare this to
178 * @return true if compKey->key is smaller than or equal to this->key, else false
179 */
180 bool operator<=(const Identifier& compKey) const;
181
182 /**
183 * compares this to a given Identifier
184 *
185 * @param compKey the the Identifier to compare this to
186 * @return true if compKey->key is greater than or equal to this->key, else false
187 */
188 bool operator>=(const Identifier& compKey) const;
189
190 /**
191 * compares this to a given Identifier
192 *
193 * @param compKey the the Identifier to compare this to
194 * @return true if compKey->key is equal to this->key, else false
195 */
196 bool operator==(const Identifier& compKey) const;
197
198 /**
199 * compares this to a given Identifier
200 *
201 * @param compKey the the Identifier to compare this to
202 * @return true if compKey->key is not equal to this->key, else false
203 */
204 bool operator!=(const Identifier& compKey) const;
205
206 /**
207 * Unifies all compare operations in one method
208 *
209 * @param compKey key to compare with
210 * @return int -1 if smaller, 0 if equal, 1 if greater
211 */
212 int compareTo(const Identifier& compKey) const;
213
214 /**
215 * assigns Identifier of rhs to this->key
216 *
217 * @param rhs the Identifier with the defined key
218 * @return this Identifier object
219 */
220 Identifier& operator=(const Identifier& rhs);
221
222 /**
223 * substracts 1 from this->key
224 *
225 * @return this Identifier object
226 */
227 Identifier& operator--();
228
229 /**
230 * adds 1 to this->key
231 *
232 * @return this Identifier object
233 */
234 Identifier& operator++();
235
236 /**
237 * adds rhs->key to this->key
238 *
239 * @param rhs the Identifier with the defined key
240 * @return this Identifier object
241 */
242 Identifier& operator+=(const Identifier& rhs);
243
244 /**
245 * substracts rhs->key from this->key
246 *
247 * @param rhs the Identifier with the defined key
248 * @return this Identifier object
249 */
250 Identifier& operator-=(const Identifier& rhs);
251
252 /**
253 * adds rhs->key to this->key
254 *
255 * @param rhs the Identifier with the defined key
256 * @return this Identifier object
257 */
258 Identifier operator+(const Identifier& rhs) const;
259
260 /**
261 * substracts rhs->key from this->key
262 *
263 * @param rhs the Identifier with the defined key
264 * @return this Identifier object
265 */
266 Identifier operator-(const Identifier& rhs) const;
267
268 /**
269 * substracts 1 from this->key
270 *
271 * @return this Identifier object
272 */
273 Identifier operator--(int);
274
275 /**
276 * adds 1 to this->key
277 *
278 * @return this Identifier object
279 */
280 Identifier operator++(int);
281
282 /**
283 * bitwise shift right
284 *
285 * @param num number of bits to shift
286 * @return this Identifier object
287 */
288 Identifier operator>>(uint num) const;
289
290 /**
291 * bitwise shift left
292 *
293 * @param num number of bits to shift
294 * @return this Identifier object
295 */
296 Identifier operator<<(uint num) const;
297
298 /**
299 * bitwise AND of rhs->key and this->key
300 *
301 * @param rhs the Identifier AND is calculated with
302 * @return this Identifier object
303 */
304 Identifier operator&(const Identifier& rhs) const;
305
306 /**
307 * bitwise OR of rhs->key and this->key
308 *
309 * @param rhs the Identifier OR is calculated with
310 * @return this Identifier object
311 */
312 Identifier operator|(const Identifier& rhs) const;
313
314 /**
315 * bitwise XOR of rhs->key and this->key
316 *
317 * @param rhs the Identifier XOR is calculated with
318 * @return this Identifier object
319 */
320 Identifier operator^(const Identifier& rhs) const;
321
322 /**
323 * bitwise NOT of this->key
324 *
325 * @return this Identifier object
326 */
327 Identifier operator~() const;
328
329 /**
330 * returns the n-th bit of this->key
331 *
332 * @param n the position of the returned bit
333 * @return the bit on position n in this->key
334 */
335 IdentifierBit operator[](uint n);
336
337 /**
338 * sets a bit of this->key
339 *
340 * @param pos the position of the bit to set
341 * @param value new value for bit at position pos
342 * @return *this
343 */
344 Identifier& setBitAt(uint pos, bool value);
345
346 //-------------------------------------------------------------------------
347 // additional math
348 //-------------------------------------------------------------------------
349
350 /**
351 * Returns a sub integer at position p with n-bits. p is counted starting
352 * from the least significant bit of the key as bit 0. Bit p of the key
353 * becomes bit 0 of the returned integer.
354 *
355 * @param p the position of the sub-integer
356 * @param n the number of bits to be returned (max.32)
357 * @return The sub-integer.
358 */
359 uint32_t get(uint p, uint n) const;
360
361 /**
362 * Returns a hash value for the key
363 *
364 * @return size_t The hash value
365 */
366 size_t hash() const;
367
368 /**
369 * Returns the position of the msb in this key, which represents
370 * just the logarithm to base 2.
371 *
372 * @return The logarithm to base 2 of this key.
373 */
374 int log_2() const;
375
376 /**
377 * Fills the suffix starting at pos with random bits to lsb.
378 *
379 * @param pos
380 * @return Identifier
381 */
382 Identifier randomSuffix(uint pos) const;
383
384 /**
385 * Fills the prefix starting at pos with random bits to msb.
386 *
387 * @param pos
388 * @return Identifier
389 */
390 Identifier randomPrefix(uint pos) const;
391
392 /**
393 * Calculates the number of equal bits from the left with another
394 * Key (shared prefix length)
395 *
396 * @param compKey the Key to compare with
397 * @return length of shared prefix
398 */
399 uint sharedPrefixLength(const Identifier& compKey) const;
400
401 /**
402 * Returns true, if this key is element of the interval (keyA, keyB)
403 * on the ring.
404 *
405 * @param keyA The left border of the interval
406 * @param keyB The right border of the interval
407 * @return True, if the key is element of the interval (keyA, keyB)
408 */
409 bool isBetween(const Identifier& keyA, const Identifier& keyB) const;
410
411 /**
412 * Returns true, if this key is element of the interval (keyA, keyB]
413 * on the ring.
414 *
415 * @param keyA The left border of the interval
416 * @param keyB The right border of the interval
417 * @return True, if the key is element of the interval (keyA, keyB]
418 */
419 bool isBetweenR(const Identifier& keyA, const Identifier& keyB) const;
420
421 /**
422 * Returns true, if this key is element of the interval [keyA, keyB)
423 * on the ring.
424 *
425 * @param keyA The left border of the interval
426 * @param keyB The right border of the interval
427 * @return True, if the key is element of the interval [keyA, keyB)
428 */
429 bool isBetweenL(const Identifier& keyA, const Identifier& keyB) const;
430
431 /**
432 * Returns true, if this key is element of the interval [keyA, keyB]
433 * on the ring.
434 *
435 * @param keyA The left border of the interval
436 * @param keyB The right border of the interval
437 * @return True, if the key is element of the interval [keyA, keyB]
438 */
439 bool isBetweenLR(const Identifier& keyA, const Identifier& keyB) const;
440
441 //-------------------------------------------------------------------------
442 // static methods
443 //-------------------------------------------------------------------------
444
445 /**
446 * Set the length of an Identifier
447 *
448 * @param length keylength in bits
449 */
450 static void setKeyLength(uint length);
451
452 /**
453 * Returns the length in number of bits.
454 *
455 * @return The length in number of bits.
456 */
457 static uint getLength();
458
459 /**
460 * Returns a random key.
461 *
462 * @return A random key.
463 */
464 static Identifier random();
465
466 /**
467 * Returns the maximum key, i.e. a key filled with bit 1
468 *
469 * @return The maximum key, i.e. a key filled with bit 1
470 */
471 static Identifier max();
472
473
474 // README: due to some problems with serialization the keylength
475 // was changed to 192 bit! As none of the hashing functions
476 // can provide 192 bit output, and we currently don't use any
477 // hashing for identifiers in the demo at all ... this is all commented out!!
478 /**
479 * Returns a key with the SHA1 cryptographic hash of a
480 * string
481 *
482 * @param value A string value.
483 * @return SHA1 of value
484 */
485 static Identifier sha1(const string& value);
486
487 static Identifier sha1(const uint8_t* value, size_t length );
488
489 /**
490 * Returns a key 2^exponent.
491 *
492 * @param exponent The exponent.
493 * @return Key=2^exponent.
494 */
495 static Identifier pow2(uint exponent);
496
497private:
498 // private constants
499
500 static uint keyLength; /**< actual length of the key */
501 static uint aSize; /**< number of needed machine words to hold the key*/
502 static mp_limb_t GMP_MSB_MASK; /**< bits to fill up if key does not
503 exactly fit in one or more machine words */
504
505 // private fields
506 bool isUnspec; /**< is this->key unspecified? */
507
508 void seed();
509
510 static const size_t array_size = MAX_KEYLENGTH / (8 * sizeof(mp_limb_t))
511 + (MAX_KEYLENGTH % (8 * sizeof(mp_limb_t)) != 0 ? 1 : 0);
512
513 /** the overlay key this object represents */
514 mp_limb_t key[array_size + 1];
515
516 // private "helper" methods
517 /**
518 * trims key after key operations
519 */
520 void trim();
521
522 /**
523 * set this->key to 0 and isUnspec to false
524 */
525 void clear();
526};
527
528/**
529 * An auxiliary class for single bits in OverlayKey
530 *
531 * Allows statements like "key[n] = true"
532 */
533class IdentifierBit {
534public:
535
536 IdentifierBit(bool value, uint pos, Identifier* key) :
537 bit(value), pos(pos), key(key) {
538 }
539
540 /** Converts to a boolean value */
541 inline operator bool() {
542 return bit;
543 }
544
545 /** Sets the corresponding bit to a boolean value
546 * @param value value to set to
547 */
548 inline IdentifierBit& operator=(bool value) {
549 key->setBitAt(pos, value);
550 return *this;
551 }
552
553 inline IdentifierBit& operator^=(bool value) {
554 key->setBitAt(pos, (*key)[pos] ^ value);
555 return *this;
556 }
557
558private:
559
560 bool bit;
561 uint pos;
562 Identifier* key;
563};
564
565}
566} // namespace ariba, common
567
568/* serializers */
569sznBeginDefault( ariba::utility::Identifier, X ) {
570 // calculate length of key
571 uint16_t len = array_size*sizeof(mp_limb_t);
572 uint8_t unspec = isUnspec;
573
574 // only serialize the lower 16 bits of keyLength
575 X && unspec && len;
576
577 // serialize the identifier
578 for (int i=array_size-1; i>=0; i--) X && key[i];
579
580 // when deserializing reset unspec flag
581 if (X.isDeserializer()) isUnspec = unspec;
582} sznEnd();
583
584#endif /* IDENTIFIER_H_ */
Note: See TracBrowser for help on using the repository browser.