123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- #pragma once
- #include <util/generic/buffer.h>
- #include <util/generic/deque.h>
- #include <util/generic/noncopyable.h>
- #include <util/generic/strbuf.h>
- #include <util/system/tls.h>
- #include <util/thread/singleton.h>
- namespace NCodecs {
- template <class TItem>
- struct TClear {
- void operator()(TItem& item) const {
- item.Clear();
- }
- };
- template <class TItem, class TCleaner = TClear<TItem>>
- class TTlsCache {
- using TSelf = TTlsCache<TItem, TCleaner>;
- struct TItemHolder: public TIntrusiveListItem<TItemHolder> {
- TItemHolder(TSelf& factory)
- : Factory(factory)
- {
- }
- void Release() {
- Factory.Release(*this);
- }
- TSelf& Factory;
- TItem Item;
- };
- class TItemGuard {
- public:
- explicit TItemGuard(TSelf& fact)
- : Holder(fact.Acquire())
- {
- }
- TItemGuard(TItemGuard&& other) noexcept {
- *this = std::move(other);
- }
- TItemGuard& operator=(TItemGuard&& other) noexcept {
- if (&other != this) {
- std::swap(Holder, other.Holder);
- }
- return *this;
- }
- ~TItemGuard() {
- if (Holder) {
- Holder->Release();
- }
- }
- TItem& Get() & {
- Y_ASSERT(Holder);
- return Holder->Item;
- }
- TItem& Get() && = delete;
- private:
- TItemHolder* Holder = nullptr;
- };
- public:
- TItemGuard Item() {
- return TItemGuard(*this);
- }
- static TSelf& TlsInstance() {
- return *FastTlsSingleton<TSelf>();
- }
- private:
- TItemHolder* Acquire() {
- if (Free.Empty()) {
- return new TItemHolder(*this);
- } else {
- return Free.PopBack();
- }
- }
- void Release(TItemHolder& item) {
- Cleaner(item.Item);
- Free.PushBack(&item);
- }
- private:
- TIntrusiveListWithAutoDelete<TItemHolder, TDelete> Free;
- TCleaner Cleaner;
- };
- using TBufferTlsCache = TTlsCache<TBuffer>;
- }
|