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