/*
*****************************************************************************************
*
*   Copyright (C) 1997-200, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*****************************************************************************************
*/
/*===============================================================================
 *
 * File cmpshrta.cpp
 *
 * Modification History:
 *
 *  Date        Name        Description
 *  2/5/97      aliu        Added CompactIntArray streamIn and streamOut methods.
 *  3/4/97      aliu        Tuned performance of CompactIntArray constructor,
 * 05/07/97     helena      Added isBogus()
 *                          based on performance data indicating that this was slow.
 * 07/15/98        erm            Synched with Java 1.2 CompactShortArray.java.
 * 07/30/98        erm            Added changes from 07/29/98 code review.
 *===============================================================================
 */
#include "ucmp16.h"
#include "cmemory.h"





#define arrayRegionMatches(source, sourceStart, target, targetStart, len) (uprv_memcmp(&source[sourceStart], &target[targetStart], len * sizeof(int16_t)) != 0)

/* internal constants*/
#define UCMP16_kMaxUnicode_int 65535
#define UCMP16_kUnicodeCount_int (UCMP16_kMaxUnicode_int + 1)
#define UCMP16_kBlockShift_int 7
#define UCMP16_kBlockCount_int (1 << UCMP16_kBlockShift_int)
#define UCMP16_kBlockBytes_int (UCMP16_kBlockCount_int * sizeof(int16_t))
#define UCMP16_kIndexShift_int (16 - UCMP16_kBlockShift_int)
#define UCMP16_kIndexCount_int (1 << UCMP16_kIndexShift_int)
#define UCMP16_kBlockMask_int (UCMP16_kBlockCount_int - 1)


const int32_t UCMP16_kMaxUnicode = UCMP16_kMaxUnicode_int;
const int32_t UCMP16_kUnicodeCount = UCMP16_kUnicodeCount_int;
const int32_t UCMP16_kBlockShift = UCMP16_kBlockShift_int;
const int32_t UCMP16_kBlockCount = UCMP16_kBlockCount_int;
const int32_t UCMP16_kBlockBytes = UCMP16_kBlockBytes_int;
const int32_t UCMP16_kIndexShift = UCMP16_kIndexShift_int;
const int32_t UCMP16_kIndexCount = UCMP16_kIndexCount_int;
const uint32_t UCMP16_kBlockMask = UCMP16_kBlockMask_int;

/**
 * Sets the array to the invalid memory state.
 */
static CompactShortArray* setToBogus(CompactShortArray* array);
static void touchBlock(CompactShortArray* this,
               int32_t i,
               int16_t value);
static UBool blockTouched(const CompactShortArray* this,
               int32_t i);


/* debug flags*/
/*=======================================================*/

int32_t ucmp16_getkUnicodeCount()
{return UCMP16_kUnicodeCount;}

int32_t ucmp16_getkBlockCount()
{return UCMP16_kBlockCount;}

int32_t ucmp16_getkIndexCount()
{ return UCMP16_kIndexCount;}

CompactShortArray* ucmp16_open(int16_t defaultValue)
{
  int32_t i;
  CompactShortArray* this = (CompactShortArray*) uprv_malloc(sizeof(CompactShortArray));
  if (this == NULL) return NULL;

  this->fCount = UCMP16_kUnicodeCount;
  this->fCompact = FALSE;
  this->fBogus = FALSE;
  this->fArray = NULL;
  this->fIndex = NULL;
  this->fHashes = NULL;
  this->fDefaultValue = defaultValue;

  this->fArray = (int16_t*)uprv_malloc(UCMP16_kUnicodeCount * sizeof(int16_t));
  if (this->fArray == NULL)
    {
      this->fBogus = TRUE;
      return NULL;
    }

  this->fIndex = (uint16_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(uint16_t));
  if (this->fIndex == NULL)
    {
      uprv_free(this->fArray);
      this->fArray = NULL;

      this->fBogus = TRUE;
      return NULL;
    }

  this->kBlockShift = UCMP16_kBlockShift;
  this->kBlockMask = UCMP16_kBlockMask;
  for (i = 0; i < UCMP16_kUnicodeCount; i += 1)
    {
      this->fArray[i] = defaultValue;
    }

  this->fHashes =(int32_t*)uprv_malloc(UCMP16_kIndexCount * sizeof(int32_t));
  if (this->fHashes == NULL)
    {
      uprv_free(this->fArray);
      uprv_free(this->fIndex);
      this->fBogus = TRUE;
      return NULL;
    }

  for (i = 0; i < UCMP16_kIndexCount; i += 1)
    {
      this->fIndex[i] = (uint16_t)(i << UCMP16_kBlockShift);
      this->fHashes[i] = 0;
    }

  return this;
}

