 /*
  * (C) 2003-2004 Columbia University Departments of Computer Science and
  * Electrical Engineering
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, is permitted provided the original authors give
  * written consent and the following conditions are met:
  *
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above
  *    copyright notice, this list of conditions and the following
  *    disclaimer in the documentation and/or other materials
  *    provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  * OF SUCH DAMAGE.
  */
void MyTable::SetFinger(int index, UINT id)
{
	if((index < LOGN)&&(Finger[index] != id))
	{
		Finger[index] = id;
		ResetStabilizeTimer();
	}
}

void MyTable::SetPredecessor(UINT id)
{
	if(Predecessor != id)
	{
		Predecessor = id;
		ResetStabilizeTimer();
	}
}



UINT MyTable::GetNextHop(UINT id)
{
	if(id == MyID)
		return MyID;
	for(int i=LOGN - 1;i >= 0;i--)
	{
		if(Belongs(Finger[i], MyID, id, 0, 1, FALSE))
			  return Finger[i];
	}
	// Error !!!!
	// id is between MyID and MySuccessor
	return(MyID);
//	printf("%s: Strange Error: Finger Table not good\n",__FUNCTION__);
//	exit(-1);
}

UINT MyTable::GetClosestPrecedingFinger(UINT id)
{
	for(int i=LOGN - 1;i >= 0;i--)
	{
		if(Belongs(Finger[i], MyID, id, 0, 0, TRUE))
			  return Finger[i];
	}
	// Error !!!!
	// id is between MyID and MySuccessor
	printf("%s: Strange Error: Finger Table not good\n",__FUNCTION__);
	exit(-1);
}

void MyTable::UpdatePredecessor(UINT newpred)
{
	if((Predecessor == MyID)||Belongs(newpred, Predecessor, MyID, 0, 0, FALSE))
	{
		Predecessor = newpred;
	}
}

void MyTable::print(int curr_timer)
{
	system("clear");
	printf("##################### My Finger Table ####################\n");
	printf("Current Stabilize TIMER is %.2f ms\n",(float)curr_timer/1000.0);
	printf("Me = %d, Pred = %d\n",MyID, Predecessor);
	for(int i=0;i < LOGN;i++)
	{
		UINT start = GetIthStart(MyID, i);
		UINT end = (GetIthStart(MyID, i+1) - 1 + MAX_N) % MAX_N;
		printf("Finger %d: Range (%d,%d) = %d\n",i, start, end, Finger[i]);
	}
}
