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_String.h"
22 #include "UT_StringHolder.h"
23 #include "UT_WorkBuffer.h"
24 
25 /*****************************************************************************/
26 // Faster version and simplier of the previous name manager.
27 // Based on profiling run the other version had a few problems.
28 // Doing lookups was slow because of some operator new calls during the lookups.
29 // Doing a lookup always had to split the string to get the base string.
30 // The multi map behavior was really only required for generating a unique name in a fast way.
31 // Now the hash() function isn't be called everytime because UT_StringHolder keeps a hash.
32 // It means if the string is kept in memory and doesn't change, only the cached hash will be used.
33 template < class DATA_TYPE >
35 {
36 public:
37 
38  /// suffix_start_number determines the starting numerical suffix when unique names are generated.
39  /// For example:
40  /// If set to 0, generating unique names for "base" will result in "base0", "base1", "base2", etc.
41  /// If set to 1, generating unique names for "base" will result in "base", "base1", "base2", etc.
42  /// If set to 2, generating unique names for "base" will result in "base", "base2", "base3", etc.
43  /// And so on.
44  UT_NameManager(int suffix_start_number = 2)
45  {
46  mySuffixStartNumber = suffix_start_number;
47  myNumEntries = 0;
48  }
50 
51  /// Returns the amount of memory owned by this UT_NameManger
52  int64 getMemoryUsage(bool inclusive) const
53  {
54  int64 mem = inclusive ? sizeof(*this) : 0;
55 
56  mem += myMap.getMemoryUsage(false);
57 
58  return mem;
59  }
60 
61  /// Returns the total number of unique names in the manager.
62  unsigned entries() const { return (unsigned) myNumEntries; }
63 
64  /// Returns true if empty, false otherwise.
65  bool empty() const { return myNumEntries == 0; }
66 
67  /// Removes a name, such as "base123", from the manager. If the removed name
68  /// was the last one in a category and the category is now empty, deletes
69  /// the category as well.
70  /// Returns true if removal was successfull, false otherwise.
71  bool deleteSymbol(const UT_StringRef &symbol, bool set_to_null )
72  {
73  if(!symbol.isstring())
74  return false;
75 
76  auto it = myMap.find(symbol);
77  if( it==myMap.end() )
78  return false;
79 
80  if( set_to_null )
81  it->second = nullptr;
82  else
83  myMap.erase(it);
84 
85  myNumEntries--;
86  UT_ASSERT(myNumEntries>=0);
87 
88  return true;
89  }
90 
91  /// Clears all the entries from this manager.
92  /// if set_to_null is true the map entries values will be set to null instead
93  /// of erasing all the entries.
94  void clear(bool set_to_null)
95  {
96  if( set_to_null )
97  {
98  for( auto it = myMap.begin(); !it.atEnd(); ++it )
99  it->second = nullptr;
100  }
101  else
102  myMap.clear();
103 
104  myNumEntries = 0;
105  }
106 
107  /// Generates a new name unique relative to the items alraedy in this collection,
108  /// optionally starting with a given name.
109  bool getUniqueName(const UT_StringRef &orig_name_in, UT_WorkBuffer& unique_name_out) const
110  {
111  unsigned i=mySuffixStartNumber;
112  char number[UT_NUMBUF];
113 
114  UT_String temp_name(orig_name_in.isstring() ? orig_name_in : "name", false);
115  UT_String base;
116  temp_name.base(base);
117 
118  unique_name_out.strcpy(base);
119  int base_len = unique_name_out.length();
120 
121  // Get the first available entry, we could add a multimap later on if this is too slow
122  // The old name manager was really slow on the findSymbol which is called more often than this.
123  for(;;)
124  {
125  UT_String::itoa(number, i++);
126  unique_name_out.append(number);
127  UT_StringRef unique_name_ref(unique_name_out.buffer() );
128  if( !findSymbol( unique_name_ref ) )
129  return true;
130 
131  // get back to previous string keeping the same buffer
132  unique_name_out.truncate(base_len);
133  }
134 
135  UT_ASSERT(false);// Shouldn't get here.
136  return false;
137  }
138 
139  /// Adds a new name to this collection. If the name already exists,
140  /// the addition will silently fail, so it is the caller's responsibility
141  /// to assure that the name is unique by calling findSymbol() if
142  /// needed. This is done to avoid extra uniqueness checks that may
143  /// be unnecessary in certain situations.
144  ///
145  /// Returns true if symbol added successfully, false otherwise.
146  bool addSymbol(const UT_StringRef &symbol, DATA_TYPE data)
147  {
148  if(!symbol.isstring())
149  return false;
150 
151  auto it = myMap.find(symbol);
152  if( it!=myMap.end() )
153  {
154  if( it->second == nullptr )
155  {
156  it->second = data;
157  myNumEntries++;
158  return true;
159  }
160  }
161  else
162  {
163  myMap.emplace(symbol, data);
164  myNumEntries++;
165  return true;
166  }
167 
168  return false;
169  }
170 
171  /// Finds the data item associated with a given name. Returns a pointer
172  /// to the item if found, nullptr if the name is not in the collection.
173  DATA_TYPE findSymbol(const UT_StringRef &symbol) const
174  {
175  if(!symbol.isstring())
176  return nullptr;
177 
178  auto it = myMap.find(symbol);
179  if( it==myMap.end() )
180  return nullptr;
181 
182  return it->second;
183 
184  }
185 
186 private:
187 
189  int mySuffixStartNumber;
190  unsigned myNumEntries;
191 
192 };
193 /*****************************************************************************/
194 #endif
void clear()
Definition: UT_ArraySet.h:360
SYS_FORCE_INLINE exint length() const
bool addSymbol(const UT_StringRef &symbol, DATA_TYPE data)
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)
iterator end()
Returns a non-const end iterator for the set.
Definition: UT_ArraySet.h:667
void clear(bool set_to_null)
png_uint_32 i
Definition: png.h:2877
iterator find(const Key &key)
Definition: UT_ArrayMap.h:144
long long int64
Definition: SYS_Types.h:107
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:652
GLboolean * data
Definition: glcorearb.h:130
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:1275
SYS_FORCE_INLINE void truncate(exint new_length)
std::pair< iterator, bool > emplace(Args &&...args)
Definition: UT_ArraySet.h:1019
bool deleteSymbol(const UT_StringRef &symbol, bool set_to_null)
#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:126
const char * base(UT_String &buf) const
SYS_FORCE_INLINE bool isstring() const