CompactShortArray* ucmp16_openAdopt(uint16_t *indexArray,
                    int16_t *newValues,
                    int32_t count,
                    int16_t defaultValue)
{
  CompactShortArray* this = (CompactShortArray*) uprv_malloc(sizeof(CompactShortArray));
  if (this == NULL) return NULL;
  this->fHashes = NULL;
  this->fCount = count;
  this->fDefaultValue = defaultValue;
  this->fBogus = FALSE;
  this->fArray = newValues;
  this->fIndex = indexArray;
  this->fCompact = count < UCMP16_kUnicodeCount;
  this->kBlockShift = UCMP16_kBlockShift;
  this->kBlockMask = UCMP16_kBlockMask;

  return this;
}

CompactShortArray* ucmp16_openAdoptWithBlockShift(uint16_t *indexArray,
                          int16_t *newValues,
                          int32_t count,
                          int16_t defaultValue,
                          int32_t blockShift)
{
  CompactShortArray* this = ucmp16_openAdopt(indexArray,
                         newValues,
                         count,
                         defaultValue);
  if (this == NULL) return NULL;

  this->kBlockShift  = blockShift;
  this->kBlockMask = (uint32_t) (((uint32_t)1 << (uint32_t)blockShift) - (uint32_t)1);

  return this;
}

/*=======================================================*/

void ucmp16_close(CompactShortArray* this)
{
  uprv_free(this->fArray);
  uprv_free(this->fIndex);
  uprv_free(this->fHashes);
  uprv_free(this);

  return;
}

CompactShortArray* setToBogus(CompactShortArray* this)
{
  uprv_free(this->fArray);
  this->fArray = NULL;

  uprv_free(this->fIndex);
  this->fIndex = NULL;

  uprv_free(this->fHashes);
  this->fHashes = NULL;

  this->fCount = 0;
  this->fCompact = FALSE;
  this->fBogus = TRUE;

  return this;
}


void ucmp16_expand(CompactShortArray* this)
{
  if (this->fCompact)
    {
      int32_t i;
      int16_t *tempArray = (int16_t*)uprv_malloc(UCMP16_kUnicodeCount * sizeof(int16_t));

      if (tempArray == NULL)
    {
      this->fBogus = TRUE;
      return;
    }

      for (i = 0; i < UCMP16_kUnicodeCount; i += 1)
    {
      tempArray[i] = ucmp16_get(this, (UChar)i);  /* HSYS : How expand?*/
        }

      for (i = 0; i < (1 << (16 - this->kBlockShift)); i += 1)
    {
      this->fIndex[i] = (uint16_t)(i<<this->kBlockShift);
        }

      uprv_free(this->fArray);
      this->fArray = tempArray;
      this->fCompact = FALSE;
    }
}

void ucmp16_set(CompactShortArray* this,
        UChar c,
        int16_t value)
{
  if (this->fCompact)
    {
      ucmp16_expand(this);
      if (this->fBogus) return;
    }

  this->fArray[(int32_t)c] = value;

  if (value != this->fDefaultValue)
    {
      touchBlock(this, c >> this->kBlockShift, value);
    }
}


