MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ObjectMap.hpp
1 /*
2  Copyright (C) 2003-2008 MySQL AB, 2008 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #ifndef NDB_OBJECT_ID_MAP_HPP
20 #define NDB_OBJECT_ID_MAP_HPP
21 
22 #include <ndb_global.h>
23 #include <NdbOut.hpp>
24 
25 #include <EventLogger.hpp>
26 extern EventLogger * g_eventLogger;
27 
28 //#define DEBUG_OBJECTMAP
29 
34 {
35 public:
36  STATIC_CONST( InvalidId = 0x7fffffff );
37  NdbObjectIdMap(Uint32 initalSize, Uint32 expandSize);
38  ~NdbObjectIdMap();
39 
40  Uint32 map(void * object);
41  void * unmap(Uint32 id, void *object);
42 
43  void * getObject(Uint32 id);
44 private:
45  const Uint32 m_expandSize;
46  Uint32 m_size;
47  Uint32 m_firstFree;
54  Uint32 m_lastFree;
55 
56  class MapEntry
57  {
58  public:
59  bool isFree() const
60  {
61  return (m_val & 1) == 1;
62  }
63 
64  Uint32 getNext() const
65  {
66  assert(isFree());
67  return static_cast<Uint32>(m_val >> 1);
68  }
69 
70  void setNext(Uint32 next)
71  {
72  m_val = (next << 1) | 1;
73  }
74 
75  void* getObj() const
76  {
77  assert((m_val & 3) == 0);
78  return reinterpret_cast<void*>(m_val);
79  }
80 
81  void setObj(void* obj)
82  {
83  m_val = reinterpret_cast<UintPtr>(obj);
84  assert((m_val & 3) == 0);
85  }
86 
87  private:
94  UintPtr m_val;
95  };
96 
97  MapEntry* m_map;
98 
99  int expand(Uint32 newSize);
100  // For debugging purposes.
101  bool checkConsistency();
102 };
103 
104 inline
105 Uint32
106 NdbObjectIdMap::map(void * object)
107 {
108  if(m_firstFree == InvalidId && expand(m_expandSize))
109  return InvalidId;
110 
111  const Uint32 ff = m_firstFree;
112  m_firstFree = m_map[ff].getNext();
113  m_map[ff].setObj(object);
114 
115  DBUG_PRINT("info",("NdbObjectIdMap::map(0x%lx) %u", (long) object, ff<<2));
116 
117  return ff<<2;
118 }
119 
120 inline
121 void *
122 NdbObjectIdMap::unmap(Uint32 id, void *object)
123 {
124  const Uint32 i = id>>2;
125 
126  assert(i < m_size);
127  if(i < m_size)
128  {
129  void * const obj = m_map[i].getObj();
130  if (object == obj)
131  {
132  m_map[i].setNext(InvalidId);
133  if (m_firstFree == InvalidId)
134  {
135  m_firstFree = i;
136  }
137  else
138  {
139  m_map[m_lastFree].setNext(i);
140  }
141  m_lastFree = i;
142  }
143  else
144  {
145  g_eventLogger->error("NdbObjectIdMap::unmap(%u, 0x%lx) obj=0x%lx",
146  id, (long) object, (long) obj);
147  DBUG_PRINT("error",("NdbObjectIdMap::unmap(%u, 0x%lx) obj=0x%lx",
148  id, (long) object, (long) obj));
149  assert(false);
150  return 0;
151  }
152 
153  DBUG_PRINT("info",("NdbObjectIdMap::unmap(%u) obj=0x%lx", id, (long) obj));
154 
155  return obj;
156  }
157  return 0;
158 }
159 
160 inline void *
161 NdbObjectIdMap::getObject(Uint32 id)
162 {
163  // DBUG_PRINT("info",("NdbObjectIdMap::getObject(%u) obj=0x%x", id, m_map[id>>2].m_obj));
164  id >>= 2;
165  assert(id < m_size);
166  if(id < m_size)
167  {
168  if(m_map[id].isFree())
169  {
170  return 0;
171  }
172  else
173  {
174  return m_map[id].getObj();
175  }
176  }
177  return 0;
178 }
179 #endif