case_insensitive_string.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #include "case_insensitive_string.h"
  2. #include <library/cpp/digest/murmur/murmur.h>
  3. #include <util/string/escape.h>
  4. #include <array>
  5. namespace {
  6. template <auto ToLower>
  7. struct TCaseInsensitiveHash {
  8. static size_t HashTail(TMurmurHash2A<size_t>& hash, const char* data, size_t size) noexcept {
  9. for (size_t i = 0; i < size; ++i) {
  10. char lower = ToLower(data[i]);
  11. hash.Update(&lower, 1);
  12. }
  13. return hash.Value();
  14. }
  15. static size_t ComputeHash(const char* s, size_t n) noexcept {
  16. TMurmurHash2A<size_t> hash;
  17. std::array<char, sizeof(size_t)> buf;
  18. size_t headSize = n - n % buf.size();
  19. for (size_t i = 0; i < headSize; i += buf.size()) {
  20. for (size_t j = 0; j < buf.size(); ++j) {
  21. buf[j] = ToLower(s[i + j]);
  22. }
  23. hash.Update(buf.data(), buf.size());
  24. }
  25. return HashTail(hash, s + headSize, n - headSize);
  26. }
  27. };
  28. }
  29. size_t CaseInsensitiveStringHash(const char* s, size_t n) noexcept {
  30. return TCaseInsensitiveHash<static_cast<int(*)(int)>(std::tolower)>::ComputeHash(s, n);
  31. }
  32. size_t CaseInsensitiveAsciiStringHash(const char* s, size_t n) noexcept {
  33. return TCaseInsensitiveHash<static_cast<char(*)(char)>(AsciiToLower)>::ComputeHash(s, n);
  34. }
  35. #define Y_DEFINE_STRING_OUT(type) \
  36. template <> \
  37. void Out<type>(IOutputStream& o, const type& p) { \
  38. o.Write(p.data(), p.size()); \
  39. }
  40. Y_DEFINE_STRING_OUT(TCaseInsensitiveString);
  41. Y_DEFINE_STRING_OUT(TCaseInsensitiveStringBuf);
  42. Y_DEFINE_STRING_OUT(TCaseInsensitiveAsciiString);
  43. Y_DEFINE_STRING_OUT(TCaseInsensitiveAsciiStringBuf);
  44. #undef Y_DEFINE_STRING_OUT
  45. #define Y_DEFINE_STRING_ESCAPE(type) \
  46. type EscapeC(const type& str) { \
  47. const auto result = EscapeC(str.data(), str.size()); \
  48. return {result.data(), result.size()}; \
  49. }
  50. Y_DEFINE_STRING_ESCAPE(TCaseInsensitiveString);
  51. Y_DEFINE_STRING_ESCAPE(TCaseInsensitiveAsciiString);
  52. #undef Y_DEFINE_STRING_ESCAPE