• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define LOG_TAG "RdbSqlStatistic"
17 
18 #include "rdb_sql_statistic.h"
19 
20 #include <thread>
21 
22 #include "concurrent_map.h"
23 #include "logger.h"
24 #include "rdb_errno.h"
25 #include "rdb_platform.h"
26 #include "task_executor.h"
27 namespace OHOS::DistributedRdb {
28 using namespace OHOS::Rdb;
29 using namespace OHOS::NativeRdb;
30 ConcurrentMap<SqlObserver *, std::shared_ptr<SqlObserver>> SqlStatistic::observers_;
31 ConcurrentMap<uint64_t, std::shared_ptr<SqlObserver::SqlExecutionInfo>> SqlStatistic::execInfos_;
32 bool SqlStatistic::enabled_ = false;
33 std::atomic_uint32_t SqlStatistic::seqId_ = 0;
Subscribe(std::shared_ptr<SqlObserver> observer)34 int SqlStatistic::Subscribe(std::shared_ptr<SqlObserver> observer)
35 {
36     observers_.ComputeIfAbsent(observer.get(), [observer](auto &) {
37         enabled_ = true;
38         return observer;
39     });
40     return E_OK;
41 }
42 
Unsubscribe(std::shared_ptr<SqlObserver> observer)43 int SqlStatistic::Unsubscribe(std::shared_ptr<SqlObserver> observer)
44 {
45     observers_.Erase(observer.get());
46     observers_.DoActionIfEmpty([]() {
47         enabled_ = false;
48         execInfos_.Clear();
49     });
50     return E_OK;
51 }
52 
SqlStatistic(const std::string & sql,int32_t step,uint32_t seqId)53 SqlStatistic::SqlStatistic(const std::string &sql, int32_t step, uint32_t seqId)
54 {
55     if (!enabled_) {
56         return;
57     }
58     step_ = step;
59     key_ = seqId == 0 ? GetThreadId() : uint64_t(seqId);
60     time_ = std::chrono::steady_clock::now();
61     auto it = execInfos_.Find(key_);
62     if (it.first) {
63         execInfo_ = it.second;
64     }
65 
66     if (execInfo_ == nullptr && seqId != 0) {
67         it = execInfos_.Find(GetThreadId());
68         execInfo_ = it.second;
69     }
70 
71     if (execInfo_ == nullptr) {
72         execInfo_ = std::shared_ptr<SqlExecInfo>(new (std::nothrow) SqlExecInfo(), Release);
73         execInfos_.Insert(key_, execInfo_);
74     }
75 
76     if (step_ == STEP_PREPARE && !sql.empty()) {
77         execInfo_->sql_.emplace_back(sql);
78     }
79 }
80 
~SqlStatistic()81 SqlStatistic::~SqlStatistic()
82 {
83     if (!enabled_) {
84         return;
85     }
86     if (execInfo_ == nullptr) {
87         return;
88     }
89     auto interval = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - time_);
90     switch (step_) {
91         case STEP_WAIT:
92             execInfo_->waitTime_ += interval.count();
93             break;
94         case STEP_PREPARE:
95             execInfo_->prepareTime_ += interval.count();
96             break;
97         case STEP_EXECUTE:
98             execInfo_->executeTime_ += interval.count();
99             break;
100         case STEP_TOTAL:
101         case STEP_TOTAL_RES:
102             execInfo_->totalTime_ += interval.count();
103             execInfos_.Erase(key_);
104             break;
105         default:
106             execInfo_->totalTime_ += interval.count();
107             break;
108     }
109 }
110 
Release(SqlExecInfo * execInfo)111 void SqlStatistic::Release(SqlExecInfo *execInfo)
112 {
113     if (execInfo == nullptr) {
114         return;
115     }
116     if (execInfo->sql_.empty()) {
117         delete execInfo;
118         return;
119     }
120     auto executor = TaskExecutor::GetInstance().GetExecutor();
121     if (executor == nullptr) {
122         delete execInfo;
123         return;
124     }
125     executor->Execute([info = std::move(*execInfo)]() {
126         observers_.ForEachCopies([&info](auto key, std::shared_ptr<SqlObserver> &observer) {
127             if (observer == nullptr) {
128                 return false;
129             }
130             observer->OnStatistic(info);
131             return false;
132         });
133     });
134     delete execInfo;
135 }
136 }