Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(441)

Side by Side Diff: extensions/common/api/declarative_net_request/rules_indexer_util.cc

Issue 2881453002: DNR Prototype: With flatbuffers
Patch Set: -- Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "extensions/common/api/declarative_net_request/rules_indexer_util.h"
6
7 #include <utility>
8
9 #include <base/debug/stack_trace.h>
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/json/json_file_value_serializer.h"
13 #include "base/metrics/histogram_macros.h"
14 #include "base/stl_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/threading/thread_restrictions.h"
17 #include "extensions/common/api/declarative_net_request.h"
18 #include "extensions/common/api/declarative_net_request/indexed_rule.h"
19 #include "extensions/common/api/declarative_net_request/ruleset_indexer.h"
20
21 namespace extensions {
22 namespace declarative_net_request {
23
24 namespace {
25
26 struct ParseInfo {
27 ParseInfo(ParseResult parse_result, int index = -1)
28 : result(parse_result), rule_index(index) {}
29
30 ParseResult result;
31 // A value of -1 denotes an empty |rule_index|.
32 int rule_index;
33 };
34
35 bool PersistRuleset(const base::FilePath& path,
36 const RulesetIndexer::SerializedData& data) {
37 return base::WriteFile(path, reinterpret_cast<const char*>(data.first),
38 base::checked_cast<int>(data.second)) != -1;
39 }
40
41 // TODO use localized string?
42 std::string GenerateErrorDescription(const ParseInfo& info) {
43 std::string error;
44 switch (info.result) {
45 case ParseResult::SUCCESS:
46 NOTREACHED();
47 break;
48 case ParseResult::ERROR_LIST_NOT_PASSED:
49 DCHECK_EQ(-1, info.rule_index);
50 error = "The ruleset file does not contain a valid list";
51 break;
52 case ParseResult::ERROR_DUPLICATE_IDS:
53 DCHECK_EQ(-1, info.rule_index);
54 error = "Rules with duplicate ids found.";
55 break;
56 case ParseResult::ERROR_RESOURCE_TYPE_DUPLICATED:
57 DCHECK_GE(info.rule_index, 0);
58 error = base::StringPrintf(
59 "Rule at index %d has duplicated resource type between %s and %s "
60 "keys",
61 info.rule_index, kResourceTypesKey, kExcludeResourceTypesKey);
62 break;
63 case ParseResult::ERROR_PERSISTING_RULESET:
64 DCHECK_EQ(-1, info.rule_index);
65 error = "The rules file could not be persisted";
66 break;
67 // case ParseResult::ERROR_EMPTY_RULE_ID:
68 // DCHECK_GE(info.rule_index, 0);
69 // error = base::StringPrintf(
70 // "Rule at index %d does not have a valid value for %s key",
71 // info.rule_index, kRuleIDKey);
72 // break;
73 case ParseResult::ERROR_EMPTY_REDIRECT_RULE_PRIORITY:
74 DCHECK_GE(info.rule_index, 0);
75 error = base::StringPrintf(
76 "Rule at index %d does not have a valid value for %s key. This is "
77 "required for redirect rules",
78 info.rule_index, kRulePriorityKey);
79 break;
80 case ParseResult::ERROR_EMPTY_REDIRECT_URL:
81 DCHECK_GE(info.rule_index, 0);
82 error = base::StringPrintf(
83 "Rule at index %d does not have a valid value for %s.%s key. This is "
84 "required for redirect rules",
85 info.rule_index, kRuleActionKey, kRedirectUrlKey);
86 break;
87 case ParseResult::ERROR_INVALID_RULE_ID:
88 DCHECK_GE(info.rule_index, 0);
89 error = base::StringPrintf(
90 "Rule at index %d has an invalid value for %s key. This should be "
91 "greater than or equal to %d",
92 info.rule_index, kRuleIDKey, kMinValidID);
93 break;
94 case ParseResult::ERROR_INVALID_REDIRECT_RULE_PRIORITY:
95 DCHECK_GE(info.rule_index, 0);
96 error = base::StringPrintf(
97 "Rule at index %d has an invalid value for %s key. This should be "
98 "greater than or equal to %d",
99 info.rule_index, kRulePriorityKey, kMinValidPriority);
100 break;
101 case ParseResult::ERROR_JSON_PARSE:
102 DCHECK_GE(info.rule_index, 0);
103 error = base::StringPrintf("Rule at index %d could not be parsed.",
104 info.rule_index);
105 break;
106 }
107 return base::StringPrintf("%s: %s", kAPIName, error.c_str());
108 }
109
110 ParseInfo IndexAndPersistRuleset(const base::Value& rules,
111 const base::FilePath& indexed_ruleset_path) {
112 base::ThreadRestrictions::AssertIOAllowed();
113
114 const base::ListValue* rules_list = nullptr;
115 if (!rules.GetAsList(&rules_list))
116 return ParseInfo(ParseResult::ERROR_LIST_NOT_PASSED);
117
118 RulesetIndexer indexer;
119 std::set<int> id_set; // Ensure all ids are distinct.
120 base::TimeTicks start_json_to_flatbuffer = base::TimeTicks::Now();
121 base::TimeDelta create_parsed_rule;
122 base::TimeDelta add_to_flatbuffer;
123 base::TimeDelta create_indexed_rule;
124 std::unique_ptr<Rule> parsed_rule;
125 for (auto iter = rules_list->begin(); iter != rules_list->end(); iter++) {
126 const size_t index = iter - rules_list->begin();
127
128 ParseResult parse_result = ParseResult::SUCCESS;
129 {
130 base::TimeTicks start = base::TimeTicks::Now();
131 parsed_rule = Rule::FromValue(*iter);
132 if (!parsed_rule)
133 parse_result = ParseResult::ERROR_JSON_PARSE;
134 create_parsed_rule += base::TimeTicks::Now() - start;
135 }
136
137 if (parse_result != ParseResult::SUCCESS)
138 return ParseInfo(parse_result, index);
139
140 if (base::ContainsKey(id_set, parsed_rule->id))
141 return ParseInfo(ParseResult::ERROR_DUPLICATE_IDS, index);
142
143 IndexedRule indexed_rule;
144 {
145 base::TimeTicks start = base::TimeTicks::Now();
146 parse_result = CreateIndexedRule(std::move(parsed_rule), &indexed_rule);
147 create_indexed_rule += base::TimeTicks::Now() - start;
148 }
149
150 if (parse_result != ParseResult::SUCCESS)
151 return ParseInfo(parse_result, index);
152
153 {
154 base::TimeTicks start = base::TimeTicks::Now();
155 indexer.AddUrlRule(indexed_rule);
156 add_to_flatbuffer += base::TimeTicks::Now() - start;
157 }
158 }
159
160 LOG(ERROR) << "--------create_parsed_rule " << create_parsed_rule << "\n";
161 LOG(ERROR) << "--------create_indexed_rule " << create_indexed_rule << "\n";
162 LOG(ERROR) << "--------add_to_flatbuffer " << add_to_flatbuffer << "\n";
163 base::TimeDelta end_json_to_flatbuffer =
164 base::TimeTicks::Now() - start_json_to_flatbuffer;
165 LOG(ERROR) << "--------end_json_to_flatbuffer " << end_json_to_flatbuffer
166 << "\n";
167
168 // The actual data buffer is still owned by |indexer|.
169 RulesetIndexer::SerializedData data = indexer.FinishAndGetData();
170
171 base::TimeTicks start_persist = base::TimeTicks::Now();
172 if (!PersistRuleset(indexed_ruleset_path, data))
173 return ParseInfo(ParseResult::ERROR_PERSISTING_RULESET);
174 base::TimeDelta end_persist = base::TimeTicks::Now() - start_persist;
175 LOG(ERROR) << "--------end_persist " << end_persist << "\n";
176
177 return ParseInfo(ParseResult::SUCCESS);
178 }
179
180 } // namespace
181
182 bool IndexAndPersistRuleset(const base::FilePath& json_rules_path,
183 const base::FilePath& indexed_ruleset_path,
184 std::string* error) {
185 base::TimeTicks start_index_and_persist = base::TimeTicks::Now();
186 base::ThreadRestrictions::AssertIOAllowed();
187
188 base::TimeTicks start_deserialization = base::TimeTicks::Now();
189 JSONFileValueDeserializer deserializer(json_rules_path);
190 std::unique_ptr<base::Value> rules = deserializer.Deserialize(nullptr, error);
191 if (!rules)
192 return false; // |error| will be populated by the call to Deserialize.
193 base::TimeDelta deserialize_time =
194 base::TimeTicks::Now() - start_deserialization;
195 LOG(ERROR) << "--------deserialize_time " << deserialize_time << "\n";
196 UMA_HISTOGRAM_TIMES("DNR.JSONDeserializeTime", deserialize_time);
197
198 const ParseInfo info = IndexAndPersistRuleset(*rules, indexed_ruleset_path);
199
200 base::TimeDelta index_and_persist_time =
201 base::TimeTicks::Now() - start_index_and_persist;
202 LOG(ERROR) << "--------index_and_persist_time " << index_and_persist_time
203 << "\n";
204 UMA_HISTOGRAM_TIMES("DNR.IndexAndPersistRuleset", index_and_persist_time);
205 if (info.result != ParseResult::SUCCESS) {
206 if (error)
207 *error = GenerateErrorDescription(info);
208 return false;
209 }
210 return true;
211 }
212
213 } // namespace declarative_net_request
214 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698