⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mempool.cpp.svn-base

📁 解码器是基于短语的统计机器翻译系统的核心模块
💻 SVN-BASE
字号:
/****************************************************************************** IrstLM: IRST Language Model Toolkit Copyright (C) 2006 Marcello Federico, ITC-irst Trento, Italy This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA******************************************************************************/// An efficient memory pool manager // by M. Federico // Copyright Marcello Federico, ITC-irst, 1998#include <iostream>#include <ostream>#include <cassert>#include "mempool.h"using namespace std;#ifdef TRACE_ENABLE#define TRACE_ERR(str) { std::cerr << str; }#else#define TRACE_ERR(str) { }#endif/*! The pool contains:   - entries of size is   - tables for bs entries*/mempool::mempool(int is, int bs){    // item size must be multiple of memory alignment step (4 bytes)  // example: is is=9  becomes i=12 (9 + 4 - 9 %4 )    is=(is>(int)sizeof(char *)?is:0);       is=is + sizeof(char *) - (is % sizeof(char *));      item_size  = is;    block_size = bs;          true_size  = is * bs;    block_list = new memnode;    block_list->block = new char[true_size];    memset(block_list->block,'0',true_size);    block_list->next  = 0;    blocknum = 1;    entries  = 0;    // build free list    char *ptr = free_list = block_list->block;    for (int i=0;i<block_size-1;i++) {    *(char **)ptr= ptr + item_size;    ptr+=item_size;                       }  *(char **)ptr = NULL; //last item  }char * mempool::allocate(){    char *ptr;    if (free_list==NULL)  {    memnode *new_block = new memnode;        new_block->block = new char[true_size];        //memset(new_block->block,'0',true_size);        new_block->next  = block_list;        block_list=new_block; // update block list        /* update  free list */        ptr = free_list = block_list->block;        for (int i=0;i<block_size-1;i++) {      *(char **)ptr = ptr + item_size;      ptr = ptr + item_size;                     }         *(char **)ptr=NULL;        blocknum++;  }    assert(free_list);    ptr = free_list;    free_list=*(char **)ptr;    *(char **)ptr=NULL; // reset the released item    entries++;    return ptr;  }int mempool::free(char* addr){    // do not check if it belongs to this pool !!  /*   memnode  *list=block_list;   while ((list != NULL) &&          ((addr < list->block) ||           (addr >= (list->block + true_size))))   list=list->next;      if ((list==NULL) || (((addr - list->block) % item_size)!=0))   {     //cerr << "mempool::free-> addr does not belong to this pool\n";     return 0;   }   */    *(char **)addr=free_list;  free_list=addr;    entries--;    return 1;}mempool::~mempool(){  memnode *ptr;    while (block_list !=NULL){    ptr=block_list->next;        delete [] block_list->block;    delete block_list;    block_list=ptr;  }   }void mempool::map (ostream& co){    co << "mempool memory map:\n";  //percorri piu` volte la lista libera    memnode *bl=block_list;  char *fl=free_list;    char* img=new char[block_size+1];  img[block_size]='\0';    while (bl !=NULL){        memset(img,'#',block_size);        fl=free_list;    while (fl != NULL){      if ((fl >= bl->block)           &&           (fl < bl->block + true_size))      {        img[(fl-bl->block)/item_size]='-';      }            fl=*(char **)fl;                         }          co << img << "\n";    bl=bl->next;      } 	delete [] img;}void mempool::stat(){    TRACE_ERR("mempool class statistics\n"            << "entries " << entries            << " blocks " << blocknum            << " used memory " << (blocknum * true_size)/1024 << " Kb\n");}strstack::strstack(int bs){    size=bs;  list=new memnode;    list->block=new char[size];    list->next=0;    memset(list->block,'\0',size);  idx=0;    waste=0;  memory=size;  entries=0;  blocknum=1;  }void strstack::stat(){    TRACE_ERR("strstack class statistics\n"            << "entries " << entries            << " blocks " << blocknum            << " used memory " << memory/1024 << " Kb\n");}char *strstack::push(char *s){  int len=strlen(s);    if ((len+1) >= size){    cerr << "strstack::push string is too long\n";    exit(1);  };    if ((idx+len+1) >= size){    //append a new block    //there must be space to     //put the index after     //the word        waste+=size-idx;    blocknum++;    memory+=size;        memnode* nd=new memnode;    nd->block=new char[size];    nd->next=list;        list=nd;        memset(list->block,'\0',size);        idx=0;      }    // append in current block    strcpy(&list->block[idx],s);    idx+=len+1;    entries++;    return &list->block[idx-len-1];  }char *strstack::pop(){    if (list==0) return 0;    if (idx==0){        // free this block and go to next        memnode *ptr=list->next;        delete [] list->block;    delete list;        list=ptr;        if (list==0)       return 0;    else      idx=size-1;  }    //go back to first non \0  while (idx>0)     if (list->block[idx--]!='\0')      break;    //go back to first \0  while (idx>0)     if (list->block[idx--]=='\0')      break;    entries--;    if (list->block[idx+1]=='\0')  {    idx+=2;    memset(&list->block[idx],'\0',size-idx);    return &list->block[idx];  }  else{    idx=0;    memset(&list->block[idx],'\0',size);    return &list->block[0];  }}char *strstack::top(){    int tidx=idx;  memnode *tlist=list;    if (tlist==0) return 0;    if (idx==0){        tlist=tlist->next;        if (tlist==0) return 0;        tidx=size-1;  }    //go back to first non \0  while (tidx>0)     if (tlist->block[tidx--]!='\0')      break;    //aaa\0bbb\0\0\0\0    //go back to first \0  while (tidx>0)     if (tlist->block[tidx--]=='\0')      break;    if (tlist->block[tidx+1]=='\0')  {    tidx+=2;    return &tlist->block[tidx];  }  else{    tidx=0;    return &tlist->block[0];  }  }strstack::~strstack(){  memnode *ptr;  while (list !=NULL){    ptr=list->next;        delete [] list->block;    delete list;    list=ptr;  } }storage::storage(int maxsize,int blocksize){  newmemory=0;  newcalls=0;  setsize=maxsize;  poolsize=blocksize; //in bytes  poolset=new mempool* [setsize+1];  for (int i=0;i<=setsize;i++)    poolset[i]=NULL;}storage::~storage(){  for (int i=0;i<=setsize;i++)    if (poolset[i])      delete poolset[i];  delete [] poolset;}char *storage::allocate(int size){    if (size<=setsize){    if (!poolset[size]){      poolset[size]=new mempool(size,poolsize/size);    }    return poolset[size]->allocate();  }  else{        newmemory+=size+8;    newcalls++;    char* p=(char *)calloc(sizeof(char),size);    if (p==NULL){      cerr << "storage::alloc insufficient memory\n";      exit(1);    }    return p;  }}char *storage::reallocate(char *oldptr,int oldsize,int newsize){    char *newptr;    assert(newsize>oldsize);    if (oldsize<=setsize){    if (newsize<=setsize){      if (!poolset[newsize])        poolset[newsize]=new mempool(newsize,poolsize/newsize);      newptr=poolset[newsize]->allocate();      memset((char*)newptr,0,newsize);    }    else      newptr=(char *)calloc(sizeof(char),newsize);        if (oldptr && oldsize){      memcpy(newptr,oldptr,oldsize);      poolset[oldsize]->free(oldptr);    }  }  else{    newptr=(char *)realloc(oldptr,newsize);    if (newptr==oldptr)       cerr << "r\b";    else      cerr << "a\b";  }  if (newptr==NULL){    cerr << "storage::realloc insufficient memory\n";    exit(1);  }    return newptr;}int storage::free(char *addr,int size){    /*   while(size<=setsize){     if (poolset[size] && poolset[size]->free(addr))       break;     size++;   }   */    if (size>setsize)    return free(addr),1;  else{    poolset[size] && poolset[size]->free(addr);  }  return 1;}void storage::stat(){  int used=0;  int memory=sizeof(char *) * setsize;  int waste=0;    for (int i=0;i<=setsize;i++)    if (poolset[i]){      used++;      memory+=poolset[i]->used();      waste+=poolset[i]->wasted();    }            TRACE_ERR("storage class statistics\n"                << "alloc entries " << newcalls                 << " used memory " << newmemory/1024 << "Kb\n"                << "mpools " << setsize                << " active  " << used                 << " used memory " << memory/1024 << "Kb"                << " wasted " << waste/1024 << "Kb\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -