case_ignored_flat_map.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. // Date: Sun Dec 4 14:57:27 CST 2016
  18. #ifndef BUTIL_CASE_IGNORED_FLAT_MAP_H
  19. #define BUTIL_CASE_IGNORED_FLAT_MAP_H
  20. #include "butil/containers/flat_map.h"
  21. namespace butil {
  22. // NOTE: Using ascii_tolower instead of ::tolower shortens 150ns in
  23. // FlatMapTest.perf_small_string_map (with -O2 added, -O0 by default)
  24. inline char ascii_tolower(char c) {
  25. extern const char* const g_tolower_map;
  26. return g_tolower_map[(int)c];
  27. }
  28. struct CaseIgnoredHasher {
  29. size_t operator()(const std::string& s) const {
  30. std::size_t result = 0;
  31. for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
  32. result = result * 101 + ascii_tolower(*i);
  33. }
  34. return result;
  35. }
  36. size_t operator()(const char* s) const {
  37. std::size_t result = 0;
  38. for (; *s; ++s) {
  39. result = result * 101 + ascii_tolower(*s);
  40. }
  41. return result;
  42. }
  43. };
  44. struct CaseIgnoredEqual {
  45. // NOTE: No overload for butil::StringPiece. It needs strncasecmp
  46. // which is much slower than strcasecmp in micro-benchmarking. As a
  47. // result, methods in HttpHeader does not accept StringPiece as well.
  48. bool operator()(const std::string& s1, const std::string& s2) const {
  49. return s1.size() == s2.size() &&
  50. strcasecmp(s1.c_str(), s2.c_str()) == 0;
  51. }
  52. bool operator()(const std::string& s1, const char* s2) const
  53. { return strcasecmp(s1.c_str(), s2) == 0; }
  54. };
  55. template <typename T>
  56. class CaseIgnoredFlatMap : public butil::FlatMap<
  57. std::string, T, CaseIgnoredHasher, CaseIgnoredEqual> {};
  58. class CaseIgnoredFlatSet : public butil::FlatSet<
  59. std::string, CaseIgnoredHasher, CaseIgnoredEqual> {};
  60. } // namespace butil
  61. #endif // BUTIL_CASE_IGNORED_FLAT_MAP_H