CernVM-FS  2.9.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 "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  atomic_inc64(&num_instances_);
31  }
32  ShortString(const ShortString &other) : long_string_(NULL) {
33  atomic_inc64(&num_instances_);
34  Assign(other);
35  }
36  ShortString(const char *chars, const unsigned length) : long_string_(NULL) {
37  atomic_inc64(&num_instances_);
38  Assign(chars, length);
39  }
40  explicit ShortString(const std::string &std_string) : long_string_(NULL) {
41  atomic_inc64(&num_instances_);
42  Assign(std_string.data(), std_string.length());
43  }
44 
45  ShortString & operator= (const ShortString & other) {
46  if (this != &other)
47  Assign(other);
48  return *this;
49  }
50 
51  ~ShortString() { delete long_string_; }
52 
53  void Assign(const char *chars, const unsigned length) {
54  delete long_string_;
55  long_string_ = NULL;
56  if (length > StackSize) {
57  atomic_inc64(&num_overflows_);
58  long_string_ = new std::string(chars, length);
59  } else {
60  if (length)
61  memcpy(stack_, chars, length);
62  this->length_ = length;
63  }
64  }
65 
66  void Assign(const ShortString &other) {
67  Assign(other.GetChars(), other.GetLength());
68  }
69 
70  void Append(const char *chars, const unsigned length) {
71  if (long_string_) {
72  long_string_->append(chars, length);
73  return;
74  }
75 
76  const unsigned new_length = this->length_ + length;
77  if (new_length > StackSize) {
78  atomic_inc64(&num_overflows_);
79  long_string_ = new std::string();
80  long_string_->reserve(new_length);
81  long_string_->assign(stack_, length_);
82  long_string_->append(chars, length);
83  return;
84  }
85  if (length > 0)
86  memcpy(&stack_[this->length_], chars, length);
87  this->length_ = new_length;
88  }
89 
90  void Clear() {
91  delete long_string_;
92  long_string_ = NULL;
93  length_ = 0;
94  }
95 
96  const char *GetChars() const {
97  if (long_string_)
98  return long_string_->data();
99  else
100  return stack_;
101  }
102 
103  unsigned GetLength() const {
104  if (long_string_)
105  return long_string_->length();
106  return length_;
107  }
108 
109  bool IsEmpty() const {
110  return GetLength() == 0;
111  }
112 
113  std::string ToString() const {
114  return std::string(this->GetChars(), this->GetLength());
115  }
116 
117  const char *c_str() const {
118  if (long_string_)
119  return long_string_->c_str();
120 
121  char *c = const_cast<char *>(stack_) + length_;
122  *c = '\0';
123  return stack_;
124  }
125 
126  bool operator ==(const ShortString &other) const {
127  const unsigned this_length = this->GetLength();
128  const unsigned other_length = other.GetLength();
129  if (this_length != other_length)
130  return false;
131  if (this_length == 0)
132  return true;
133 
134  return memcmp(this->GetChars(), other.GetChars(), this_length) == 0;
135  }
136 
137  bool operator !=(const ShortString &other) const {
138  return !(*this == other);
139  }
140 
141  bool operator <(const ShortString &other) const {
142  const unsigned this_length = this->GetLength();
143  const unsigned other_length = other.GetLength();
144 
145  if (this_length < other_length)
146  return true;
147  if (this_length > other_length)
148  return false;
149 
150  const char *this_chars = this->GetChars();
151  const char *other_chars = other.GetChars();
152  for (unsigned i = 0; i < this_length; ++i) {
153  if (this_chars[i] < other_chars[i])
154  return true;
155  if (this_chars[i] > other_chars[i])
156  return false;
157  }
158  return false;
159  }
160 
161  bool StartsWith(const ShortString &other) const {
162  const unsigned this_length = this->GetLength();
163  const unsigned other_length = other.GetLength();
164  if (this_length < other_length)
165  return false;
166 
167  return memcmp(this->GetChars(), other.GetChars(), other_length) == 0;
168  }
169 
170  ShortString Suffix(const unsigned start_at) const {
171  const unsigned length = this->GetLength();
172  if (start_at >= length)
173  return ShortString("", 0);
174 
175  return ShortString(this->GetChars() + start_at, length-start_at);
176  }
177 
178  static uint64_t num_instances() { return atomic_read64(&num_instances_); }
179  static uint64_t num_overflows() { return atomic_read64(&num_overflows_); }
180 
181  private:
182  std::string *long_string_;
183  char stack_[StackSize+1]; // +1 to add a final '\0' if necessary
184  unsigned char length_;
187 }; // class ShortString
188 
192 
193 template<unsigned char StackSize, char Type>
195 template<unsigned char StackSize, char Type>
197 
198 #ifdef CVMFS_NAMESPACE_GUARD
199 } // namespace CVMFS_NAMESPACE_GUARD
200 #endif
201 
202 #endif // CVMFS_SHORTSTRING_H_
ShortString< kDefaultMaxName, 1 > NameString
Definition: shortstring.h:190
int64_t atomic_int64
Definition: atomic.h:18
unsigned char length_
Definition: shortstring.h:184
ShortString Suffix(const unsigned start_at) const
Definition: shortstring.h:170
void Assign(const char *chars, const unsigned length)
Definition: shortstring.h:53
const unsigned char kDefaultMaxName
Definition: shortstring.h:22
void Clear()
Definition: shortstring.h:90
std::string * long_string_
Definition: shortstring.h:182
static uint64_t num_instances()
Definition: shortstring.h:178
const unsigned char kDefaultMaxPath
Definition: shortstring.h:24
ShortString(const std::string &std_string)
Definition: shortstring.h:40
bool operator<(SharedPtr< T > const &a, SharedPtr< U > const &b)
Definition: shared_ptr.h:141
bool operator!=(const cvmcache_hash &a, const cvmcache_hash &b)
void Append(const char *chars, const unsigned length)
Definition: shortstring.h:70
static atomic_int64 num_overflows_
Definition: shortstring.h:185
void Assign(const ShortString &other)
Definition: shortstring.h:66
const unsigned char kDefaultMaxLink
Definition: shortstring.h:23
std::string ToString() const
Definition: shortstring.h:113
bool operator==(const cvmcache_hash &a, const cvmcache_hash &b)
bool IsEmpty() const
Definition: shortstring.h:109
ShortString< kDefaultMaxLink, 2 > LinkString
Definition: shortstring.h:191
ShortString< kDefaultMaxPath, 0 > PathString
Definition: shortstring.h:189
ShortString(const char *chars, const unsigned length)
Definition: shortstring.h:36
bool StartsWith(const ShortString &other) const
Definition: shortstring.h:161
unsigned GetLength() const
Definition: shortstring.h:103
ShortString(const ShortString &other)
Definition: shortstring.h:32
static uint64_t num_overflows()
Definition: shortstring.h:179
const char * c_str() const
Definition: shortstring.h:117
const char * GetChars() const
Definition: shortstring.h:96
static atomic_int64 num_instances_
Definition: shortstring.h:186