HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_NameManager.h
Go to the documentation of this file.
1 /*
2 * PROPRIETARY INFORMATION. This software is proprietary to
3 * Side Effects Software Inc., and is not to be reproduced,
4 * transmitted, or disclosed in any way without written permission.
5 *
6 * NAME: UT_NameManager.h
7 *
8 * COMMENTS:
9 *
10 * This class implements a templated name manager, which aims to
11 * provide fast unique name management functions. Note that it
12 * is templated, and thus can be used with any data type.
13 *
14 */
15 
16 #ifndef __UT_NameManager_h__
17 #define __UT_NameManager_h__
18 
19 #include "UT_API.h"
20 #include "UT_ArrayStringMap.h"
21 #include "UT_Defines.h"
22 #include "UT_Function.h"
23 #include "UT_String.h"
24 #include "UT_StringHolder.h"
25 #include "UT_WorkBuffer.h"
26 
27 /*****************************************************************************/
28 /// Returns a unique name based on the requested one, by appending
29 /// numerical suffix if there is a name collision.
30 /// The is_unique parameter function takes a suggestd name as a parameter and
31 /// returns true if it is unique; or false otherwise.
33  UT_Function<bool(const UT_StringRef&)> is_unique);
34 
35 
36 /*****************************************************************************/
37 // Faster version and simplier of the previous name manager.
38 // Based on profiling run the other version had a few problems.
39 // Doing lookups was slow because of some operator new calls during the lookups.
40 // Doing a lookup always had to split the string to get the base string.
41 // The multi map behavior was really only required for generating a unique name in a fast way.
42 // Now the hash() function isn't be called everytime because UT_StringHolder keeps a hash.
43 // It means if the string is kept in memory and doesn't change, only the cached hash will be used.
44 template < class DATA_TYPE >
46 {
47 public:
48 
49  /// suffix_start_number determines the starting numerical suffix when unique names are generated.
50  /// For example:
51  /// If set to 0, generating unique names for "base" will result in "base0", "base1", "base2", etc.
52  /// If set to 1, generating unique names for "base" will result in "base", "base1", "base2", etc.
53  /// If set to 2, generating unique names for "base" will result in "base", "base2", "base3", etc.
54  /// And so on.
55  UT_NameManager(int suffix_start_number = 2)
56  {
57  mySuffixStartNumber = suffix_start_number;
58  myNumEntries = 0;
59  }
61 
62  /// Returns the amount of memory owned by this UT_NameManger
63  int64 getMemoryUsage(bool inclusive) const
64  {
65  int64 mem = inclusive ? sizeof(*this) : 0;
66 
67  mem += myMap.getMemoryUsage(false);
68 
69  return mem;
70  }
71 
72  /// Returns the total number of unique names in the manager.
73  unsigned entries() const { return (unsigned) myNumEntries; }
74 
75  /// Returns true if empty, false otherwise.
76  bool empty() const { return myNumEntries == 0; }
77 
78  /// Removes a name, such as "base123", from the manager. If the removed name
79  /// was the last one in a category and the category is now empty, deletes
80  /// the category as well.
81  /// Returns true if removal was successfull, false otherwise.
82  bool deleteSymbol(const UT_StringRef &symbol, bool set_to_null )
83  {
84  if(!symbol.isstring())
85  return false;
86 
87  auto it = myMap.find(symbol);
88  if( it==myMap.end() )
89  return false;
90 
91  if( set_to_null )
92  it->second = nullptr;
93  else
94  myMap.erase(it);
95 
96  UT_ASSERT(myNumEntries>0);
97  myNumEntries--;
98 
99  return true;
100  }
101 
102  /// Clears all the entries from this manager.
103  /// if set_to_null is true the map entries values will be set to null instead
104  /// of erasing all the entries.
105  void clear(bool set_to_null)
106  {
107  if( set_to_null )
108  {
109  for( auto it = myMap.begin(); !it.atEnd(); ++it )
110  it->second = nullptr;
111  }
112  else
113  myMap.clear();
114 
115  myNumEntries = 0;
116  }
117 
118  /// Generates a new name unique relative to the items alraedy in this collection,
119  /// optionally starting with a given name.
120  bool getUniqueName(const UT_StringRef &orig_name_in, UT_WorkBuffer& unique_name_out) const
121  {
122  unsigned i=mySuffixStartNumber;
123  char number[UT_NUMBUF];
124 
125  UT_String temp_name(
126  orig_name_in.isstring()
127  ? static_cast<const char *>(orig_name_in) : "name",
128  false);
129  UT_String base;
130  temp_name.base(base);
131 
132  unique_name_out.strcpy(base);
133  int base_len = unique_name_out.length();
134 
135  // Get the first available entry, we could add a multimap later on if this is too slow
136  // The old name manager was really slow on the findSymbol which is called more often than this.
137  for(;;)
138  {
139  UT_String::itoa(number, i++);
140  unique_name_out.append(number);
141  UT_StringRef unique_name_ref(unique_name_out.buffer() );
142  if( !findSymbol( unique_name_ref ) )
143  return true;
144 
145  // get back to previous string keeping the same buffer
146  unique_name_out.truncate(base_len);
147  }
148 
149  UT_ASSERT(false);// Shouldn't get here.
150  return false;
151  }
152 
153  /// Adds a new name to this collection. If the name already exists,
154  /// the addition will silently fail, so it is the caller's responsibility
155  /// to assure that the name is unique by calling findSymbol() if
156  /// needed. This is done to avoid extra uniqueness checks that may
157  /// be unnecessary in certain situations.
158  ///
159  /// Returns true if symbol added successfully, false otherwise.
160  bool addSymbol(const UT_StringRef &symbol, DATA_TYPE data)
161  {
162  if(!symbol.isstring())
163  return false;
164 
165  auto it = myMap.find(symbol);
166  if( it!=myMap.end() )
167  {
168  if( it->second == nullptr )
169  {
170  it->second = data;
171  myNumEntries++;
172  return true;
173  }
174  }
175  else
176  {
177  myMap.emplace(symbol, data);
178  myNumEntries++;
179  return true;
180  }
181 
182  return false;
183  }
184 
185  /// Finds the data item associated with a given name. Returns a pointer
186  /// to the item if found, nullptr if the name is not in the collection.
187  DATA_TYPE findSymbol(const UT_StringRef &symbol) const
188  {
189  if(!symbol.isstring())
190  return nullptr;
191 
192  auto it = myMap.find(symbol);
193  if( it==myMap.end() )
194  return nullptr;
195 
196  return it->second;
197 
198  }
199 
200 private:
201 
203  int mySuffixStartNumber;
204  unsigned myNumEntries;
205 
206 };
207 /*****************************************************************************/
208 #endif
void clear()
Definition: UT_ArraySet.h:369
SYS_FORCE_INLINE exint length() const
bool addSymbol(const UT_StringRef &symbol, DATA_TYPE data)
GLboolean * data
Definition: glcorearb.h:131
UT_NameManager(int suffix_start_number=2)
bool empty() const
Returns true if empty, false otherwise.
SYS_FORCE_INLINE const char * buffer() const
SYS_FORCE_INLINE void strcpy(const char *src)
#define UT_API
Definition: UT_API.h:14
iterator end()
Returns a non-const end iterator for the set.
Definition: UT_ArraySet.h:676
void clear(bool set_to_null)
iterator find(const Key &key)
Definition: UT_ArrayMap.h:158
unsigned entries() const
Returns the total number of unique names in the manager.
int64 getMemoryUsage(bool inclusive) const
Returns the amount of memory owned by this UT_NameManger.
DATA_TYPE findSymbol(const UT_StringRef &symbol) const
iterator begin()
Returns a non-const iterator for the beginning of the set.
Definition: UT_ArraySet.h:661
long long int64
Definition: SYS_Types.h:116
GLuint const GLchar * name
Definition: glcorearb.h:786
std::function< T > UT_Function
Definition: UT_Function.h:37
bool getUniqueName(const UT_StringRef &orig_name_in, UT_WorkBuffer &unique_name_out) const
static int itoa(char *str, int64 i)
int64 getMemoryUsage(bool inclusive) const
Definition: UT_ArraySet.h:1300
SYS_FORCE_INLINE void truncate(exint new_length)
std::pair< iterator, bool > emplace(Args &&...args)
Definition: UT_ArraySet.h:1035
bool deleteSymbol(const UT_StringRef &symbol, bool set_to_null)
UT_API UT_StringHolder UTuniqueName(const UT_StringRef &name, UT_Function< bool(const UT_StringRef &)> is_unique)
#define UT_NUMBUF
Definition: UT_Defines.h:24
SYS_FORCE_INLINE void append(char character)
iterator erase(iterator pos)
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
const char * base(UT_String &buf) const
SYS_FORCE_INLINE bool isstring() const
Definition: format.h:895