mariadb/ndb/src/ndbapi/ObjectMap.hpp
jonas@perch.ndb.mysql.com e358a81710 bug#9282 - ndb
big delete from causing NdbObjectIdMap::expand at same time 
  as receiver thread perform getObjectId
2005-09-19 14:05:54 +02:00

158 lines
3.3 KiB
C++

/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef NDB_OBJECT_ID_MAP_HPP
#define NDB_OBJECT_ID_MAP_HPP
#include <ndb_global.h>
//#include <NdbMutex.h>
#include <NdbOut.hpp>
//#define DEBUG_OBJECTMAP
/**
* Global ObjectMap
*/
class NdbObjectIdMap //: NdbLockable
{
public:
STATIC_CONST( InvalidId = ~(Uint32)0 );
NdbObjectIdMap(NdbMutex*, Uint32 initalSize = 128, Uint32 expandSize = 10);
~NdbObjectIdMap();
Uint32 map(void * object);
void * unmap(Uint32 id, void *object);
void * getObject(Uint32 id);
private:
Uint32 m_size;
Uint32 m_expandSize;
Uint32 m_firstFree;
union MapEntry {
Uint32 m_next;
void * m_obj;
} * m_map;
NdbMutex * m_mutex;
void expand(Uint32 newSize);
};
inline
NdbObjectIdMap::NdbObjectIdMap(NdbMutex* mutex, Uint32 sz, Uint32 eSz) {
m_size = 0;
m_firstFree = InvalidId;
m_map = 0;
m_mutex = mutex;
m_expandSize = eSz;
expand(sz);
#ifdef DEBUG_OBJECTMAP
ndbout_c("NdbObjectIdMap:::NdbObjectIdMap(%u)", sz);
#endif
}
inline
NdbObjectIdMap::~NdbObjectIdMap(){
free(m_map);
}
inline
Uint32
NdbObjectIdMap::map(void * object){
// lock();
if(m_firstFree == InvalidId){
expand(m_expandSize);
}
Uint32 ff = m_firstFree;
m_firstFree = m_map[ff].m_next;
m_map[ff].m_obj = object;
// unlock();
#ifdef DEBUG_OBJECTMAP
ndbout_c("NdbObjectIdMap::map(0x%x) %u", object, ff<<2);
#endif
return ff<<2;
}
inline
void *
NdbObjectIdMap::unmap(Uint32 id, void *object){
Uint32 i = id>>2;
// lock();
if(i < m_size){
void * obj = m_map[i].m_obj;
if (object == obj) {
m_map[i].m_next = m_firstFree;
m_firstFree = i;
} else {
ndbout_c("Error: NdbObjectIdMap::::unmap(%u, 0x%x) obj=0x%x", id, object, obj);
return 0;
}
// unlock();
#ifdef DEBUG_OBJECTMAP
ndbout_c("NdbObjectIdMap::unmap(%u) obj=0x%x", id, obj);
#endif
return obj;
}
return 0;
}
inline void *
NdbObjectIdMap::getObject(Uint32 id){
#ifdef DEBUG_OBJECTMAP
ndbout_c("NdbObjectIdMap::getObject(%u) obj=0x%x", id, m_map[id>>2].m_obj);
#endif
id >>= 2;
if(id < m_size){
return m_map[id].m_obj;
}
return 0;
}
inline void
NdbObjectIdMap::expand(Uint32 incSize){
NdbMutex_Lock(m_mutex);
Uint32 newSize = m_size + incSize;
MapEntry * tmp = (MapEntry*)realloc(m_map, newSize * sizeof(MapEntry));
if (likely(tmp != 0))
{
m_map = tmp;
for(Uint32 i = m_size; i<newSize; i++){
m_map[i].m_next = i + 1;
}
m_firstFree = m_size;
m_map[newSize-1].m_next = InvalidId;
m_size = newSize;
}
else
{
ndbout_c("NdbObjectIdMap::expand unable to expand!!");
}
NdbMutex_Unlock(m_mutex);
}
#endif