COPASI API  4.16.103
CKeyFactory.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2013 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 // Copyright (C) 2003 - 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 /**
16  * CKeyFactory class.
17  * This class is used to create a unique key whithin COPASI. It also allows
18  * retreival of the CCopasiObject the key is assigned to.
19  *
20  * Created for Copasi by Stefan Hoops 2003
21  * Copyright Stefan Hoops
22  */
23 #include <sstream>
24 #include <stdlib.h>
25 
26 #include "copasi/copasi.h"
27 
29 
30 bool CKeyFactory::isValidKey(const std::string & key,
31  const std::string & prefix)
32 {
33  if (key == "" && prefix == "") return true;
34 
35  size_t digitsStart = key.length() - 1;
36 
37  while (isDigit(key[digitsStart]) && digitsStart) --digitsStart;
38 
39  if (digitsStart < 1 || digitsStart > key.length() - 2 || key[digitsStart] != '_') return false;
40 
41  if (prefix != "")
42  {
43  if (prefix != key.substr(0, digitsStart)) return false;
44  else return true;
45  }
46 
47  size_t prefixEnd = 0;
48 
49  while (isPrefix(key[prefixEnd]) && prefixEnd < digitsStart) ++prefixEnd;
50 
51  return (prefixEnd == digitsStart);
52 }
53 
55  CVector< bool >()
56 {}
57 
59  CVector< bool >(256)
60 {
61  size_t i, imax;
62 
63  for (i = 0, imax = size(); i < imax; i++)
64  (*(CVector< bool > *) this)[i] = false;
65 
66  for (i = 0, imax = str.length(); i < imax; i++)
67  (*(CVector< bool > *) this)[(size_t) str[i]] = true;
68 }
69 
71 
72 const bool & CKeyFactory::CDecisionVector::operator()(const unsigned char & c) const
73 {return (*(CVector< bool > *) this)[(size_t) c];}
74 
76  mBeyond(0),
77  mSize(128),
78  mTable(128),
79  mFree()
80 {memset(mTable.array(), 0, mSize * sizeof(CCopasiObject *));}
81 
83  mBeyond(src.mBeyond),
84  mSize(src.mSize),
85  mTable(src.mTable),
86  mFree(src.mFree)
87 {}
88 
90 
92 {
93  size_t index;
94 
95  if (!mFree.empty())
96  {
97  index = mFree.top();
98  mFree.pop();
99  }
100  else
101  {
102  index = mBeyond;
103 
104  mBeyond++;
105 
106  if (mBeyond > mSize)
107  {
108  mTable.resize(mSize * 2, true);
109  memset(mTable.array() + mSize, 0, mSize * sizeof(CCopasiObject *));
110  mSize *= 2;
111  }
112  }
113 
114  mTable[index] = pObject;
115  return index;
116 }
117 
118 bool CKeyFactory::HashTable::addFix(const size_t & index,
119  CCopasiObject * pObject)
120 {
121  while (index >= mSize)
122  {
123  mTable.resize(mSize * 2, true);
124  memset(mTable.array() + mSize, 0,
125  mSize * sizeof(CCopasiObject *));
126  mSize *= 2;
127  }
128 
129  if (mTable[index]) return false;
130 
131  mTable[index] = pObject;
132  return true;
133 }
134 
136 {
137  if (index < mSize) return mTable[index];
138 
139  return NULL;
140 }
141 
142 bool CKeyFactory::HashTable::remove(const size_t & index)
143 {
144  if (index < mSize)
145  {
146  if (!mTable[index]) return false;
147 
148  mTable[index] = NULL;
149  mFree.push(index);
150 
151  return true;
152  }
153 
154  return false;
155 }
156 
158 
159 CKeyFactory::CDecisionVector CKeyFactory::isPrefix("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
160 
162  mKeyTable()
163 {}
164 
166 
167 std::string CKeyFactory::add(const std::string & prefix,
168  CCopasiObject * pObject)
169 {
170  std::map< std::string, CKeyFactory::HashTable >::iterator it =
171  mKeyTable.find(prefix);
172 
173  if (it == mKeyTable.end())
174  {
175  std::pair<std::map< std::string, CKeyFactory::HashTable >::iterator, bool> ret =
176  mKeyTable.insert(std::map< std::string, CKeyFactory::HashTable >::value_type(prefix, CKeyFactory::HashTable()));
177 
178  it = ret.first;
179  }
180 
181  std::stringstream key;
182  key << prefix + "_" << it->second.add(pObject);
183 
184  return key.str();
185 }
186 
187 bool CKeyFactory::addFix(const std::string & key, CCopasiObject * pObject)
188 {
189  size_t pos = key.length() - 1;
190 
191  while (isDigit(key[pos]) && pos) --pos;
192 
193  std::string Prefix = key.substr(0, pos);
194  size_t index = atoi(key.substr(pos + 1).c_str());
195 
196  std::map< std::string, CKeyFactory::HashTable >::iterator it =
197  mKeyTable.find(Prefix);
198 
199  if (it == mKeyTable.end())
200  {
201  std::pair<std::map< std::string, CKeyFactory::HashTable >::iterator, bool> ret =
202  mKeyTable.insert(std::map< std::string, CKeyFactory::HashTable >::value_type(Prefix, CKeyFactory::HashTable()));
203 
204  it = ret.first;
205  }
206 
207  return it->second.addFix(index, pObject);
208 }
209 
210 bool CKeyFactory::remove(const std::string & key)
211 {
212  size_t pos = key.length();
213 
214  if (pos == 0) return false;
215 
216  --pos;
217 
218  while (isDigit(key[pos]) && pos) --pos;
219 
220  std::string Prefix = key.substr(0, pos);
221 
222  size_t index = 0;
223 
224  if (pos + 1 < key.length())
225  index = atoi(key.substr(pos + 1).c_str());
226 
227  std::map< std::string, CKeyFactory::HashTable >::iterator it =
228  mKeyTable.find(Prefix);
229 
230  if (it == mKeyTable.end()) return false;
231 
232  return it->second.remove(index);
233 }
234 
235 CCopasiObject * CKeyFactory::get(const std::string & key)
236 {
237  if (key.length() == 0) return NULL;
238 
239  size_t pos = key.length() - 1; //TODO !!!pos can be invalid (-1); not anymore, but look for other errors like this
240 
241  while (isDigit(key[pos]) && pos) --pos;
242 
243  std::string Prefix = key.substr(0, pos);
244  size_t index = atoi(key.substr(pos + 1).c_str());
245 
246  std::map< std::string, CKeyFactory::HashTable >::iterator it =
247  mKeyTable.find(Prefix);
248 
249  if (it == mKeyTable.end()) return NULL;
250 
251  return it->second.get(index);
252 }
bool remove(const std::string &key)
CVector< CCopasiObject * > mTable
Definition: CKeyFactory.h:43
std::map< std::string, HashTable > mKeyTable
Definition: CKeyFactory.h:74
static CDecisionVector isDigit
Definition: CKeyFactory.h:79
static CDecisionVector isPrefix
Definition: CKeyFactory.h:84
CCopasiObject * get(const std::string &key)
static bool isValidKey(const std::string &key, const std::string &prefix="")
Definition: CKeyFactory.cpp:30
bool addFix(const std::string &key, CCopasiObject *pObject)
std::string add(const std::string &prefix, CCopasiObject *pObject)
size_t add(CCopasiObject *pObject)
Definition: CKeyFactory.cpp:91
size_t size() const
Definition: CVector.h:100
CCopasiObject * get(const size_t &index)
CType * array()
Definition: CVector.h:139
bool remove(const size_t &index)
bool addFix(const size_t &index, CCopasiObject *pObject)
const bool & operator()(const unsigned char &c) const
Definition: CKeyFactory.cpp:72