#include "WKdm.h"
static WK_word*
WK_pack_2bits(WK_word* source_buf,
WK_word* source_end,
WK_word* dest_buf) {
WK_word* src_next = source_buf;
WK_word* dest_next = dest_buf;
while (src_next < source_end) {
WK_word temp = src_next[0];
temp |= (src_next[1] << 2);
temp |= (src_next[2] << 4);
temp |= (src_next[3] << 6);
dest_next[0] = temp;
dest_next++;
src_next += 4;
}
return dest_next;
}
static WK_word*
WK_pack_4bits(WK_word* source_buf,
WK_word* source_end,
WK_word* dest_buf) {
WK_word* src_next = source_buf;
WK_word* dest_next = dest_buf;
while (src_next < source_end) {
WK_word temp = src_next[0];
temp |= (src_next[1] << 4);
dest_next[0] = temp;
dest_next++;
src_next += 2;
}
return dest_next;
}
static WK_word*
WK_pack_3_tenbits(WK_word* source_buf,
WK_word* source_end,
WK_word* dest_buf) {
WK_word* src_next = source_buf;
WK_word* dest_next = dest_buf;
while (src_next < source_end) {
WK_word temp = src_next[0];
temp |= (src_next[1] << 10);
temp |= (src_next[2] << 20);
dest_next[0] = temp;
dest_next++;
src_next += 3;
}
return dest_next;
}
unsigned int
WKdm_compress (WK_word* src_buf,
WK_word* dest_buf,
unsigned int num_input_words)
{
DictionaryElement dictionary[DICTIONARY_SIZE];
WK_word tempTagsArray[300];
WK_word tempQPosArray[300];
WK_word tempLowBitsArray[1200];
WK_word* boundary_tmp;
WK_word* next_full_patt;
char* next_tag = (char *) tempTagsArray;
char* next_qp = (char *) tempQPosArray;
WK_word* next_low_bits = tempLowBitsArray;
WK_word* next_input_word = src_buf;
WK_word* end_of_input = src_buf + num_input_words;
PRELOAD_DICTIONARY;
next_full_patt = dest_buf + TAGS_AREA_OFFSET + (num_input_words / 16);
#ifdef WK_DEBUG
printf("\nIn WKdm_compress\n");
printf("About to actually compress, src_buf is %u\n", src_buf);
printf("dictionary is at %u\n", dictionary);
printf("dest_buf is %u next_full_patt is %u\n", dest_buf, next_full_patt);
fflush(stdout);
#endif
while (next_input_word < end_of_input)
{
WK_word *dict_location;
WK_word dict_word;
WK_word input_word = *next_input_word;
dict_location =
(WK_word *)
((void*) (((char*) dictionary) + HASH_TO_DICT_BYTE_OFFSET(input_word)));
dict_word = *dict_location;
if (input_word == dict_word)
{
RECORD_EXACT(dict_location - dictionary);
}
else if (input_word == 0) {
RECORD_ZERO;
}
else
{
WK_word input_high_bits = HIGH_BITS(input_word);
if (input_high_bits == HIGH_BITS(dict_word)) {
RECORD_PARTIAL(dict_location - dictionary, LOW_BITS(input_word));
*dict_location = input_word;
}
else {
RECORD_MISS(input_word);
*dict_location = input_word;
}
}
next_input_word++;
}
#ifdef WK_DEBUG
printf("AFTER MODELING in WKdm_compress()\n"); fflush(stdout);
printf("tempTagsArray holds %u bytes\n",
next_tag - (char *) tempTagsArray);
printf("tempQPosArray holds %u bytes\n",
next_qp - (char *) tempQPosArray);
printf("tempLowBitsArray holds %u bytes\n",
(char *) next_low_bits - (char *) tempLowBitsArray);
printf("next_full_patt is %p\n",
next_full_patt);
printf(" i.e., there are %u full patterns\n",
next_full_patt - (dest_buf + TAGS_AREA_OFFSET + (num_input_words / 16)));
fflush(stdout);
{ int i;
WK_word *arr =(dest_buf + TAGS_AREA_OFFSET + (num_input_words / 16));
printf(" first 20 full patterns are: \n");
for (i = 0; i < 20; i++) {
printf(" %d", arr[i]);
}
printf("\n");
}
#endif
SET_QPOS_AREA_START(dest_buf,next_full_patt);
#ifdef WK_DEBUG
printf("about to pack %u bytes holding tags\n",
next_tag - (char *) tempTagsArray);
{ int i;
char* arr = (char *) tempTagsArray;
printf(" first 200 tags are: \n");
for (i = 0; i < 200; i++) {
printf(" %d", arr[i]);
}
printf("\n");
}
#endif
boundary_tmp = WK_pack_2bits(tempTagsArray,
(WK_word *) ((void *) next_tag),
dest_buf + HEADER_SIZE_IN_WORDS);
#ifdef WK_DEBUG
printf("packing tags stopped at %u\n", boundary_tmp);
#endif
{
unsigned int num_bytes_to_pack = (unsigned int)(next_qp - (char *) tempQPosArray);
unsigned int num_packed_words = (num_bytes_to_pack + 7) >> 3; unsigned int num_source_words = num_packed_words * 2;
WK_word* endQPosArray = tempQPosArray + num_source_words;
for (;
next_qp < (char*)endQPosArray;
next_qp++) {
*next_qp = 0;
}
#ifdef WK_DEBUG
printf("about to pack %u (bytes holding) queue posns.\n",
num_bytes_to_pack);
printf("packing them from %u words into %u words\n",
num_source_words, num_packed_words);
printf("dest is range %u to %u\n",
next_full_patt, next_full_patt + num_packed_words);
{ int i;
char *arr = (char *) tempQPosArray;
printf(" first 200 queue positions are: \n");
for (i = 0; i < 200; i++) {
printf(" %d", arr[i]);
}
printf("\n");
}
#endif
boundary_tmp = WK_pack_4bits(tempQPosArray,
endQPosArray,
next_full_patt);
#ifdef WK_DEBUG
printf("Packing of queue positions stopped at %u\n", boundary_tmp);
#endif // WK_DEBUG
SET_LOW_BITS_AREA_START(dest_buf,boundary_tmp);
}
{
unsigned int num_tenbits_to_pack =
(unsigned int)(next_low_bits - tempLowBitsArray);
unsigned int num_packed_words = (num_tenbits_to_pack + 2) / 3; unsigned int num_source_words = num_packed_words * 3;
WK_word* endLowBitsArray = tempLowBitsArray + num_source_words;
for (;
next_low_bits < endLowBitsArray;
next_low_bits++) {
*next_low_bits = 0;
}
#ifdef WK_DEBUG
printf("about to pack low bits\n");
printf("num_tenbits_to_pack is %u\n", num_tenbits_to_pack);
printf("endLowBitsArray is %u\n", endLowBitsArray);
#endif
boundary_tmp = WK_pack_3_tenbits (tempLowBitsArray,
endLowBitsArray,
boundary_tmp);
SET_LOW_BITS_AREA_END(dest_buf,boundary_tmp);
}
return (unsigned int)((char *) boundary_tmp - (char *) dest_buf);
}