Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

UnpackMem.hpp

Go to the documentation of this file.
00001 #define MAX_BLOCKSIZE      (2L*1024L*1024L)
00002 #define MIN_DATABLOCKSIZE  512
00003 
00004 struct UnpackDataBlock
00005 {
00006    unsigned long     len;
00007    UnpackDataBlock   *next;
00008    // The data starts right after the last attribute !
00009 
00010    char *GetPtr() {  return (char *)(this+1);  }
00011    unsigned long GetLen() {  return len;  }
00012 };
00013 
00014 struct UnpackMemBlock
00015 {
00016    unsigned long  len;
00017    unsigned long  used;
00018    UnpackMemBlock *next;
00019 };
00020 
00021 class UnpackMemMan
00022 {
00023    UnpackMemBlock *firstblock,*lastblock;
00024    unsigned long  curmaxblocksize;
00025    unsigned long  neededmemoryspace;
00026 
00027    UnpackMemBlock *AllocateMemBlock(UnpackMemBlock **memblockref)
00028    {
00029       // We make sure that we don't try to allocate more than we need
00030       if(curmaxblocksize>neededmemoryspace)
00031          curmaxblocksize=neededmemoryspace;
00032 
00033       // Now we try to allocated as much memory as possible.
00034       // If this fails, we try to allocated half as much, and so on
00035       // If the block size drops below 20000K, we are running out of memory !
00036       do
00037       {
00038          *memblockref=(UnpackMemBlock *)malloc(curmaxblocksize+sizeof(UnpackMemBlock));
00039          if(*memblockref!=NULL)
00040             // We were successful ?? => break
00041          {
00042             (*memblockref)->len=curmaxblocksize;
00043             (*memblockref)->used=0;
00044             (*memblockref)->next=NULL;
00045 
00046             return *memblockref;
00047          }
00048 
00049          curmaxblocksize/=2;  // We try half the size
00050 
00051          if(curmaxblocksize<20000)  // Blocksize is very small ? ==> That's it, we drop out !
00052             return NULL;
00053       }
00054       while(1);
00055    }
00056 
00057 public:
00058 
00059    char Init(unsigned long myneededmemoryspace,unsigned long datablockcount)
00060    {
00061       neededmemoryspace=myneededmemoryspace+datablockcount*sizeof(UnpackDataBlock);
00062       curmaxblocksize=MAX_BLOCKSIZE;
00063 
00064       // Let's see if we can already allocate as much as possible
00065       lastblock=AllocateMemBlock(&firstblock);
00066       if(lastblock==NULL)
00067          return -1;
00068 
00069       return 0;
00070    }
00071 
00072    UnpackDataBlock *AllocateDataBlocks(unsigned long len)
00073    {
00074       UnpackDataBlock *firstdatablock=NULL,**lastdatablockref=&firstdatablock;
00075 
00076       while(lastblock->used+sizeof(UnpackDataBlock)+len>lastblock->len)
00077          // As long as the data block does not fit onto the current memblock
00078          // We must allocate more space !
00079       {
00080          if(lastblock->used+sizeof(UnpackDataBlock)+MIN_DATABLOCKSIZE<lastblock->len)
00081             // If there is a certain minimum space, then we can at least use parts of the
00082             // block
00083          {
00084             *lastdatablockref=(UnpackDataBlock *)((char *)(lastblock+1)+lastblock->used);
00085             (*lastdatablockref)->len=lastblock->len-lastblock->used-sizeof(UnpackDataBlock);
00086             (*lastdatablockref)->next=NULL;
00087 
00088             len-=(*lastdatablockref)->len;
00089             neededmemoryspace-=(*lastdatablockref)->len;
00090 
00091             lastblock->used=lastblock->len;
00092 
00093             lastdatablockref=&((*lastdatablockref)->next);
00094          }
00095 
00096          // Now, we allocate a new block
00097 
00098          lastblock=AllocateMemBlock(&(lastblock->next));
00099          if(lastblock==NULL)
00100             return NULL;
00101 
00102          lastblock=lastblock->next;
00103       }
00104 
00105       *lastdatablockref=(UnpackDataBlock *)((char *)(lastblock+1)+lastblock->used);
00106       (*lastdatablockref)->len=len;
00107       (*lastdatablockref)->next=NULL;
00108 
00109       neededmemoryspace-=len+sizeof(UnpackDataBlock);
00110 
00111       lastblock->used+=sizeof(UnpackDataBlock)+len;
00112 
00113       return firstdatablock;
00114    }
00115 };
00116 
00117 extern UnpackMemMan  unpackmemman;

Generated on Sat Oct 13 16:08:41 2001 for XMILL by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001