ClickHouse/dbms/include/DB/Core/StringRef.h

103 lines
2.2 KiB
C
Raw Normal View History

2012-05-31 04:49:55 +00:00
#pragma once
#include <string.h>
#include <city.h>
#include <string>
#include <vector>
2012-05-31 04:49:55 +00:00
2014-01-08 16:33:28 +00:00
#include <functional>
2014-04-08 12:54:32 +00:00
#include <ostream>
2012-05-31 04:49:55 +00:00
namespace DB
{
/// Штука, чтобы не создавать строки для поиска подстроки в хэш таблице.
struct StringRef
{
2014-04-08 07:31:51 +00:00
const char * data = nullptr;
size_t size = 0;
2012-05-31 04:49:55 +00:00
StringRef(const char * data_, size_t size_) : data(data_), size(size_) {}
2012-05-31 05:41:56 +00:00
StringRef(const unsigned char * data_, size_t size_) : data(reinterpret_cast<const char *>(data_)), size(size_) {}
2012-05-31 04:49:55 +00:00
StringRef(const std::string & s) : data(s.data()), size(s.size()) {}
2014-04-08 07:31:51 +00:00
StringRef() {}
std::string toString() const { return std::string(data, size); }
2012-05-31 04:49:55 +00:00
};
typedef std::vector<StringRef> StringRefs;
2012-05-31 04:49:55 +00:00
inline bool operator==(StringRef lhs, StringRef rhs)
{
2012-06-01 10:45:29 +00:00
/// Так почему-то быстрее, чем return lhs.size == rhs.size && 0 == memcmp(lhs.data, rhs.data, lhs.size);
if (lhs.size != rhs.size)
return false;
for (size_t pos = 0; pos < lhs.size; ++pos)
if (lhs.data[pos] != rhs.data[pos])
return false;
return true;
2012-05-31 04:49:55 +00:00
}
inline bool operator!=(StringRef lhs, StringRef rhs)
{
return !(lhs == rhs);
}
2014-04-08 12:54:32 +00:00
inline bool operator<(StringRef lhs, StringRef rhs)
{
int cmp = memcmp(lhs.data, rhs.data, std::min(lhs.size, rhs.size));
if (cmp == 0)
return lhs.size < rhs.size;
else
return cmp < 0;
}
2012-05-31 04:49:55 +00:00
struct StringRefHash
{
inline size_t operator() (StringRef x) const
{
return CityHash64(x.data, x.size);
}
};
struct StringRefZeroTraits
{
2014-04-08 07:47:51 +00:00
static inline bool check(DB::StringRef x) { return nullptr == x.data; }
2014-04-08 07:31:51 +00:00
static inline void set(DB::StringRef & x) { x.data = nullptr; }
};
inline bool operator==(StringRef lhs, const char * rhs)
{
for (size_t pos = 0; pos < lhs.size; ++pos)
{
if (!rhs[pos] || lhs.data[pos] != rhs[pos])
return false;
}
return true;
}
2014-03-26 10:56:21 +00:00
2014-03-26 18:19:25 +00:00
inline std::ostream & operator<<(std::ostream & os, const StringRef & str)
{
if (str.data)
2014-04-08 12:54:32 +00:00
os.write(str.data, str.size);
return os;
2014-03-26 18:19:25 +00:00
}
2012-05-31 04:49:55 +00:00
}
namespace std
{
2014-01-08 16:33:28 +00:00
template <>
struct hash<DB::StringRef>
{
2014-01-08 16:33:28 +00:00
size_t operator()(const DB::StringRef & x) const
{
2014-01-08 16:33:28 +00:00
return CityHash64(x.data, x.size);
}
};
}