You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

symcache_id_list.hxx 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*-
  2. * Copyright 2022 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef RSPAMD_SYMCACHE_ID_LIST_HXX
  17. #define RSPAMD_SYMCACHE_ID_LIST_HXX
  18. #pragma once
  19. #include <cstdint>
  20. #include <cstring> // for memset
  21. #include <algorithm>// for sort/bsearch
  22. #include "config.h"
  23. #include "libutil/mem_pool.h"
  24. #include "contrib/ankerl/svector.h"
  25. namespace rspamd::symcache {
  26. /*
  27. * This structure is optimised to store ids list:
  28. * - If the first element is -1 then use dynamic part, else use static part
  29. * There is no std::variant to save space
  30. */
  31. constexpr const auto id_capacity = 4;
  32. constexpr const auto id_sort_threshold = 32;
  33. struct id_list {
  34. ankerl::svector<std::uint32_t, id_capacity> data;
  35. id_list() = default;
  36. auto reset()
  37. {
  38. data.clear();
  39. }
  40. /**
  41. * Returns ids from a compressed list, accepting a mutable reference for number of elements
  42. * @param nids output of the number of elements
  43. * @return
  44. */
  45. auto get_ids(unsigned &nids) const -> const std::uint32_t *
  46. {
  47. nids = data.size();
  48. return data.data();
  49. }
  50. auto add_id(std::uint32_t id) -> void
  51. {
  52. data.push_back(id);
  53. /* Check sort threshold */
  54. if (data.size() > id_sort_threshold) {
  55. std::sort(data.begin(), data.end());
  56. }
  57. }
  58. auto set_ids(const std::uint32_t *ids, std::size_t nids) -> void
  59. {
  60. data.resize(nids);
  61. for (auto &id: data) {
  62. id = *ids++;
  63. }
  64. if (data.size() > id_sort_threshold) {
  65. std::sort(data.begin(), data.end());
  66. }
  67. }
  68. auto check_id(unsigned int id) const -> bool
  69. {
  70. if (data.size() > id_sort_threshold) {
  71. return std::binary_search(data.begin(), data.end(), id);
  72. }
  73. return std::find(data.begin(), data.end(), id) != data.end();
  74. }
  75. };
  76. }// namespace rspamd::symcache
  77. #endif//RSPAMD_SYMCACHE_ID_LIST_HXX