Skip to content

Commit 4f92d75

Browse files
committed
Fixed lru cache
1 parent 55189fc commit 4f92d75

File tree

1 file changed

+35
-45
lines changed

1 file changed

+35
-45
lines changed

ydb/core/kqp/proxy_service/kqp_proxy_databases_cache.cpp

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ class TDatabaseSubscriberActor : public TActor<TDatabaseSubscriberActor> {
5050
};
5151

5252
using TBase = TActor<TDatabaseSubscriberActor>;
53-
using TDatabaseStatePtr = typename std::list<TDatabaseState>::iterator;
5453

5554
public:
5655
TDatabaseSubscriberActor(TDuration idleTimeout)
5756
: TBase(&TDatabaseSubscriberActor::StateFunc)
5857
, IdleTimeout(idleTimeout)
58+
, DatabaseStates(std::numeric_limits<size_t>::max())
5959
{}
6060

6161
void Registered(TActorSystem* sys, const TActorId& owner) {
@@ -65,86 +65,76 @@ class TDatabaseSubscriberActor : public TActor<TDatabaseSubscriberActor> {
6565

6666
void Handle(TEvPrivate::TEvSubscribeOnDatabase::TPtr& ev) {
6767
const TString& database = ev->Get()->Database;
68-
const auto it = DatabasePathToState.find(database);
68+
auto databaseStateIt = DatabaseStates.Find(database);
6969

70-
if (it == DatabasePathToState.end()) {
71-
DatabaseStates.emplace_front(TDatabaseState{.Database = database});
72-
DatabasePathToState.insert({database, DatabaseStates.begin()});
70+
if (databaseStateIt == DatabaseStates.End()) {
71+
DatabaseStates.Insert({database, TDatabaseState{.Database = database}});
7372
Register(NWorkload::CreateDatabaseFetcherActor(SelfId(), database));
7473
StartIdleCheck();
7574
return;
7675
}
7776

78-
const auto databaseState = it->second;
79-
if (databaseState->DatabaseId) {
80-
SendSubscriberInfo(*databaseState, Ydb::StatusIds::SUCCESS);
77+
databaseStateIt->LastUpdateTime = TInstant::Now();
78+
if (databaseStateIt->DatabaseId) {
79+
SendSubscriberInfo(*databaseStateIt, Ydb::StatusIds::SUCCESS);
8180
}
8281
}
8382

8483
void Handle(TEvPrivate::TEvPingDatabaseSubscription::TPtr& ev) {
85-
const auto it = DatabasePathToState.find(ev->Get()->Database);
86-
if (it == DatabasePathToState.end()) {
87-
return;
84+
auto databaseStateIt = DatabaseStates.Find(ev->Get()->Database);
85+
if (databaseStateIt != DatabaseStates.End()) {
86+
databaseStateIt->LastUpdateTime = TInstant::Now();
8887
}
89-
90-
TDatabaseState databaseState = *it->second;
91-
databaseState.LastUpdateTime = TInstant::Now();
92-
93-
DatabaseStates.erase(it->second);
94-
DatabaseStates.emplace_front(databaseState);
95-
it->second = DatabaseStates.begin();
9688
}
9789

9890
void Handle(NWorkload::TEvFetchDatabaseResponse::TPtr& ev) {
99-
const auto it = DatabasePathToState.find(ev->Get()->Database);
100-
if (it == DatabasePathToState.end()) {
91+
auto databaseStateIt = DatabaseStates.Find(ev->Get()->Database);
92+
if (databaseStateIt == DatabaseStates.End()) {
10193
return;
10294
}
10395

104-
const auto databaseState = it->second;
105-
databaseState->FetchRequestIsRunning = false;
106-
UpdateDatabaseState(*databaseState, ev->Get()->PathId, ev->Get()->Serverless);
107-
SendSubscriberInfo(*databaseState, ev->Get()->Status, ev->Get()->Issues);
96+
databaseStateIt->FetchRequestIsRunning = false;
97+
UpdateDatabaseState(*databaseStateIt, ev->Get()->PathId, ev->Get()->Serverless);
98+
SendSubscriberInfo(*databaseStateIt, ev->Get()->Status, ev->Get()->Issues);
10899

109100
if (ev->Get()->Status == Ydb::StatusIds::SUCCESS) {
110101
FreeWatchKey++;
111-
databaseState->WatchKey = FreeWatchKey;
102+
databaseStateIt->WatchKey = FreeWatchKey;
112103
Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvWatchPathId(ev->Get()->PathId, FreeWatchKey));
113104
}
114105
}
115106

116107
void Handle(TEvTxProxySchemeCache::TEvWatchNotifyDeleted::TPtr& ev) {
117-
const auto it = DatabasePathToState.find(ev->Get()->Path);
118-
if (it == DatabasePathToState.end()) {
108+
auto databaseStateIt = DatabaseStates.Find(ev->Get()->Path);
109+
if (databaseStateIt == DatabaseStates.End()) {
119110
return;
120111
}
121112

122-
const auto databaseState = it->second;
123-
UnsubscribeFromSchemeCache(*databaseState);
124-
SendSubscriberInfo(*databaseState, Ydb::StatusIds::NOT_FOUND, {NYql::TIssue{"Database was dropped"}});
125-
DatabasePathToState.erase(it);
126-
DatabaseStates.erase(databaseState);
113+
UnsubscribeFromSchemeCache(*databaseStateIt);
114+
SendSubscriberInfo(*databaseStateIt, Ydb::StatusIds::NOT_FOUND, {NYql::TIssue{"Database was dropped"}});
115+
DatabaseStates.Erase(databaseStateIt);
127116
}
128117

129118
void HandlePoison() {
130-
for (auto& databaseState : DatabaseStates) {
131-
UnsubscribeFromSchemeCache(databaseState);
132-
}
133-
119+
Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvWatchRemove(0));
134120
TBase::PassAway();
135121
}
136122

137123
void HandleWakeup() {
138124
IdleCheckStarted = false;
139125
const auto minimalTime = TInstant::Now() - IdleTimeout;
140-
while (!DatabaseStates.empty() && DatabaseStates.back().LastUpdateTime <= minimalTime) {
141-
UnsubscribeFromSchemeCache(DatabaseStates.back());
142-
SendSubscriberInfo(DatabaseStates.back(), Ydb::StatusIds::ABORTED, {NYql::TIssue{"Database subscription was dropped by idle timeout"}});
143-
DatabasePathToState.erase(DatabaseStates.back().Database);
144-
DatabaseStates.pop_back();
126+
while (!DatabaseStates.Empty()) {
127+
auto oldestIt = DatabaseStates.FindOldest();
128+
if (oldestIt->LastUpdateTime > minimalTime) {
129+
break;
130+
}
131+
132+
UnsubscribeFromSchemeCache(*oldestIt);
133+
SendSubscriberInfo(*oldestIt, Ydb::StatusIds::ABORTED, {NYql::TIssue{"Database subscription was dropped by idle timeout"}});
134+
DatabaseStates.Erase(oldestIt);
145135
}
146136

147-
if (!DatabaseStates.empty()) {
137+
if (!DatabaseStates.Empty()) {
148138
StartIdleCheck();
149139
}
150140
}
@@ -162,6 +152,7 @@ class TDatabaseSubscriberActor : public TActor<TDatabaseSubscriberActor> {
162152

163153
private:
164154
static void UpdateDatabaseState(TDatabaseState& databaseState, TPathId pathId, bool serverless) {
155+
databaseState.LastUpdateTime = TInstant::Now();
165156
databaseState.DatabaseId = (serverless ? TStringBuilder() << pathId.OwnerId << ":" << pathId.LocalPathId << ":" : TStringBuilder()) << databaseState.Database;
166157
databaseState.Serverless = serverless;
167158
}
@@ -173,7 +164,7 @@ class TDatabaseSubscriberActor : public TActor<TDatabaseSubscriberActor> {
173164
}
174165
}
175166

176-
void SendSubscriberInfo(TDatabaseState& databaseState, Ydb::StatusIds::StatusCode status, NYql::TIssues issues = {}) {
167+
void SendSubscriberInfo(const TDatabaseState& databaseState, Ydb::StatusIds::StatusCode status, NYql::TIssues issues = {}) {
177168
if (status == Ydb::StatusIds::SUCCESS || status == Ydb::StatusIds::UNSUPPORTED) {
178169
Send(Owner, new TEvKqp::TEvUpdateDatabaseInfo(databaseState.Database, databaseState.DatabaseId, databaseState.Serverless));
179170
} else {
@@ -197,8 +188,7 @@ class TDatabaseSubscriberActor : public TActor<TDatabaseSubscriberActor> {
197188
TActorId Owner;
198189
bool IdleCheckStarted = false;
199190

200-
std::unordered_map<TString, TDatabaseStatePtr> DatabasePathToState;
201-
std::list<TDatabaseState> DatabaseStates;
191+
TLRUCache<TString, TDatabaseState> DatabaseStates;
202192
ui32 FreeWatchKey = 0;
203193
};
204194

0 commit comments

Comments
 (0)