/*
 * Author:
 *         Kendy Kutzner <kutzner@ira.uka.de>
 *
 * (c) 2005 Research Group Dr. Fuhrmann, University of Karlsruhe, Germany
 * All rights reserved.
 *
 * $Id: id.h,v 1.21 2005/11/21 10:46:57 kutzner Exp $
 *
 */

/**
 * \file
 * Declare class id, used to store node and key identifiers.
 */

#ifndef _ID_H_
#define _ID_H_

#include <string>
using namespace std;

#include "utils.h"
#include "igor.h"

/// Size of an identifier.
#define INTS_PER_ID 5

/**
 * An identifier of a node or an key.
 */

class id {
	public:
		/// Construct and initialize as empty.
		id();
		/// Construct with a given int as value.
		id(int val); // DBG use only
		/// Construct a new ID with given value from human readable representation.
		id(const string & val){parseid(val);}
		/// Construct a new ID with given value, but use raw memory at address src and length len as source.
		id(void * src, size_t len){fromraw(src, len);}
		/// Destruction all arround!
		virtual ~id(){return;}
		/// Randomize an id.
		void randomize();
		/// The metric function.
		int closer(const id * id1, const id * id2) const ;
		/// The metric function.
		int closer(const id & id1, const id & id2) const {return closer(&id1, &id2);};
		/// Distinguish empty IDs from usable ones.
		bool empty() const {return _idempty;} ;
		/// Set an ID to unused.
		void setempty(){_idempty = true;};

		/// Convert to human readable / network transportable.
		virtual string tostring() const;
		/// Conversion from human readable / network transportable to internal
		void parseid(string s);

		/// Copy foreign values.
		void change(const id & n);
		/// Compare two IDs.
		bool operator==(const id&) const;

		/// Flip a random bit.
		void create_random_log_fingerdest();
		/// Flip a given bit.
		void create_log_fingerdest(int);
		/// Compute the logarithmus dualis of the distance between two IDs.
		double lddist(id&);
		/// Return the number of bits a ID is made of.
		static int bits(){return INTS_PER_ID * 32;}

		/// Return a pointer to the binary representation of the ID. Not portable. Use with care.
		void * raw(){return (void*)(_id);};
		/// Return the raw lenght of the internal representation. Not portable. Use with care.
		size_t rawlength(){return sizeof(int)*INTS_PER_ID;};
		/// Set the internal representation to the given piece of memory.
		void fromraw(const void *, size_t);

	protected:
		/** 
		 * The internal representation of the ID.
		 * IDs are stored as unsigned 32bit integers.
		 */
		uint32 _id[INTS_PER_ID];
		/**
		 * Whether this is a valid ID or just some invalided space.
		 */
		bool _idempty;
};

#endif