void ucmp16_setRange(CompactShortArray* this,
             UChar start,
             UChar end,
             int16_t value)
{
  int32_t i;
  if (this->fCompact)
    {
      ucmp16_expand(this);
      if (this->fBogus)  return;
    }
  if (value != this->fDefaultValue)
    {
      for (i = start; i <= end; i += 1)
    {
       this->fArray[i] = value;
      touchBlock(this, i >> this->kBlockShift, value);
    }
    }
  else
    {
      for (i = start; i <= end; i += 1)      this->fArray[i] = value;
    }
}


/*=======================================================*/
void ucmp16_compact(CompactShortArray* this)
{
  if (!this->fCompact)
    {
      int32_t limitCompacted = 0;
      int32_t i, iBlockStart;
      int16_t iUntouched = -1;

      for (i = 0, iBlockStart = 0; i < (1 << (16 - this->kBlockShift)); i += 1, iBlockStart += (1 << this->kBlockShift))
    {
      UBool touched = blockTouched(this, i);

      this->fIndex[i] = 0xFFFF;

      if (!touched && iUntouched != -1)
        {
          /* If no values in this block were set, we can just set its
           * index to be the same as some other block with no values
           * set, assuming we've seen one yet.
           */
          this->fIndex[i] = iUntouched;
            }
      else
        {
          int32_t j, jBlockStart;

          for (j = 0, jBlockStart = 0;
           j < limitCompacted;
           j += 1, jBlockStart += (1 << this->kBlockShift))
        {
          if (this->fHashes[i] == this->fHashes[j] &&
              arrayRegionMatches(this->fArray,
                     iBlockStart,
                     this->fArray,
                     jBlockStart,
                     (1 << this->kBlockShift)))
            {
              this->fIndex[i] = (int16_t)jBlockStart;
                    }
                }

                /* TODO: verify this is correct*/
          if (this->fIndex[i] == 0xFFFF)
        {
          /* we didn't match, so copy & update*/
          uprv_memcpy(&(this->fArray[jBlockStart]),
                 &(this->fArray[iBlockStart]),
                 (1 << this->kBlockShift)*sizeof(int16_t));

          this->fIndex[i] = (int16_t)jBlockStart;
          this->fHashes[j] = this->fHashes[i];
          limitCompacted += 1;

          if (!touched)
            {
              /* If this is the first untouched block we've seen,*/
              /* remember its index.*/
              iUntouched = (int16_t)jBlockStart;
                    }
                }
            }
        }

        /* we are done compacting, so now make the array shorter*/
      {
    int32_t newSize = limitCompacted * (1 << this->kBlockShift);
    int16_t *result = (int16_t*) uprv_malloc(sizeof(int16_t) * newSize);

    uprv_memcpy(result, this->fArray, newSize * sizeof(int16_t));

    uprv_free(this->fArray);
    this->fArray = result;
    this->fCount = newSize;
    uprv_free(this->fHashes);
    this->fHashes = NULL;

    this->fCompact = TRUE;
      }
    }
}

/**
 * Query whether a specified block was "touched", i.e. had a value set.
 * Untouched blocks can be skipped when compacting the array
 */

int16_t ucmp16_getDefaultValue(const CompactShortArray* this)
{
  return this->fDefaultValue;
}


void touchBlock(CompactShortArray* this,
        int32_t i,
        int16_t value)
{
  this->fHashes[i] = (this->fHashes[i] + (value << 1)) | 1;
}

UBool blockTouched(const CompactShortArray* this, int32_t i)
{
  return (this->fHashes[i] != 0);
}


const int16_t*
ucmp16_getArray(const CompactShortArray* this)
{
    return this->fArray;
}

const uint16_t*
ucmp16_getIndex(const CompactShortArray* this)
{
    return this->fIndex;
}

uint32_t
ucmp16_getCount(const CompactShortArray* this)
{
    return this->fCount;
}

