registry.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "registry.h"
  2. #include <library/cpp/blockcodecs/core/codecs.h>
  3. #include <util/system/yassert.h>
  4. #include <util/generic/hash.h>
  5. #include <util/generic/deque.h>
  6. #include <util/generic/singleton.h>
  7. #include <util/system/env.h>
  8. using namespace NResource;
  9. using namespace NBlockCodecs;
  10. namespace {
  11. inline const ICodec* GetCodec() noexcept {
  12. static const ICodec* ret = Codec("zstd08_5");
  13. return ret;
  14. }
  15. typedef std::pair<TStringBuf, TStringBuf> TDescriptor;
  16. struct TStore: public IStore, public THashMap<TStringBuf, TDescriptor*> {
  17. void Store(const TStringBuf key, const TStringBuf data) override {
  18. if (contains(key)) {
  19. const TStringBuf value = (*this)[key]->second;
  20. if (value != data) {
  21. size_t vsize = GetCodec()->DecompressedLength(value);
  22. size_t dsize = GetCodec()->DecompressedLength(data);
  23. if (vsize + dsize < 1000) {
  24. Y_ABORT_UNLESS(false, "Redefinition of key %s:\n"
  25. " old value: %s,\n"
  26. " new value: %s.",
  27. TString{key}.Quote().c_str(),
  28. Decompress(value).Quote().c_str(),
  29. Decompress(data).Quote().c_str());
  30. } else {
  31. Y_ABORT_UNLESS(false, "Redefinition of key %s,"
  32. " old size: %zu,"
  33. " new size: %zu.",
  34. TString{key}.Quote().c_str(), vsize, dsize);
  35. }
  36. }
  37. } else {
  38. D_.push_back(TDescriptor(key, data));
  39. (*this)[key] = &D_.back();
  40. }
  41. Y_ABORT_UNLESS(size() == Count(), "size mismatch");
  42. }
  43. bool Has(const TStringBuf key) const override {
  44. return contains(key);
  45. }
  46. bool FindExact(const TStringBuf key, TString* out) const override {
  47. if (TDescriptor* const* res = FindPtr(key)) {
  48. // temporary
  49. // https://st.yandex-team.ru/DEVTOOLS-3985
  50. try {
  51. *out = Decompress((*res)->second);
  52. } catch (const yexception& e) {
  53. if (GetEnv("RESOURCE_DECOMPRESS_DIAG")) {
  54. Cerr << "Can't decompress resource " << key << Endl << e.what() << Endl;
  55. }
  56. throw e;
  57. }
  58. return true;
  59. }
  60. return false;
  61. }
  62. void FindMatch(const TStringBuf subkey, IMatch& cb) const override {
  63. for (const auto& it : *this) {
  64. if (it.first.StartsWith(subkey)) {
  65. // temporary
  66. // https://st.yandex-team.ru/DEVTOOLS-3985
  67. try {
  68. const TResource res = {
  69. it.first, Decompress(it.second->second)};
  70. cb.OnMatch(res);
  71. } catch (const yexception& e) {
  72. if (GetEnv("RESOURCE_DECOMPRESS_DIAG")) {
  73. Cerr << "Can't decompress resource " << it.first << Endl << e.what() << Endl;
  74. }
  75. throw e;
  76. }
  77. }
  78. }
  79. }
  80. size_t Count() const noexcept override {
  81. return D_.size();
  82. }
  83. TStringBuf KeyByIndex(size_t idx) const override {
  84. return D_.at(idx).first;
  85. }
  86. typedef TDeque<TDescriptor> TDescriptors;
  87. TDescriptors D_;
  88. };
  89. }
  90. TString NResource::Compress(const TStringBuf data) {
  91. return GetCodec()->Encode(data);
  92. }
  93. TString NResource::Decompress(const TStringBuf data) {
  94. return GetCodec()->Decode(data);
  95. }
  96. IStore* NResource::CommonStore() {
  97. return SingletonWithPriority<TStore, 0>();
  98. }