/* Copyright (c) 1991-2002 Doshita Lab. Speech Group, Kyoto University */
/* Copyright (c) 2000-2002 Speech and Acoustics Processing Lab., NAIST */
/*   All rights reserved   */

/* gprune_common.c --- common functions for gprune_*.c */

/* $Id: gprune_common.c,v 1.2 2002/09/11 22:01:50 ri Exp $ */

#include <sent/stddefs.h>
#include <sent/htk_hmm.h>
#include <sent/htk_param.h>
#include <sent/hmm.h>
#include <sent/gprune.h>
#include "globalvars.h"

/* OP_calced operations */
int
find_insert_point(LOGPROB score, int len)
{
  /* binary search on score */
  int left = 0;
  int right = len - 1;
  int mid;

  while (left < right) {
    mid = (left + right) / 2;
    if (OP_calced_score[mid] > score) {
      left = mid + 1;
    } else {
      right = mid;
    }
  }
  return(left);
}
int
cache_push(int id, LOGPROB score, int len)
{
  int insertp;
  int i;

  if (len == 0) {               /* first one */
    OP_calced_score[0] = score;
    OP_calced_id[0] = id;
    return(1);
  }
  if (OP_calced_score[len-1] >= score) { /* bottom */
    if (len < OP_gprune_num) {          /* append to bottom */
      OP_calced_score[len] = score;
      OP_calced_id[len] = id;
      len++;
    }
    return len;
  }
  if (OP_calced_score[0] < score) {
    insertp = 0;
  } else {
    insertp = find_insert_point(score, len);
  }
  if (len < OP_gprune_num) {
    bcopy(&(OP_calced_score[insertp]), &(OP_calced_score[insertp+1]), sizeof(LOGPROB)*(len - insertp));
    bcopy(&(OP_calced_id[insertp]), &(OP_calced_id[insertp+1]), sizeof(int)*(len - insertp));    
  } else if (insertp < len - 1) {
    bcopy(&(OP_calced_score[insertp]), &(OP_calced_score[insertp+1]), sizeof(LOGPROB)*(len - insertp - 1));
    bcopy(&(OP_calced_id[insertp]), &(OP_calced_id[insertp+1]), sizeof(int)*(len - insertp - 1));
  }
  OP_calced_score[insertp] = score;
  OP_calced_id[insertp] = id;
  if (len < OP_gprune_num) len++;
  return(len);
}

