#include #include #include "nmglobal.h" #include "nbench1.h" /* ** Word catalog */ #define WORDCATSIZE 50 char *wordcatarray[WORDCATSIZE] = { "Hello", "He", "Him", "the", "this", "that", "though", "rough", "cough", "obviously", "But", "but", "bye", "begin", "beginning", "beginnings", "of", "our", "ourselves", "yourselves", "to", "together", "togetherness", "from", "either", "I", "A", "return", "However", "that", "example", "yet", "quickly", "all", "if", "were", "includes", "always", "never", "not", "small", "returns", "set", "basic", "Entered", "with", "used", "shown", "you", "know" }; /************************ ** HUFFMAN COMPRESSION ** ************************/ /************** ** DoHuffman ** *************** ** Execute a huffman compression on a block of plaintext. ** Note that (as with IDEA encryption) an iteration of the ** Huffman test includes a compression AND a decompression. ** Also, the compression cycle includes building the ** Huffman tree. */ void DoHuffman(void) { HuffStruct *lochuffstruct; /* Loc pointer to global data */ char *errorcontext; int systemerror; unsigned long accumtime; double iterations; char *comparray; char *decomparray; char *plaintext; /* ** Link to global data */ lochuffstruct=&global_huffstruct; /* ** Set error context. */ errorcontext="CPU:Huffman"; /* ** Allocate memory for the plaintext and the compressed text. ** We'll be really pessimistic here, and allocate equal amounts ** for both (though we know...well, we PRESUME) the compressed ** stuff will take less than the plain stuff. ** Also note that we'll build a 3rd buffer to decompress ** into, and we preallocate space for the huffman tree. ** (We presume that the Huffman tree will grow no larger ** than 512 bytes. This is actually a super-conservative ** estimate...but, who cares?) */ plaintext=(char *)AllocateMemory(lochuffstruct->arraysize,&systemerror); if(systemerror) { ReportError(errorcontext,systemerror); } comparray=(char *)AllocateMemory(lochuffstruct->arraysize,&systemerror); if(systemerror) { ReportError(errorcontext,systemerror); FreeMemory(plaintext,&systemerror); } decomparray=(char *)AllocateMemory(lochuffstruct->arraysize,&systemerror); if(systemerror) { ReportError(errorcontext,systemerror); FreeMemory(plaintext,&systemerror); FreeMemory(comparray,&systemerror); } hufftree=(huff_node *)AllocateMemory(sizeof(huff_node) * 512, &systemerror); if(systemerror) { ReportError(errorcontext,systemerror); FreeMemory(plaintext,&systemerror); FreeMemory(comparray,&systemerror); FreeMemory(decomparray,&systemerror); } /* ** Build the plaintext buffer. Since we want this to ** actually be able to compress, we'll use the ** wordcatalog to build the plaintext stuff. */ /* ** Reset random number generator so things repeat. ** added by Uwe F. Mayer */ randnum((int32_t)13); create_text_block(plaintext,lochuffstruct->arraysize-1,(unsigned short)500); plaintext[lochuffstruct->arraysize-1L]='\0'; plaintextlen=lochuffstruct->arraysize; /* ** See if we need to perform self adjustment loop. */ if(lochuffstruct->adjust==0) { /* ** Do self-adjustment. This involves initializing the ** # of loops and increasing the loop count until we ** get a number of loops that we can use. */ for(lochuffstruct->loops=100L; lochuffstruct->loopsloops+=10L) if(DoHuffIteration(plaintext, comparray, decomparray, lochuffstruct->arraysize, lochuffstruct->loops, hufftree)>global_min_ticks) break; } /* ** All's well if we get here. Do the test. */ accumtime=0L; iterations=(double)0.0; do { accumtime+=DoHuffIteration(plaintext, comparray, decomparray, lochuffstruct->arraysize, lochuffstruct->loops, hufftree); iterations+=(double)lochuffstruct->loops; } while(TicksToSecs(accumtime)request_secs); /* ** Clean up, calculate results, and go home. Be sure to ** show that we don't have to rerun adjustment code. */ FreeMemory((void *)plaintext,&systemerror); FreeMemory((void *)comparray,&systemerror); FreeMemory((void *)decomparray,&systemerror); FreeMemory((void *)hufftree,&systemerror); lochuffstruct->iterspersec=iterations / TicksToFracSecs(accumtime); if(lochuffstruct->adjust==0) lochuffstruct->adjust=1; } /********************* ** create_text_line ** ********************** ** Create a random line of text, stored at *dt. The line may be ** no more than nchars long. */ static void create_text_line(char *dt, long nchars) { long charssofar; /* # of characters so far */ long tomove; /* # of characters to move */ char myword[40]; /* Local buffer for words */ char *wordptr; /* Pointer to word from catalog */ charssofar=0; do { /* ** Grab a random word from the wordcatalog */ /* wordptr=wordcatarray[abs_randwc((long)WORDCATSIZE)];*/ wordptr=wordcatarray[abs_randwc((int32_t)WORDCATSIZE)]; MoveMemory((void *)myword, (void *)wordptr, (unsigned long)strlen(wordptr)+1); /* ** Append a blank. */ tomove=strlen(myword)+1; myword[tomove-1]=' '; /* ** See how long it is. If its length+charssofar > nchars, we have ** to trim it. */ if((tomove+charssofar)>nchars) tomove=nchars-charssofar; /* ** Attach the word to the current line. Increment counter. */ MoveMemory((void *)dt,(void *)myword,(unsigned long)tomove); charssofar+=tomove; dt+=tomove; /* ** If we're done, bail out. Otherwise, go get another word. */ } while(charssofartblen) linelen=tblen-bytessofar; if(linelen>1) { create_text_line(tb,linelen); } tb+=linelen-1; /* Add the carriage return */ *tb++='\n'; bytessofar+=linelen; } while(bytessofar>3; bitnumb=bitoffset % 8; /* ** Set or clear */ if(bitchar=='1') comparray[byteoffset]|=(1<>3; bitnumb=bitoffset % 8; /* ** Fetch */ return((1<