CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
shortstring.h
Go to the documentation of this file.
1 
9 #ifndef CVMFS_SHORTSTRING_H_
10 #define CVMFS_SHORTSTRING_H_
11 
12 #include <algorithm>
13 #include <cstring>
14 #include <string>
15 
16 #include "util/atomic.h"
17 
18 #ifdef CVMFS_NAMESPACE_GUARD
19 namespace CVMFS_NAMESPACE_GUARD {
20 #endif
21 
22 const unsigned char kDefaultMaxName = 25;
23 const unsigned char kDefaultMaxLink = 25;
24 const unsigned char kDefaultMaxPath = 200;
25 
26 template<unsigned char StackSize, char Type>
27 class ShortString {
28  public:
29  ShortString() : long_string_(NULL), length_(0) {
30 #ifdef DEBUGMSG
31  atomic_inc64(&num_instances_);
32 #endif
33  }
34  ShortString(const ShortString &other) : long_string_(NULL) {
35 #ifdef DEBUGMSG
36  atomic_inc64(&num_instances_);
37 #endif
38  Assign(other);
39  }
40  ShortString(const char *chars, const unsigned length) : long_string_(NULL) {
41 #ifdef DEBUGMSG
42  atomic_inc64(&num_instances_);
43 #endif
44  Assign(chars, length);
45  }
46  explicit ShortString(const std::string &std_string) : long_string_(NULL) {
47 #ifdef DEBUGMSG
48  atomic_inc64(&num_instances_);
49 #endif
50  Assign(std_string.data(), std_string.length());
51  }
52 
53  ShortString & operator= (const ShortString & other) {
54  if (this != &other)
55  Assign(other);
56  return *this;
57  }
58 
59  ~ShortString() { delete long_string_; }
60 
61  void Assign(const char *chars, const unsigned length) {
62  delete long_string_;
63  long_string_ = NULL;
64  this->length_ = length;
65  if (length > StackSize) {
66 #ifdef DEBUGMSG
67  atomic_inc64(&num_overflows_);
68 #endif
69  long_string_ = new std::string(chars, length);
70  } else {
71  if (length)
72  memcpy(stack_, chars, length);
73  }
74  }
75 
76  void Assign(const ShortString &other) {
77  Assign(other.GetChars(), other.GetLength());
78  }
79 
80  void Append(const char *chars, const unsigned length) {
81  if (long_string_) {
82  long_string_->append(chars, length);
83  return;
84  }
85 
86  const unsigned new_length = this->length_ + length;
87  if (new_length > StackSize) {
88 #ifdef DEBUGMSG
89  atomic_inc64(&num_overflows_);
90 #endif
91  long_string_ = new std::string();
92  long_string_->reserve(new_length);
93  long_string_->assign(stack_, length_);
94  long_string_->append(chars, length);
95  return;
96  }
97  if (length > 0)
98  memcpy(&stack_[this->length_], chars, length);
99  this->length_ = new_length;
100  }
101 
108  void Truncate(unsigned new_length) {
109  assert(new_length <= this->GetLength());
110  if (long_string_) {
111  long_string_->erase(new_length);
112  return;
113  }
114  this->length_ = new_length;
115  }
116 
117  void Clear() {
118  delete long_string_;
119  long_string_ = NULL;
120  length_ = 0;
121  }
122 
123  const char *GetChars() const {
124  if (long_string_) {
125  return long_string_->data();
126  } else {
127  return stack_;
128  }
129  }
130 
131  unsigned GetLength() const {
132  if (long_string_)
133  return long_string_->length();
134  return length_;
135  }
136 
137  bool IsEmpty() const {
138  return GetLength() == 0;
139  }
140 
141  std::string ToString() const {
142  return std::string(this->GetChars(), this->GetLength());
143  }
144 
145  const char *c_str() const {
146  if (long_string_)
147  return long_string_->c_str();
148 
149  char *c = const_cast<char *>(stack_) + length_;
150  *c = '\0';
151  return stack_;
152  }
153 
154  bool operator ==(const ShortString &other) const {
155  const unsigned this_length = this->GetLength();
156  const unsigned other_length = other.GetLength();
157  if (this_length != other_length)
158  return false;
159  if (this_length == 0)
160  return true;
161 
162  return memcmp(this->GetChars(), other.GetChars(), this_length) == 0;
163  }
164 
165  bool operator !=(const ShortString &other) const {
166  return !(*this == other);
167  }
168 
169  bool operator <(const ShortString &other) const {
170  const unsigned this_length = this->GetLength();
171  const unsigned other_length = other.GetLength();
172 
173  if (this_length < other_length)
174  return true;
175  if (this_length > other_length)
176  return false;
177 
178  const char *this_chars = this->GetChars();
179  const char *other_chars = other.GetChars();
180  for (unsigned i = 0; i < this_length; ++i) {
181  if (this_chars[i] < other_chars[i])
182  return true;
183  if (this_chars[i] > other_chars[i])
184  return false;
185  }
186  return false;
187  }
188 
189  bool StartsWith(const ShortString &other) const {
190  const unsigned this_length = this->GetLength();
191  const unsigned other_length = other.GetLength();
192  if (this_length < other_length)
193  return false;
194 
195  return memcmp(this->GetChars(), other.GetChars(), other_length) == 0;
196  }
197 
198  ShortString Suffix(const unsigned start_at) const {
199  const unsigned length = this->GetLength();
200  if (start_at >= length)
201  return ShortString("", 0);
202 
203  return ShortString(this->GetChars() + start_at, length-start_at);
204  }
205 
206  static uint64_t num_instances() { return atomic_read64(&num_instances_); }
207  static uint64_t num_overflows() { return atomic_read64(&num_overflows_); }
208 
209  private:
210  std::string *long_string_;
211  char stack_[StackSize+1]; // +1 to add a final '\0' if necessary
212  unsigned char length_;
215 }; // class ShortString
216 
220 
221 template<unsigned char StackSize, char Type>
223 template<unsigned char StackSize, char Type>
225 
226 // See posix.cc for the std::string counterparts
227 PathString GetParentPath(const PathString &path);
228 NameString GetFileName(const PathString &path);
229 
230 
231 #ifdef CVMFS_NAMESPACE_GUARD
232 } // namespace CVMFS_NAMESPACE_GUARD
233 #endif
234 
235 #endif // CVMFS_SHORTSTRING_H_
ShortString< kDefaultMaxName, 1 > NameString
Definition: shortstring.h:218
int64_t atomic_int64
Definition: atomic.h:18
unsigned char length_
Definition: shortstring.h:212
NameString GetFileName(const PathString &path)
Definition: shortstring.cc:29
ShortString Suffix(const unsigned start_at) const
Definition: shortstring.h:198
void Assign(const char *chars, const unsigned length)
Definition: shortstring.h:61
void Truncate(unsigned new_length)
Definition: shortstring.h:108
const unsigned char kDefaultMaxName
Definition: shortstring.h:22
assert((mem||(size==0))&&"Out Of Memory")
void Clear()
Definition: shortstring.h:117
std::string * long_string_
Definition: shortstring.h:210
static uint64_t num_instances()
Definition: shortstring.h:206
const unsigned char kDefaultMaxPath
Definition: shortstring.h:24
ShortString(const std::string &std_string)
Definition: shortstring.h:46
bool operator<(SharedPtr< T > const &a, SharedPtr< U > const &b)
Definition: shared_ptr.h:144
bool operator!=(const cvmcache_hash &a, const cvmcache_hash &b)
void Append(const char *chars, const unsigned length)
Definition: shortstring.h:80
static atomic_int64 num_overflows_
Definition: shortstring.h:213
void Assign(const ShortString &other)
Definition: shortstring.h:76
const unsigned char kDefaultMaxLink
Definition: shortstring.h:23
std::string ToString() const
Definition: shortstring.h:141
bool operator==(const cvmcache_hash &a, const cvmcache_hash &b)
bool IsEmpty() const
Definition: shortstring.h:137
ShortString< kDefaultMaxLink, 2 > LinkString
Definition: shortstring.h:219
ShortString< kDefaultMaxPath, 0 > PathString
Definition: shortstring.h:217
PathString GetParentPath(const PathString &path)
Definition: shortstring.cc:15
ShortString(const char *chars, const unsigned length)
Definition: shortstring.h:40
bool StartsWith(const ShortString &other) const
Definition: shortstring.h:189
unsigned GetLength() const
Definition: shortstring.h:131
ShortString(const ShortString &other)
Definition: shortstring.h:34
static uint64_t num_overflows()
Definition: shortstring.h:207
const char * c_str() const
Definition: shortstring.h:145
const char * GetChars() const
Definition: shortstring.h:123
static atomic_int64 num_instances_
Definition: shortstring.h:214