/* 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