由于一些需求需要,简单实现了一个共享内存map。
#ifndef MKEYINTSHMMAP_HPP_
#define MKEYINTSHMMAP_HPP_
#include < sys / ipc.h >
#include < sys / shm.h >
/**/ /**
* 适合小数据量,int 索引
* 数据量越多效率相对降低.
* 每次插入,删除都会重建索引
* 查找相对快速,二分数组查找.
* 适合于load数据到内存的查询修改操作.对于频繁增加减少的不适合
*
* 没有锁操作,如果多进程操作,自己加锁
*
* T 必须是不含有指针的固定大小可存入结构体
*
*/
template < class T >
class MKeyIntShmMap
... {
public:
MKeyIntShmMap(int t_shmkey,int t_max_size)
...{
max_size = t_max_size;
sizePtr = NULL;
keyPtr = NULL;
elementPtr = NULL;
int shmid;
shmid=shmget(t_shmkey,sizeof(int)+(sizeof(int)*3)*t_max_size+t_max_size*sizeof(T),IPC_CREAT|0666);
if(shmid<=0)
...{
fprintf(stderr," shm new exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
int addr = (int)shmat(shmid, 0, 0);
if(addr<=0)
...{
fprintf(stderr," shm mat exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
shm_addr = (char *)addr;
//共享内存第一段int 存个数
sizePtr = (int *)shm_addr;
//第二位存最小空闲块
minfreePtr = (int *)(shm_addr+sizeof(int));
//共享内存第二段,存 key 列表
keyPtr = (int *)(shm_addr+sizeof(int)*2);
//共享内存第三段,存 块占用标记
indexPtr = (int *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size);
//存内存使用标记
flagPtr = (int *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size+sizeof(int)*max_size);
//共享内存第四段,数据区域
elementPtr = (T *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size+sizeof(int)*max_size+sizeof(int)*max_size);
//第一次创建
struct shmid_ds shmid_st;
shmctl(shmid, IPC_STAT, &shmid_st);
if (shmid_st.shm_cpid == getpid())
...{
*sizePtr = 0;
*minfreePtr = 0;
for(int i=0;i<max_size;i++)
...{
flagPtr[i] = 0;
}
}
}
~MKeyIntShmMap()
...{
}
T* add(int key,const T& obj)
...{
if((*sizePtr)>=max_size)
...{
return NULL;
}
int pos = 0;
int flag = findPos(key,pos);
if(flag)
...{
//flagPtr[indexPtr[pos]] = 0;
elementPtr[indexPtr[pos]] = obj;
}
else
...{
for(int i=(*sizePtr);i>pos;i--)
...{
keyPtr[i] = keyPtr[i-1];
indexPtr[i] = indexPtr[i-1];
}
int tpos = -1;
for(int i=(*minfreePtr);i<max_size;i++)
...{
if(flagPtr[i]==0)
...{
tpos = i;
break;
}
}
flagPtr[tpos] = 1;
(*minfreePtr) = tpos+1;
keyPtr[pos] = key;
indexPtr[pos] = tpos;
elementPtr[tpos] = obj;
(*sizePtr)++;
}
return &elementPtr[indexPtr[pos]];
}
void del(int key)
...{
int pos = 0;
int flag = findPos(key,pos);
if(flag)
...{
flagPtr[indexPtr[pos]] = 0;
if((*minfreePtr)>indexPtr[pos])
...{
(*minfreePtr) = indexPtr[pos];
}
for(int i=pos+1;i<(*sizePtr);i++)
...{
keyPtr[i-1] = keyPtr[i];
indexPtr[i-1] = indexPtr[i];
}
(*sizePtr)--;
}
}
T& operator[](int key)
...{
if((*sizePtr)>=max_size)
...{
fprintf(stderr," shm full exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
int pos = 0;
int flag = findPos(key,pos);
if(flag)
...{
return elementPtr[indexPtr[pos]];
}
else
...{
for(int i=(*sizePtr);i>pos;i--)
...{
keyPtr[i] = keyPtr[i-1];
indexPtr[i] = indexPtr[i-1];
}
int tpos = -1;
for(int i=(*minfreePtr);i<max_size;i++)
...{
if(flagPtr[i]==0)
...{
tpos = i;
break;
}
}
flagPtr[tpos] = 1;
(*minfreePtr) = tpos+1;
keyPtr[pos] = key;
indexPtr[pos] = tpos;
T obj;
elementPtr[tpos] = obj;
(*sizePtr)++;
return elementPtr[indexPtr[pos]];
}
}
T* find(int key)
...{
int pos = 0;
int flag = findPos(key,pos);
if(flag)
...{
return &elementPtr[indexPtr[pos]];
}
else
...{
return NULL;
}
}
int getSize()
...{
return (*sizePtr);
}
int getKey(int pos)
...{
return keyPtr[pos];
}
T* get(int pos)
...{
return &elementPtr[indexPtr[pos]];
}
void clear()
...{
*sizePtr = 0;
for(int i=0;i<max_size;i++)
...{
flagPtr[i] = 0;
}
(*minfreePtr) = 0;
}
protected:
private:
//找到key所在的位置
//找到key,返回1,pos指向所在位置
//找不到key,返回0,pos指向所应该插入位置
int findPos(int key,int &pos)
...{
if((*sizePtr)==0)
...{
pos = 0;
return 0;
}
int p0 = 0;
int p2 = (*sizePtr)-1;
int p1 = (p0+p2)/2;
while(true)
...{
int cmp = 0;
if(key>keyPtr[p1])
...{
cmp = 1;
}
else if(key<keyPtr[p1])
...{
cmp = -1;
}
else
...{
cmp = 0;
}
if(cmp>0)
...{
if(p2-p1>1)
...{
p0 = p1;
p1 = (p0+p2)/2;
}
else
...{
if(key>keyPtr[p2])
...{
pos = p2+1;
return 0;
}
else if(key<keyPtr[p2])
...{
pos = p1+1;
return 0;
}
else
...{
pos = p2;
return 1;
}
}
}
else if(cmp<0)
...{
if(p1-p0>1)
...{
p2 = p1;
p1 = (p0+p2)/2;
}
else
...{
if(key<keyPtr[p0])
...{
pos = p0;
return 0;
}
else if(key>keyPtr[p0])
...{
pos = p0+1;
return 0;
}
else
...{
pos = p0;
return 1;
}
}
}
else
...{
pos = p1;
return 1;
}
}
}
char * shm_addr;
int max_size;
int * minfreePtr;
int * sizePtr;
int * keyPtr;
int * flagPtr;
int * indexPtr;
T* elementPtr; //数据中不含NULL指针
} ;
/**/ /*
* 没有测试过,可能含有错误,因为map操作,最好在应用层考虑加解锁,所以,不建议使用
template<class T>
class MKeyIntShmSafeMap
{
public:
MKeyIntShmSafeMap(int t_shmkey,int t_semkey,int t_max_size)
{
int sid;
sid=semget(t_semkey,1,IPC_CREAT|0666);
if(sid<=0)
{
fprintf(stderr," sem new exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
semun arg;
arg.val = 1;
if (semctl(sid, 0, SETVAL, arg)==-1)
{
fprintf(stderr," sem ctl exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
semid = sid;
lock();
max_size = t_max_size;
sizePtr = NULL;
keyPtr = NULL;
elementPtr = NULL;
int shmid;
shmid=shmget(t_shmkey,sizeof(int)+(sizeof(int)*3)*t_max_size+t_max_size*sizeof(T),IPC_CREAT|0666);
if(shmid<=0)
{
fprintf(stderr," shm new exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
unlock();
throw MEXP_NEW;
}
int addr = (int)shmat(shmid, 0, 0);
if(addr<=0)
{
fprintf(stderr," shm mat exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
unlock();
throw MEXP_NEW;
}
shm_addr = (char *)addr;
//共享内存第一段int 存个数
sizePtr = (int *)shm_addr;
//第二位存最小空闲块
minfreePtr = (int *)(shm_addr+sizeof(int));
//共享内存第二段,存 key 列表
keyPtr = (int *)(shm_addr+sizeof(int)*2);
//共享内存第三段,存 块占用标记
indexPtr = (int *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size);
//存内存使用标记
flagPtr = (int *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size+sizeof(int)*max_size);
//共享内存第四段,数据区域
elementPtr = (T *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size+sizeof(int)*max_size+sizeof(int)*max_size);
//第一次创建
struct shmid_ds shmid_st;
shmctl(shmid, IPC_STAT, &shmid_st);
if (shmid_st.shm_cpid == getpid())
{
*sizePtr = 0;
*minfreePtr = 0;
for(int i=0;i<max_size;i++)
{
flagPtr[i] = 0;
}
}
unlock();
}
~MKeyIntShmMap()
{
}
int add(int key,const T& obj)
{
lock();
if((*sizePtr)>=max_size)
{
unlock();
return -1;
}
int pos = 0;
int flag = findPos(key,pos);
if(flag)
{
//flagPtr[indexPtr[pos]] = 0;
elementPtr[indexPtr[pos]] = obj;
}
else
{
for(int i=(*sizePtr);i>pos;i--)
{
keyPtr[i] = keyPtr[i-1];
indexPtr[i] = indexPtr[i-1];
}
int tpos = -1;
for(int i=(*minfreePtr);i<max_size;i++)
{
if(flagPtr[i]==0)
{
tpos = i;
break;
}
}
flagPtr[tpos] = 1;
(*minfreePtr) = tpos+1;
keyPtr[pos] = key;
indexPtr[pos] = tpos;
elementPtr[tpos] = obj;
(*sizePtr)++;
}
unlock();
return 0;
}
void del(int key)
{
lock();
int pos = 0;
int flag = findPos(key,pos);
if(flag)
{
flagPtr[indexPtr[pos]] = 0;
if((*minfreePtr)>indexPtr[pos])
{
(*minfreePtr) = indexPtr[pos];
}
for(int i=pos+1;i<(*sizePtr);i++)
{
keyPtr[i-1] = keyPtr[i];
indexPtr[i-1] = indexPtr[i];
}
(*sizePtr)--;
}
unlock();
}
int find(int key,T & obj)
{
lock();
int pos = 0;
int flag = findPos(key,pos);
if(flag)
{
obj = elementPtr[indexPtr[pos]];
unlock();
return 0;
}
else
{
unlock();
return -1;
}
}
int getSize()
{
return (*sizePtr);
}
int getKey(int pos)
{
return keyPtr[pos];
}
int get(int pos,T &obj)
{
obj = elementPtr[indexPtr[pos]];
}
void clear()
{
lock();
*sizePtr = 0;
for(int i=0;i<max_size;i++)
{
flagPtr[i] = 0;
}
(*minfreePtr) = 0;
unlock();
}
protected:
private:
//找到key所在的位置
//找到key,返回1,pos指向所在位置
//找不到key,返回0,pos指向所应该插入位置
int findPos(int key,int &pos)
{
if((*sizePtr)==0)
{
pos = 0;
return 0;
}
int p0 = 0;
int p2 = (*sizePtr)-1;
int p1 = (p0+p2)/2;
while(true)
{
int cmp = 0;
if(key>keyPtr[p1])
{
cmp = 1;
}
else if(key<keyPtr[p1])
{
cmp = -1;
}
else
{
cmp = 0;
}
if(cmp>0)
{
if(p2-p1>1)
{
p0 = p1;
p1 = (p0+p2)/2;
}
else
{
if(key>keyPtr[p2])
{
pos = p2+1;
return 0;
}
else if(key<keyPtr[p2])
{
pos = p1+1;
return 0;
}
else
{
pos = p2;
return 1;
}
}
}
else if(cmp<0)
{
if(p1-p0>1)
{
p2 = p1;
p1 = (p0+p2)/2;
}
else
{
if(key<keyPtr[p0])
{
pos = p0;
return 0;
}
else if(key>keyPtr[p0])
{
pos = p0+1;
return 0;
}
else
{
pos = p0;
return 1;
}
}
}
else
{
pos = p1;
return 1;
}
}
}
void lock()
{
//加锁
struct sembuf op[1] = {{0, -1, 0}};
if (semop (sid, &op[0], 1) == -1)
{
fprintf(stderr," sem lock exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
}
void unlock()
{
//解锁
struct sembuf op[1] = {{0, 1, 0}};
if (semop (sid, &op[0], 1) == -1)
{
fprintf(stderr," sem unlock exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
}
int semid;
char * shm_addr;
int max_size;
int * minfreePtr;
int * sizePtr;
int * keyPtr;
int * flagPtr;
int * indexPtr;
T* elementPtr; //数据中不含NULL指针
};
*/
#endif /*MKEYINTSHMMAP_HPP_*/
#define MKEYINTSHMMAP_HPP_
#include < sys / ipc.h >
#include < sys / shm.h >
/**/ /**
* 适合小数据量,int 索引
* 数据量越多效率相对降低.
* 每次插入,删除都会重建索引
* 查找相对快速,二分数组查找.
* 适合于load数据到内存的查询修改操作.对于频繁增加减少的不适合
*
* 没有锁操作,如果多进程操作,自己加锁
*
* T 必须是不含有指针的固定大小可存入结构体
*
*/
template < class T >
class MKeyIntShmMap
... {
public:
MKeyIntShmMap(int t_shmkey,int t_max_size)
...{
max_size = t_max_size;
sizePtr = NULL;
keyPtr = NULL;
elementPtr = NULL;
int shmid;
shmid=shmget(t_shmkey,sizeof(int)+(sizeof(int)*3)*t_max_size+t_max_size*sizeof(T),IPC_CREAT|0666);
if(shmid<=0)
...{
fprintf(stderr," shm new exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
int addr = (int)shmat(shmid, 0, 0);
if(addr<=0)
...{
fprintf(stderr," shm mat exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
shm_addr = (char *)addr;
//共享内存第一段int 存个数
sizePtr = (int *)shm_addr;
//第二位存最小空闲块
minfreePtr = (int *)(shm_addr+sizeof(int));
//共享内存第二段,存 key 列表
keyPtr = (int *)(shm_addr+sizeof(int)*2);
//共享内存第三段,存 块占用标记
indexPtr = (int *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size);
//存内存使用标记
flagPtr = (int *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size+sizeof(int)*max_size);
//共享内存第四段,数据区域
elementPtr = (T *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size+sizeof(int)*max_size+sizeof(int)*max_size);
//第一次创建
struct shmid_ds shmid_st;
shmctl(shmid, IPC_STAT, &shmid_st);
if (shmid_st.shm_cpid == getpid())
...{
*sizePtr = 0;
*minfreePtr = 0;
for(int i=0;i<max_size;i++)
...{
flagPtr[i] = 0;
}
}
}
~MKeyIntShmMap()
...{
}
T* add(int key,const T& obj)
...{
if((*sizePtr)>=max_size)
...{
return NULL;
}
int pos = 0;
int flag = findPos(key,pos);
if(flag)
...{
//flagPtr[indexPtr[pos]] = 0;
elementPtr[indexPtr[pos]] = obj;
}
else
...{
for(int i=(*sizePtr);i>pos;i--)
...{
keyPtr[i] = keyPtr[i-1];
indexPtr[i] = indexPtr[i-1];
}
int tpos = -1;
for(int i=(*minfreePtr);i<max_size;i++)
...{
if(flagPtr[i]==0)
...{
tpos = i;
break;
}
}
flagPtr[tpos] = 1;
(*minfreePtr) = tpos+1;
keyPtr[pos] = key;
indexPtr[pos] = tpos;
elementPtr[tpos] = obj;
(*sizePtr)++;
}
return &elementPtr[indexPtr[pos]];
}
void del(int key)
...{
int pos = 0;
int flag = findPos(key,pos);
if(flag)
...{
flagPtr[indexPtr[pos]] = 0;
if((*minfreePtr)>indexPtr[pos])
...{
(*minfreePtr) = indexPtr[pos];
}
for(int i=pos+1;i<(*sizePtr);i++)
...{
keyPtr[i-1] = keyPtr[i];
indexPtr[i-1] = indexPtr[i];
}
(*sizePtr)--;
}
}
T& operator[](int key)
...{
if((*sizePtr)>=max_size)
...{
fprintf(stderr," shm full exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
int pos = 0;
int flag = findPos(key,pos);
if(flag)
...{
return elementPtr[indexPtr[pos]];
}
else
...{
for(int i=(*sizePtr);i>pos;i--)
...{
keyPtr[i] = keyPtr[i-1];
indexPtr[i] = indexPtr[i-1];
}
int tpos = -1;
for(int i=(*minfreePtr);i<max_size;i++)
...{
if(flagPtr[i]==0)
...{
tpos = i;
break;
}
}
flagPtr[tpos] = 1;
(*minfreePtr) = tpos+1;
keyPtr[pos] = key;
indexPtr[pos] = tpos;
T obj;
elementPtr[tpos] = obj;
(*sizePtr)++;
return elementPtr[indexPtr[pos]];
}
}
T* find(int key)
...{
int pos = 0;
int flag = findPos(key,pos);
if(flag)
...{
return &elementPtr[indexPtr[pos]];
}
else
...{
return NULL;
}
}
int getSize()
...{
return (*sizePtr);
}
int getKey(int pos)
...{
return keyPtr[pos];
}
T* get(int pos)
...{
return &elementPtr[indexPtr[pos]];
}
void clear()
...{
*sizePtr = 0;
for(int i=0;i<max_size;i++)
...{
flagPtr[i] = 0;
}
(*minfreePtr) = 0;
}
protected:
private:
//找到key所在的位置
//找到key,返回1,pos指向所在位置
//找不到key,返回0,pos指向所应该插入位置
int findPos(int key,int &pos)
...{
if((*sizePtr)==0)
...{
pos = 0;
return 0;
}
int p0 = 0;
int p2 = (*sizePtr)-1;
int p1 = (p0+p2)/2;
while(true)
...{
int cmp = 0;
if(key>keyPtr[p1])
...{
cmp = 1;
}
else if(key<keyPtr[p1])
...{
cmp = -1;
}
else
...{
cmp = 0;
}
if(cmp>0)
...{
if(p2-p1>1)
...{
p0 = p1;
p1 = (p0+p2)/2;
}
else
...{
if(key>keyPtr[p2])
...{
pos = p2+1;
return 0;
}
else if(key<keyPtr[p2])
...{
pos = p1+1;
return 0;
}
else
...{
pos = p2;
return 1;
}
}
}
else if(cmp<0)
...{
if(p1-p0>1)
...{
p2 = p1;
p1 = (p0+p2)/2;
}
else
...{
if(key<keyPtr[p0])
...{
pos = p0;
return 0;
}
else if(key>keyPtr[p0])
...{
pos = p0+1;
return 0;
}
else
...{
pos = p0;
return 1;
}
}
}
else
...{
pos = p1;
return 1;
}
}
}
char * shm_addr;
int max_size;
int * minfreePtr;
int * sizePtr;
int * keyPtr;
int * flagPtr;
int * indexPtr;
T* elementPtr; //数据中不含NULL指针
} ;
/**/ /*
* 没有测试过,可能含有错误,因为map操作,最好在应用层考虑加解锁,所以,不建议使用
template<class T>
class MKeyIntShmSafeMap
{
public:
MKeyIntShmSafeMap(int t_shmkey,int t_semkey,int t_max_size)
{
int sid;
sid=semget(t_semkey,1,IPC_CREAT|0666);
if(sid<=0)
{
fprintf(stderr," sem new exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
semun arg;
arg.val = 1;
if (semctl(sid, 0, SETVAL, arg)==-1)
{
fprintf(stderr," sem ctl exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
semid = sid;
lock();
max_size = t_max_size;
sizePtr = NULL;
keyPtr = NULL;
elementPtr = NULL;
int shmid;
shmid=shmget(t_shmkey,sizeof(int)+(sizeof(int)*3)*t_max_size+t_max_size*sizeof(T),IPC_CREAT|0666);
if(shmid<=0)
{
fprintf(stderr," shm new exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
unlock();
throw MEXP_NEW;
}
int addr = (int)shmat(shmid, 0, 0);
if(addr<=0)
{
fprintf(stderr," shm mat exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
unlock();
throw MEXP_NEW;
}
shm_addr = (char *)addr;
//共享内存第一段int 存个数
sizePtr = (int *)shm_addr;
//第二位存最小空闲块
minfreePtr = (int *)(shm_addr+sizeof(int));
//共享内存第二段,存 key 列表
keyPtr = (int *)(shm_addr+sizeof(int)*2);
//共享内存第三段,存 块占用标记
indexPtr = (int *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size);
//存内存使用标记
flagPtr = (int *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size+sizeof(int)*max_size);
//共享内存第四段,数据区域
elementPtr = (T *)(shm_addr+sizeof(int)*2+sizeof(int)*max_size+sizeof(int)*max_size+sizeof(int)*max_size);
//第一次创建
struct shmid_ds shmid_st;
shmctl(shmid, IPC_STAT, &shmid_st);
if (shmid_st.shm_cpid == getpid())
{
*sizePtr = 0;
*minfreePtr = 0;
for(int i=0;i<max_size;i++)
{
flagPtr[i] = 0;
}
}
unlock();
}
~MKeyIntShmMap()
{
}
int add(int key,const T& obj)
{
lock();
if((*sizePtr)>=max_size)
{
unlock();
return -1;
}
int pos = 0;
int flag = findPos(key,pos);
if(flag)
{
//flagPtr[indexPtr[pos]] = 0;
elementPtr[indexPtr[pos]] = obj;
}
else
{
for(int i=(*sizePtr);i>pos;i--)
{
keyPtr[i] = keyPtr[i-1];
indexPtr[i] = indexPtr[i-1];
}
int tpos = -1;
for(int i=(*minfreePtr);i<max_size;i++)
{
if(flagPtr[i]==0)
{
tpos = i;
break;
}
}
flagPtr[tpos] = 1;
(*minfreePtr) = tpos+1;
keyPtr[pos] = key;
indexPtr[pos] = tpos;
elementPtr[tpos] = obj;
(*sizePtr)++;
}
unlock();
return 0;
}
void del(int key)
{
lock();
int pos = 0;
int flag = findPos(key,pos);
if(flag)
{
flagPtr[indexPtr[pos]] = 0;
if((*minfreePtr)>indexPtr[pos])
{
(*minfreePtr) = indexPtr[pos];
}
for(int i=pos+1;i<(*sizePtr);i++)
{
keyPtr[i-1] = keyPtr[i];
indexPtr[i-1] = indexPtr[i];
}
(*sizePtr)--;
}
unlock();
}
int find(int key,T & obj)
{
lock();
int pos = 0;
int flag = findPos(key,pos);
if(flag)
{
obj = elementPtr[indexPtr[pos]];
unlock();
return 0;
}
else
{
unlock();
return -1;
}
}
int getSize()
{
return (*sizePtr);
}
int getKey(int pos)
{
return keyPtr[pos];
}
int get(int pos,T &obj)
{
obj = elementPtr[indexPtr[pos]];
}
void clear()
{
lock();
*sizePtr = 0;
for(int i=0;i<max_size;i++)
{
flagPtr[i] = 0;
}
(*minfreePtr) = 0;
unlock();
}
protected:
private:
//找到key所在的位置
//找到key,返回1,pos指向所在位置
//找不到key,返回0,pos指向所应该插入位置
int findPos(int key,int &pos)
{
if((*sizePtr)==0)
{
pos = 0;
return 0;
}
int p0 = 0;
int p2 = (*sizePtr)-1;
int p1 = (p0+p2)/2;
while(true)
{
int cmp = 0;
if(key>keyPtr[p1])
{
cmp = 1;
}
else if(key<keyPtr[p1])
{
cmp = -1;
}
else
{
cmp = 0;
}
if(cmp>0)
{
if(p2-p1>1)
{
p0 = p1;
p1 = (p0+p2)/2;
}
else
{
if(key>keyPtr[p2])
{
pos = p2+1;
return 0;
}
else if(key<keyPtr[p2])
{
pos = p1+1;
return 0;
}
else
{
pos = p2;
return 1;
}
}
}
else if(cmp<0)
{
if(p1-p0>1)
{
p2 = p1;
p1 = (p0+p2)/2;
}
else
{
if(key<keyPtr[p0])
{
pos = p0;
return 0;
}
else if(key>keyPtr[p0])
{
pos = p0+1;
return 0;
}
else
{
pos = p0;
return 1;
}
}
}
else
{
pos = p1;
return 1;
}
}
}
void lock()
{
//加锁
struct sembuf op[1] = {{0, -1, 0}};
if (semop (sid, &op[0], 1) == -1)
{
fprintf(stderr," sem lock exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
}
void unlock()
{
//解锁
struct sembuf op[1] = {{0, 1, 0}};
if (semop (sid, &op[0], 1) == -1)
{
fprintf(stderr," sem unlock exception: file=[%s] line=[%d] code=[%d] ",__FILE__,__LINE__,MEXP_NEW);
throw MEXP_NEW;
}
}
int semid;
char * shm_addr;
int max_size;
int * minfreePtr;
int * sizePtr;
int * keyPtr;
int * flagPtr;
int * indexPtr;
T* elementPtr; //数据中不含NULL指针
};
*/
#endif /*MKEYINTSHMMAP_HPP_*/
使用实例
#include
"
MTest.h
"
typedef MKeyIntShmMap < int > MyMKeyIntShmMap;
typedef struct
... {
int id;
char name[123];
} MyStruct;
typedef MKeyIntShmMap < MyStruct > StructMKeyIntShmMap;
int main( int agrc, char * argv[])
... {
MyMKeyIntShmMap myMap(99123,100);
if(agrc==2)
...{
myMap.del(atoi(argv[1]));
}
if(agrc==4)
...{
myMap.clear();
}
if(agrc==3)
...{
myMap[atoi(argv[1])] = atoi(argv[2]);
}
printf("map size = %d ",myMap.getSize());
myMap[1] = 123;
printf("map size = %d ",myMap.getSize());
myMap[128] = 212;
printf("map size = %d ",myMap.getSize());
myMap[123] = 22;
printf("map size = %d ",myMap.getSize());
printf("key=value ");
for(int i=0;i<myMap.getSize();i++)
...{
printf(" %d=%d ",myMap.getKey(i),*myMap.get(i));
}
StructMKeyIntShmMap test(99124,5);
for(int i=0;i<8;i++)
...{
MyStruct cc;
cc.id = 123+i;
snprintf(cc.name,sizeof(cc.name)-1,"hello%d",i);
test.add(i*2,cc);
}
for(int i=0;i<test.getSize();i++)
...{
printf(" %d=%d %s ",test.getKey(i),test.get(i)->id,test.get(i)->name);
}
}
typedef MKeyIntShmMap < int > MyMKeyIntShmMap;
typedef struct
... {
int id;
char name[123];
} MyStruct;
typedef MKeyIntShmMap < MyStruct > StructMKeyIntShmMap;
int main( int agrc, char * argv[])
... {
MyMKeyIntShmMap myMap(99123,100);
if(agrc==2)
...{
myMap.del(atoi(argv[1]));
}
if(agrc==4)
...{
myMap.clear();
}
if(agrc==3)
...{
myMap[atoi(argv[1])] = atoi(argv[2]);
}
printf("map size = %d ",myMap.getSize());
myMap[1] = 123;
printf("map size = %d ",myMap.getSize());
myMap[128] = 212;
printf("map size = %d ",myMap.getSize());
myMap[123] = 22;
printf("map size = %d ",myMap.getSize());
printf("key=value ");
for(int i=0;i<myMap.getSize();i++)
...{
printf(" %d=%d ",myMap.getKey(i),*myMap.get(i));
}
StructMKeyIntShmMap test(99124,5);
for(int i=0;i<8;i++)
...{
MyStruct cc;
cc.id = 123+i;
snprintf(cc.name,sizeof(cc.name)-1,"hello%d",i);
test.add(i*2,cc);
}
for(int i=0;i<test.getSize();i++)
...{
printf(" %d=%d %s ",test.getKey(i),test.get(i)->id,test.get(i)->name);
}
}