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