ObjectMap.hpp 3.16 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/* 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

20
#include <ndb_global.h>
21 22 23 24 25 26 27 28 29 30 31
//#include <NdbMutex.h>
#include <NdbOut.hpp>

//#define DEBUG_OBJECTMAP

/**
  * Global ObjectMap
  */
class NdbObjectIdMap //: NdbLockable
{
public:
32
  STATIC_CONST( InvalidId = ~(Uint32)0 );
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
  NdbObjectIdMap(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;

  void expand(Uint32 newSize);
};

inline
NdbObjectIdMap::NdbObjectIdMap(Uint32 sz, Uint32 eSz) {
  m_size = 0;
  m_firstFree = InvalidId;
  m_map = 0;
  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){

joreland@mysql.com's avatar
joreland@mysql.com committed
96
  Uint32 i = id>>2;
97 98

  //  lock();
joreland@mysql.com's avatar
joreland@mysql.com committed
99 100 101 102 103 104 105 106 107 108 109 110
  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();
    
111
#ifdef DEBUG_OBJECTMAP
joreland@mysql.com's avatar
joreland@mysql.com committed
112
    ndbout_c("NdbObjectIdMap::unmap(%u) obj=0x%x", id, obj);
113
#endif
joreland@mysql.com's avatar
joreland@mysql.com committed
114 115 116 117
    
    return obj;
  }
  return 0;
118 119 120 121 122 123 124
}

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
joreland@mysql.com's avatar
joreland@mysql.com committed
125 126 127 128 129
  id >>= 2;
  if(id < m_size){
    return m_map[id].m_obj;
  }
  return 0;
130 131 132 133 134 135 136
}

inline void
NdbObjectIdMap::expand(Uint32 incSize){
  Uint32 newSize = m_size + incSize;
  MapEntry * tmp = (MapEntry*)malloc(newSize * sizeof(MapEntry));

137 138 139 140
  if (m_map) {
    memcpy(tmp, m_map, m_size * sizeof(MapEntry));
    free((void*)m_map);
  }
141 142 143 144 145 146 147 148 149 150 151
  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;
}

#endif