Scippy

SoPlex

Sequential object-oriented simPlex

nameset.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2015 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file nameset.h
17  * @brief Set of strings.
18  */
19 #ifndef _NAMESET_H_
20 #define _NAMESET_H_
21 
22 #include <assert.h>
23 
24 #include "spxdefines.h"
25 #include "dataset.h"
26 #include "datahashtable.h"
27 #include "datakey.h"
28 
29 namespace soplex
30 {
31 /**@class NameSet
32  @brief Set of strings.
33  @ingroup Elementary
34 
35  Class NameSet implements a symbol or name table. It allows to store or
36  remove names (i.e., \c char*), but does not provide means for manipulating
37  stored names.
38 
39  Names in a NameSet may be accessed via numbers from 0 through num()-1
40  and via \ref soplex::DataKey "DataKeys". See DataSet for a description of
41  these concepts.
42 
43  At a time a NameSet can hold a maximum of max() entries. This can be
44  reset with method reMax(). If more than max() names are added to a
45  NameSet, it adjusts itself automatically to the required size. This
46  implies, that references to names within a NameSet may become invalid if
47  the NameSet is expanded.
48 
49  All names (i.e., the actual char strings) in a NameSet are stored in one
50  continuous memory block of size memMax(). At one time memSize() bytes of
51  it are used for actually saving names; the remaining memory is free to hold
52  additional names. memRemax() can be used to reset memMax() but not lower
53  than to memSize(). Method memPack() performs a garbage collection to
54  gain free memory resulting from removed names.
55 
56  @warning Since the keys the NameSet uses to reference the strings are
57  generated internally, it is extremly important that the calls
58  to DataSet from within NameSet are synchronous to any calls
59  outside to DataSet, such as in row or column adding.
60 */
61 class NameSet
62 {
63 public:
64 
65  /**@brief Handles of names in a NameSet.
66  * @ingroup Elementary
67  *
68  * Class Name provides the handles (i.e., char*s) of names in a
69  * NameSet.
70  */
71  class Name
72  {
73  private:
74 
75  //------------------------------
76  /**@name Private Data */
77  //@{
78  static const char deflt; ///< default zero string.
79  //@}
80 
81  public:
82 
83  //------------------------------
84  /**@name Public Data */
85  //@{
86  const char *name; ///< pointer to the name string.
87  //@}
88 
89  //------------------------------
90  /**@name Friends */
91  //@{
92  /// equality operator.
93  friend int operator==(const Name& n1, const Name& n2)
94  {
95  return (strcmp (n1.name, n2.name) == 0);
96  }
97  /// output operator.
98  friend std::ostream& operator<<(std::ostream& out, const Name& n)
99  {
100  return out << n.name;
101  }
102  //@}
103 
104  //------------------------------
105  /**@name Debugging */
106  //@{
107  /// consistency check.
108  bool isConsistent () const
109  {
110  return (name != 0);
111  }
112  //@}
113 
114  //------------------------------------
115  /**@name Constructors / destructors */
116  //@{
117  /// default constructor.
118  Name()
119  : name(&deflt)
120  {}
121  /// copy constructor.
122  /** Only the pointer to the name is copied, but not the name itself.
123  */
124  Name (const Name& str)
125  : name(str.name)
126  {}
127  /// implictly constructs a Name out of a C style character string.
128  Name (const char* str)
129  : name(str)
130  {}
131  //@}
132  };
133 
134 private:
135 
136  //------------------------------
137  /**@name Data */
138  //@{
139  DataSet < int > set; ///< name set.
140  char* mem; ///< string memory
141  int memmax; ///< size of string memory
142  int memused; ///< size of used string memory
143  /** Every name in a NameSet is assigned a DataKey by which it can be
144  accessed (see NameSet::operator[]()). See DataKey for a more
145  detailed description of the concept of Keys.
146  */
147  DataHashTable < Name, DataKey > hashtab; ///< hashtable for names
148  //@}
149 
150 public:
151 
152  //------------------------------
153  /**@name Inquiry */
154  //@{
155  /// returns \p num 'th name of NameSet.
156  const char* operator[](int pnum) const
157  {
158  return &mem[set[pnum]];
159  }
160 
161  /// returns name for DataKey \p pkey of NameSet.
162  const char* operator[](const DataKey& pkey) const
163  {
164  return &mem[set[pkey]];
165  }
166 
167  /// returns nr. of names in NameSet.
168  int num() const
169  {
170  return set.num();
171  }
172 
173  /// returns maximum nr. of names that fit into NameSet.
174  int max() const
175  {
176  return set.max();
177  }
178 
179  /// returns maximum DataKey::idx used in NameSet.
180  int size() const
181  {
182  return set.size();
183  }
184 
185  /// returns maximum length of string memory.
186  int memMax() const
187  {
188  return memmax;
189  }
190 
191  /// returns used length of string memory.
192  int memSize() const
193  {
194  return memused;
195  }
196 
197  /// returns DataKey of the \p pnum 'th name in NameSet.
198  DataKey key(int pnum) const
199  {
200  return set.key(pnum);
201  }
202 
203  /// returns DataKey of name \p str in NameSet.
204  DataKey key(const char* str) const
205  {
206  const Name nam(str);
207  const DataKey* result = hashtab.get(nam);
208  return result == 0 ? DataKey() : *hashtab.get(nam);
209  }
210 
211  /// returns number of name with DataKey \p pkey in NameSet.
212  int number(const DataKey& pkey) const
213  {
214  return set.number(pkey);
215  }
216 
217  /// returns number of name \p str in NameSet.
218  int number(const char *str) const
219  {
220  const Name nam(str);
221  if (hashtab.has(nam))
222  {
223  assert(hashtab.get(nam) != 0);
224  return number(*hashtab.get(nam));
225  }
226  else
227  return -1;
228  }
229 
230  /// does NameSet has a name with number \p pnum?
231  bool has(int pnum) const
232  {
233  return set.has(pnum);
234  }
235 
236  /// does NameSet has a name \p str?
237  bool has(const char* str) const
238  {
239  const Name nam(str);
240  return hashtab.has(nam);
241  }
242 
243  /// does NameSet has a name with DataKey \p pkey?
244  bool has(const DataKey& pkey) const
245  {
246  return set.has(pkey);
247  }
248  //@}
249 
250  //----------------------------
251  /**@name Extension */
252  //@{
253  ///
254  void add(const char* str);
255  /// adds name \p str to NameSet.
256  void add(DataKey& key, const char* str);
257 
258  ///
259  void add(const NameSet& set);
260  /// adds all names in \p set to NameSet.
261  void add(DataKey key[], const NameSet& nset);
262  //@}
263 
264 
265  //----------------------------
266  /**@name Shrinking */
267  //@{
268  /// removes name with DataKey \p key from NameSet.
269  void remove(const DataKey& key);
270 
271  /// removes \p pnum 'th name from NameSet.
272  void remove(int pnum)
273  {
274  remove(key(pnum));
275  }
276 
277  /// removes name \p str from NameSet.
278  void remove(const char* str);
279 
280  /// removes \p n names with DataKeys \p keys from NameSet.
281  void remove(const DataKey keys[], int n);
282 
283  /// removes \p n names with numbers \p nums from NameSet.
284  void remove(const int nums[], int n);
285 
286  /// remove all entries where \p dstat is less than zero.
287  void remove(int dstat[]);
288 
289  /// removes all names from NameSet.
290  void clear();
291  //@}
292 
293 
294  //----------------------------
295  /**@name Memory Control */
296  //@{
297  /// resets max() to \p newmax.
298  void reMax(int newmax = 0);
299 
300  /// resets memMax() to \p newmax.
301  void memRemax(int newmax = 0);
302 
303  /// garbage collection.
304  void memPack();
305  //@}
306 
307 
308  //----------------------------
309  /**@name Control Parameters */
310  //@{
311  /// memory extension factor for entries.
312  /** When more than max() names are added to a NameSet, it is
313  automatically resized to fit the additional names. Parameter
314  \p factor is the factor by which the element memory is extended to do
315  so.
316  */
318 
319  /// memory extension factor for names.
320  /** When the names added to a NameSet do no longer fit into the name
321  memory (i.e. the memory for saving the strings), it is automatically
322  resized to fit the additional names. Parameter \p memFactor is the
323  factor by which this memory is extended to do so.
324  */
326  //@}
327 
328  //----------------------------
329  /**@name Miscellaneous */
330  //@{
331  /// consistency check.
332  bool isConsistent() const;
333  //@}
334 
335  //--------------------------------------
336  /**@name Constructors / Destructors */
337  //@{
338  /// default constructor.
339  /** @param max start value for max()
340  * @param mmax start value for memMax()
341  * @param fac start value for #factor
342  * @param memFac start value for #memFactor
343  */
344  explicit
345  NameSet(int max = 10000,
346  int mmax = -1,
347  Real fac = 2,
348  Real memFac = 2);
349 
350  /// destructor.
351  ~NameSet();
352  //@}
353 
354 private:
355 
356  //--------------------------------------
357  /**@name Blocked */
358  //@{
359  /// copy constructor.
360  NameSet(const NameSet& old);
361 
362  /// assignment operator.
363  NameSet& operator=(const NameSet& rhs);
364  //@}
365 };
366 
367 extern std::ostream& operator<<(std::ostream& s, const NameSet& nset);
368 
369 } // namespace soplex
370 #endif // _NAMESET_H_