1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2022 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 "soplex/spxdefines.h"
25 #include "soplex/dataset.h"
26 #include "soplex/datahashtable.h"
27 #include "soplex/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 Name& operator=(const Name& old)
133 {
(1) Event self_assign: |
No protection against the object assigning to itself. |
134 name = old.name;
135 return *this;
136 }
137 ///@}
138 };
139
140 private:
141
142 //------------------------------
143 /**@name Data */
144 ///@{
145 DataSet < int > set; ///< name set.
146 char* mem; ///< string memory
147 int memmax; ///< size of string memory
148 int memused; ///< size of used string memory
149 /** Every name in a NameSet is assigned a DataKey by which it can be
150 accessed (see NameSet::operator[]()). See DataKey for a more
151 detailed description of the concept of Keys.
152 */
153 DataHashTable < Name, DataKey > hashtab; ///< hashtable for names
154 ///@}
155
156 public:
157
158 //------------------------------
159 /**@name Inquiry */
160 ///@{
161 /// returns \p num 'th name of NameSet.
162 const char* operator[](int pnum) const
163 {
164 return &mem[set[pnum]];
165 }
166
167 /// returns name for DataKey \p pkey of NameSet.
168 const char* operator[](const DataKey& pkey) const
169 {
170 return &mem[set[pkey]];
171 }
172
173 /// returns nr. of names in NameSet.
174 int num() const
175 {
176 return set.num();
177 }
178
179 /// returns maximum nr. of names that fit into NameSet.
180 int max() const
181 {
182 return set.max();
183 }
184
185 /// returns maximum DataKey::idx used in NameSet.
186 int size() const
187 {
188 return set.size();
189 }
190
191 /// returns maximum length of string memory.
192 int memMax() const
193 {
194 return memmax;
195 }
196
197 /// returns used length of string memory.
198 int memSize() const
199 {
200 return memused;
201 }
202
203 /// returns DataKey of the \p pnum 'th name in NameSet.
204 DataKey key(int pnum) const
205 {
206 return set.key(pnum);
207 }
208
209 /// returns DataKey of name \p str in NameSet.
210 DataKey key(const char* str) const
211 {
212 const Name nam(str);
213 const DataKey* result = hashtab.get(nam);
214 return result == 0 ? DataKey() : *hashtab.get(nam);
215 }
216
217 /// returns number of name with DataKey \p pkey in NameSet.
218 int number(const DataKey& pkey) const
219 {
220 return set.number(pkey);
221 }
222
223 /// returns number of name \p str in NameSet.
224 int number(const char* str) const
225 {
226 const Name nam(str);
227
228 if(hashtab.has(nam))
229 {
230 assert(hashtab.get(nam) != 0);
231 return number(*hashtab.get(nam));
232 }
233 else
234 return -1;
235 }
236
237 /// does NameSet has a name with number \p pnum?
238 bool has(int pnum) const
239 {
240 return set.has(pnum);
241 }
242
243 /// does NameSet has a name \p str?
244 bool has(const char* str) const
245 {
246 const Name nam(str);
247 return hashtab.has(nam);
248 }
249
250 /// does NameSet has a name with DataKey \p pkey?
251 bool has(const DataKey& pkey) const
252 {
253 return set.has(pkey);
254 }
255 ///@}
256
257 //----------------------------
258 /**@name Extension */
259 ///@{
260 ///
261 void add(const char* str);
262 /// adds name \p str to NameSet.
263 void add(DataKey& key, const char* str);
264
265 ///
266 void add(const NameSet& set);
267 /// adds all names in \p set to NameSet.
268 void add(DataKey key[], const NameSet& nset);
269 ///@}
270
271
272 //----------------------------
273 /**@name Shrinking */
274 ///@{
275 /// removes name with DataKey \p key from NameSet.
276 void remove(const DataKey& key);
277
278 /// removes \p pnum 'th name from NameSet.
279 void remove(int pnum)
280 {
281 remove(key(pnum));
282 }
283
284 /// removes name \p str from NameSet.
285 void remove(const char* str);
286
287 /// removes \p n names with DataKeys \p keys from NameSet.
288 void remove(const DataKey keys[], int n);
289
290 /// removes \p n names with numbers \p nums from NameSet.
291 void remove(const int nums[], int n);
292
293 /// remove all entries where \p dstat is less than zero.
294 void remove(int dstat[]);
295
296 /// removes all names from NameSet.
297 void clear();
298 ///@}
299
300
301 //----------------------------
302 /**@name Memory Control */
303 ///@{
304 /// resets max() to \p newmax.
305 void reMax(int newmax = 0);
306
307 /// resets memMax() to \p newmax.
308 void memRemax(int newmax = 0);
309
310 /// garbage collection.
311 void memPack();
312 ///@}
313
314
315 //----------------------------
316 /**@name Control Parameters */
317 ///@{
318 /// memory extension factor for entries.
319 /** When more than max() names are added to a NameSet, it is
320 automatically resized to fit the additional names. Parameter
321 \p factor is the factor by which the element memory is extended to do
322 so.
323 */
324 Real factor;
325
326 /// memory extension factor for names.
327 /** When the names added to a NameSet do no longer fit into the name
328 memory (i.e. the memory for saving the strings), it is automatically
329 resized to fit the additional names. Parameter \p memFactor is the
330 factor by which this memory is extended to do so.
331 */
332 Real memFactor;
333 ///@}
334
335 //----------------------------
336 /**@name Miscellaneous */
337 ///@{
338 /// consistency check.
339 bool isConsistent() const;
340 ///@}
341
342 //--------------------------------------
343 /**@name Constructors / Destructors */
344 ///@{
345 /// default constructor.
346 /** @param max start value for max()
347 * @param mmax start value for memMax()
348 * @param fac start value for #factor
349 * @param memFac start value for #memFactor
350 */
351 explicit
352 NameSet(int max = 10000,
353 int mmax = -1,
354 Real fac = 2,
355 Real memFac = 2);
356
357 /// destructor.
358 ~NameSet();
359 ///@}
360
361 private:
362
363 //--------------------------------------
364 /**@name Blocked */
365 ///@{
366 /// copy constructor.
367 NameSet(const NameSet& old);
368
369 /// assignment operator.
370 NameSet& operator=(const NameSet& rhs);
371 ///@}
372 };
373
374 extern std::ostream& operator<<(std::ostream& s, const NameSet& nset);
375
376 } // namespace soplex
377 #endif // _NAMESET_H_
378