小样:内存管理系统实现,提供可持久化功能
2013-11-22 14:24
501 查看
基本思想:
1.把内存分块管理,这里是把内存分为64字节一块
2.下一块的地址,不是存储下一块的地址,而是相对偏移地址,为了持久化,
3.把首64字节为保留空间,分别记录 空闲块链表的首地址,使用块链表的首地址
首64字节定义
块的定义如下
内存管理的集体实现
这里提供的是字符串的存储,能存储字符串就可以存储所有的类型,对于一个字符串STR如果大小大于64-8个字节,就采用,多个块存储,如 a1,a2。。。an n个块存储,第一个块a1 -> size 为字符串的大小 STR.size(),其他为0;只要找到第一个块,我们就知道这个字符串STR需要多少个块存储。
1.把内存分块管理,这里是把内存分为64字节一块
2.下一块的地址,不是存储下一块的地址,而是相对偏移地址,为了持久化,
3.把首64字节为保留空间,分别记录 空闲块链表的首地址,使用块链表的首地址
首64字节定义
struct HeadInfo { int freeList; int usedList; unsigned int count; int unused[] };
块的定义如下
class DString { public: int size; //the next node offset int next; char valueStr[valueSize]; DString() { size=0; next=-1; memset(valueStr,0,valueSize*sizeof(char)); } DString(char *str,int length) { size=0; next=-1; memset(valueStr,0,sizeof(char)*valueSize); assert(length<=valueSize); memcpy(valueStr,str,length); size=length; } void setSize(int size) { this->size=size; } void setNextLocation(int location) { next=location; } ~DString() { size=0; next=0; memset(valueStr,0,valueSize*sizeof(char)); } };记得块的初始化,其中 next 执行该块的下一块相对偏移量,通过基地址+next可以找到下一块。
内存管理的集体实现
#include<iostream> #include<fstream> #include "StringPool.h" #include"dString.h" #include"HeadInfo.h" using namespace std; CStringPool::CStringPool ():poolSize(0x1000) { cout<<"CStringPool"<<endl; assert(sizeof(HeadInfo)<=sizeof(DString)); poolP=NULL; poolP=(char *)malloc(sizeof(char)*poolSize); assert(poolP!=NULL); DString fillInfo; int DSsize=sizeof(DString); int offset=0; int nodeCount=poolSize/sizeof(DString); for(int i=0;i<nodeCount;i++) { if(i!=nodeCount-1) { fillInfo.setNextLocation(offset+DSsize); } else { fillInfo.setNextLocation(-1); } memcpy(poolP+offset,&fillInfo,DSsize); offset+=DSsize; } head=(HeadInfo*)poolP; head->freeList=0+DSsize; head->count=0; head->usedList=-1; #ifdef BUG printList(head->freeList); #endif } void CStringPool::printList(int index) { DString * tem1,*tem2; int prelocation,nowLocation; tem1=getNodeList(index); if(tem1!=NULL) cout<<"locaiton : "<<index<<endl; prelocation=index; while((tem2=getNextNode(tem1))!=NULL) { nowLocation=tem1->next; cout<<"prelocaiton: "<<prelocation<<", now location"<<nowLocation<<" "<<nowLocation-prelocation<<endl; prelocation=nowLocation; tem1=tem2; } } DString* CStringPool::getNodeList(int offset) { DString *beginLocation; beginLocation=(DString*) ( poolP+offset); return beginLocation; } int CStringPool ::getNodeIndex(DString *node) { int index= (char *)node -(char*)poolP; if((unsigned int)index>(poolSize-sizeof(DString))) { return -1; } return index; } DString * CStringPool::getNextNode( DString *nowNode) { DString * temP=NULL; if(nowNode->next>0) { temP=(DString*) (poolP+nowNode->next); } return temP; } DString* CStringPool::getFreeNodesAndRemoveFromeFreelist(int nodeNum) { if((head->count+nodeNum)*sizeof(DString)>poolSize) { return NULL; } DString *beginLocation; DString * endLocation=NULL; beginLocation=(DString*)(poolP+head->freeList); endLocation=beginLocation; for(int i=1;i<nodeNum;i++) { endLocation=getNextNode(endLocation); assert(endLocation!=NULL); } head->freeList=endLocation->next; endLocation->next=-1; return beginLocation; } DString* CStringPool::getPreNodeInUseList(int index) { int usedbegin=head->usedList; //if index pointer to the head node if(usedbegin==index) { return getNodeList(index); } if(usedbegin<0) { return NULL; } DString *usedList=getNodeList(usedbegin); while(usedList!=NULL) { if(usedList->next==index) { return usedList; } usedList=getNextNode(usedList); } return NULL; } /* return 0 oK return -1 the index is out of range; */ int CStringPool::getUsedNodesAndRemoveFromeUsedlist(int index) { DString *preNode=getPreNodeInUseList(index); if(preNode!=NULL) { int * preIndexP; if(index==head->usedList) { preIndexP=&(head->usedList); } else { preIndexP=&(preNode->next); } DString *delNode=getNodeList(index); int delLength=delNode->size; assert(delLength>0); DString *tem=delNode; int inNodeOff=sizeof(delNode->next)+sizeof(delNode->size); //clear the node; while(delLength>0) { if((unsigned int)delLength>(sizeof(DString)-inNodeOff)) { tem->size=-1; memset(tem->valueStr,0,sizeof(DString)-inNodeOff); tem=getNextNode(tem); } else { tem->size=-1; memset(tem->valueStr,0,sizeof(DString)-inNodeOff); break; } delLength=delLength-sizeof(DString)+inNodeOff; } // link the used list *preIndexP=tem->next; tem->next=-1; //link to the free list int freeListBeginOffset=head->freeList; head->freeList=getNodeIndex(delNode); tem->next=freeListBeginOffset; return 0; } else { return -1; } } CStringPool::~CStringPool(void) { free(poolP); } int CStringPool::set(const string &strIn) { DString * nodeList; int index=-1; //一个节点中,非用了存储数据的长度 int InnodeOff=sizeof(nodeList->size)+sizeof(nodeList->next); //将要存储的数据需要占几个节点 int nodeNum=(strIn.size()+sizeof(DString)-1)/(sizeof(DString)-InnodeOff); const char *cStrP=strIn.c_str(); int length=strIn.size(); nodeList=getFreeNodesAndRemoveFromeFreelist(nodeNum); if(nodeList==NULL) { return -2; } index=(char *)nodeList-(char *)poolP; nodeList->size=strIn.size(); //DString* beginLocation; //DString *tem; int leftSize= length; while(leftSize>0) { leftSize=leftSize-sizeof(DString)+InnodeOff; if(leftSize>=0) { memcpy(nodeList->valueStr,cStrP,sizeof(DString)-InnodeOff); cStrP=cStrP+(sizeof(DString)-InnodeOff); nodeList=getNextNode(nodeList); } else { memcpy(nodeList->valueStr,cStrP,leftSize+sizeof(DString)-InnodeOff); nodeList->next=-1; } } // update the used list; int oldUsedBeginOffset=head->usedList; head->usedList=index; nodeList->next=oldUsedBeginOffset; return index; } bool CStringPool::get(int index, string & strOut) { //strOut.clear(); DString *strP=getNodeList(index); if(strP==NULL) { cout<<"wrong index"<<endl; return false; } int strLength=strP->size; int inNodeOff=sizeof(strP->next)+sizeof(strP->size); #ifdef BUG cout<<"the length of the string you will get is "<<strP->size<<endl; #endif while(strLength>0) { if((unsigned int)strLength>(sizeof(DString)-inNodeOff)) { strOut.append(strP->valueStr,(sizeof(DString)-inNodeOff)); strP=getNextNode(strP); } else { strOut.append(strP->valueStr,strLength); } strLength=strLength-(sizeof(DString)-inNodeOff); } //cout<<strOut<<endl; return true; } bool CStringPool:: del(int index) { int state=getUsedNodesAndRemoveFromeUsedlist(index); if(state==0) return true; else return false; } bool CStringPool::saveToFile(const string &filePath) { fstream outPut; outPut.open(filePath.c_str(),ios::binary|ios::out); if(outPut!=0) { cout<<"open file error"<<endl; return false; } //write head to file char *p ; int length=poolSize; p=poolP; for(int i=0;i<length;i++) { outPut.put(*p); p++; } return true; } bool CStringPool::loadFromFile(const string &filePath) { fstream input; input.open(filePath.c_str(),ios::binary|ios::in ); if(input==NULL) { cout <<"open file error"<<endl; return false; } int length=poolSize; char * p=poolP; for(int i=0;i<length;i++) { if(input.get(*p)) { p++; } } return true; }
这里提供的是字符串的存储,能存储字符串就可以存储所有的类型,对于一个字符串STR如果大小大于64-8个字节,就采用,多个块存储,如 a1,a2。。。an n个块存储,第一个块a1 -> size 为字符串的大小 STR.size(),其他为0;只要找到第一个块,我们就知道这个字符串STR需要多少个块存储。
相关文章推荐
- LeetCode:Populating Next Right Pointers in Each Node I II
- chapter 3Expressions
- Client Connection to RAC Intermittently ORA-12545 TNS: Host or Object Does not Exist
- replaceAll中的斜杆问题
- 度量Web性能的关键指标
- Netbeans中使用FindBugs Plugin
- eml邮件格式转换为html-python
- apache设置映射文件夹的配置方法
- eclipse 中用svn共享项目
- Python中的异常
- UNIX Domain Socket IPC (sockaddr_un )
- 模拟登陆WINDOWS认证的sharepoint页面
- RH033读书笔记(4)-Lab 5 File Permissions
- iOS9
- 递归法
- Java简单入门---------JDK的检测,安装和环境变量设定
- System Center 2012 R2之SCVMM 2012 R2部署
- NSUserDefaults简介及使用
- linux 上方便上传下载的工具rz/sz安装
- Django Context小解