1 /*
2 * Copyright (c) 2023-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 #include "doc_query.h"
16 
17 #include <unordered_set>
18 
19 #include "decoded/decoded_event.h"
20 #include "hiview_logger.h"
21 #include "sys_event_query.h"
22 
23 namespace OHOS {
24 namespace HiviewDFX {
25 namespace EventStore {
26 DEFINE_LOG_TAG("HiView-DocQuery");
27 
And(const Cond & cond)28 void DocQuery::And(const Cond& cond)
29 {
30     if (cond.col_ == EventCol::DOMAIN || cond.col_ == EventCol::NAME) {
31         HIVIEW_LOGI("invalid condition, cond.col=%{public}s", cond.col_.c_str());
32         return;
33     }
34     if (IsInnerCond(cond)) {
35         innerConds_.push_back(cond);
36         return;
37     }
38     extraConds_.push_back(cond);
39 }
40 
IsInnerCond(const Cond & cond) const41 bool DocQuery::IsInnerCond(const Cond& cond) const
42 {
43     const std::unordered_set<std::string> innerFields = {
44         EventCol::SEQ, EventCol::TS, EventCol::TZ,
45         EventCol::PID, EventCol::TID, EventCol::UID,
46     };
47     return innerFields.find(cond.col_) != innerFields.end();
48 }
49 
IsContainCond(const Cond & cond,const FieldValue & value) const50 bool DocQuery::IsContainCond(const Cond& cond, const FieldValue& value) const
51 {
52     switch (cond.op_) {
53         case EQ:
54             return value == cond.fieldValue_;
55         case NE:
56             return value != cond.fieldValue_;
57         case GT:
58             return value > cond.fieldValue_;
59         case GE:
60             return value >= cond.fieldValue_;
61         case LT:
62             return value < cond.fieldValue_;
63         case LE:
64             return value <= cond.fieldValue_;
65         case SW:
66             return value.IsStartWith(cond.fieldValue_);
67         case NSW:
68             return value.IsNotStartWith(cond.fieldValue_);
69         default:
70             return false;
71     }
72 }
73 
IsContainInnerCond(const InnerFieldStruct & innerField,const Cond & cond) const74 bool DocQuery::IsContainInnerCond(const InnerFieldStruct& innerField, const Cond& cond) const
75 {
76     FieldValue value;
77     if (cond.col_ == EventCol::SEQ) {
78         value = innerField.seq;
79     } else if (cond.col_ == EventCol::TS) {
80         value = static_cast<int64_t>(innerField.ts);
81     } else if (cond.col_ == EventCol::TZ) {
82         value = static_cast<int64_t>(innerField.tz);
83     } else if (cond.col_ == EventCol::UID) {
84         value = static_cast<int64_t>(innerField.uid);
85     } else if (cond.col_ == EventCol::PID) {
86         value = static_cast<int64_t>(innerField.pid);
87     } else if (cond.col_ == EventCol::TID) {
88         value = static_cast<int64_t>(innerField.tid);
89     } else {
90         return false;
91     }
92     return IsContainCond(cond, value);
93 }
94 
IsContainInnerConds(uint8_t * content) const95 bool DocQuery::IsContainInnerConds(uint8_t* content) const
96 {
97     if (innerConds_.empty()) {
98         return true;
99     }
100     InnerFieldStruct innerField = *(reinterpret_cast<InnerFieldStruct*>(content + BLOCK_SIZE));
101     return std::all_of(innerConds_.begin(), innerConds_.end(), [this, &innerField] (auto& cond) {
102         return IsContainInnerCond(innerField, cond);
103     });
104 }
105 
IsContainExtraConds(uint8_t * content) const106 bool DocQuery::IsContainExtraConds(uint8_t* content) const
107 {
108     if (extraConds_.empty()) {
109         return true;
110     }
111     EventRaw::DecodedEvent decodedEvent(content);
112     return std::all_of(extraConds_.begin(), extraConds_.end(), [this, &decodedEvent] (auto& cond) {
113         const auto& extraParams = decodedEvent.GetAllCustomizedValues();
114         for (auto& param : extraParams) {
115             if (cond.col_ != param->GetKey()) {
116                 continue;
117             }
118             FieldValue paramValue;
119             if (int64_t intValue = 0; param->AsInt64(intValue)) {
120                 paramValue = intValue;
121             } else if (uint64_t uintValue = 0; param->AsUint64(uintValue)) {
122                 paramValue = uintValue;
123             } else if (double dValue = 0; param->AsDouble(dValue)) {
124                 paramValue = dValue;
125             } else if (std::string sValue; param->AsString(sValue)) {
126                 paramValue = sValue;
127             } else {
128                 return false;
129             }
130             return IsContainCond(cond, paramValue);
131         }
132         return false;
133     });
134 }
135 
ToString() const136 std::string DocQuery::ToString() const
137 {
138     std::string output;
139     const std::string connStr = " and ";
140     for (auto& cond : innerConds_) {
141         output.append(cond.ToString());
142         if (&cond != &innerConds_.back()) {
143             output.append(connStr);
144         }
145     }
146     for (auto& cond : extraConds_) {
147         output.append(connStr).append(cond.ToString());
148         if (&cond != &extraConds_.back()) {
149             output.append(connStr);
150         }
151     }
152     return output;
153 }
154 }; // DocQuery
155 } // HiviewDFX
156 } // OHOS
157