/**********************************************
 * * Author: Zhibin Wu, WINLAB, Rutgers University
 * * Date  August 2003
 * *
 * **********************************************/


#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "fixtb.h"

static int rtent_trich(const void *a, const void *b) {
  nsaddr_t ia = ((const fixrt_ent *) a)->dst;
  nsaddr_t ib = ((const fixrt_ent *) b)->dst;
  if (ia > ib) return 1;
  if (ib > ia) return -1;
  return 0;
}

FixRTable::FixRTable() {
  // Let's start with a ten element maxelts.
  elts = 0;
  maxelts = 10;
  rtab = new fixrt_ent[maxelts];
}

void
FixRTable::AddEntry(const fixrt_ent &ent)
{
  fixrt_ent *it;
  //DEBUG
  assert(ent.metric <= BIG);

  if ((it = (fixrt_ent*) bsearch(&ent, rtab, elts, sizeof(fixrt_ent), 
				 rtent_trich))) {
    bcopy(&ent,it,sizeof(fixrt_ent));
    return;
    }

  if (elts == maxelts) {
    fixrt_ent *tmp = rtab;
    maxelts *= 2;
    rtab = new fixrt_ent[maxelts];
    bcopy(tmp, rtab, elts*sizeof(fixrt_ent));
    delete tmp;
  }
  
  int max;
  
  for (max=0;max<elts;max++) {
	  if (ent.dst < rtab[max].dst) {
		  break;
	  }
  }

  int i = elts-1;
  while (i >= max) 
	  rtab[i+1] = rtab[i--];
 
  bcopy(&ent, &rtab[max], sizeof(fixrt_ent));
  elts++;

  return;
}


fixrt_ent *
FixRTable::GetEntry(nsaddr_t dest) {
  fixrt_ent ent;
  ent.dst = dest;
  return (fixrt_ent *) bsearch(&ent, rtab, elts, sizeof(fixrt_ent), 
				rtent_trich);
}
