
#ifndef consistent_hash_h
#define consistent_hash_h

#include <string>
#include "extent_protocol.h"
#include "../rpc/rpc.h"
#include "member.h"



class  consistent_hash {

	public:
    typedef extent_protocol::extentid_t id_type;


		consistent_hash();
		consistent_hash(std::list<member> lst);

		//LOOKUP
		member lookup(std::string id);
		member lookup(id_type id); //returns the member to whom id maps to
		member lookup_previous(member m); //looks up the member before m in the ring
		member lookup_next(member m); //looks up the member before m in the ring
		member lookup_hash(double h); //looksup based on the given hash
		

		// MEMBERSHIP 
		void set_membership(std::list<member> lst);
		bool contains_member(member m); //true if it contains the given member 
		bool add_member(member m); //true if the member was added (did not exist)
		bool remove_member(member m); //true if the member was removed (existed)
		int size() {return mems.size();}

		//HASHING
		double hash(member m);
		double hash(id_type id);

		void print_mems();
        id_type string_to_id(std::string);

	private:
		std::list<member> mems;
		/* INVARIANT:
		- the mems list is stored in order of increasing hashes of the members
		- no two clients have the same cid
		
		*/
		bool add_my_member(member m); //true if the member was added (did not exist) NO locks used
		pthread_mutex_t ch_lock;

		
	
		//parameters
		static const int prime1 = 211;
		static const int prime2 = 0; //13
		static const int prime3 = 11131;//52711;
		
};

#endif
