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

Side by Side Diff: net/tools/domain_security_preload_generator/huffman/huffman_frequency_tracker.cc

Issue 2551153003: Add static domain security state generator tool. (Closed)
Patch Set: fix base64 issue and accidental replace. Created 4 years 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 (c) 2016 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 "net/tools/domain_security_preload_generator/huffman/huffman_frequency_ tracker.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10 #include "net/tools/domain_security_preload_generator/huffman/huffman_node.h"
agl 2016/12/06 18:51:35 If this is the only include of |huffman_node.h| th
martijnc 2016/12/07 22:37:54 It is only used here. Moved HuffmanNode into an an
11
12 namespace net {
13
14 namespace {
15
16 bool CompareNodes(const std::unique_ptr<net::HuffmanNode>& lhs,
17 const std::unique_ptr<net::HuffmanNode>& rhs) {
18 return lhs->count() < rhs->count();
19 }
20
21 } // namespace
22
23 HuffmanFrequencyTracker::HuffmanFrequencyTracker() {}
24
25 HuffmanFrequencyTracker::~HuffmanFrequencyTracker() {}
26
27 void HuffmanFrequencyTracker::RecordUsage(uint8_t character) {
28 counts_[character] += 1;
29 }
30
31 HuffmanRepresentationTable
32 HuffmanFrequencyTracker::ToHuffmanRepresentationTable() {
33 HuffmanRepresentationTable table;
34 std::unique_ptr<HuffmanNode> node(BuildTree());
35
36 TreeToHuffmanRepresentationTable(node.get(), 0, 0, &table);
37 return table;
38 }
39
40 void HuffmanFrequencyTracker::TreeToHuffmanRepresentationTable(
41 HuffmanNode* node,
42 uint32_t bits,
43 uint32_t number_of_bits,
44 HuffmanRepresentationTable* table) {
45 if (node->IsLeaf()) {
46 HuffmanRepresentation item;
47 item.bits = bits;
48 item.number_of_bits = number_of_bits;
49
50 table->insert(HuffmanRepresentationPair(node->value(), item));
51 } else {
52 uint32_t new_bits = bits << 1;
53 TreeToHuffmanRepresentationTable(node->left().get(), new_bits,
54 number_of_bits + 1, table);
55 TreeToHuffmanRepresentationTable(node->right().get(), new_bits | 1,
56 number_of_bits + 1, table);
57 }
58 }
59
60 std::vector<uint8_t> HuffmanFrequencyTracker::AsVector() {
61 std::vector<uint8_t> bytes;
62 std::unique_ptr<HuffmanNode> node(BuildTree());
63 WriteToVector(node.get(), &bytes);
64 return bytes;
65 }
66
67 uint32_t HuffmanFrequencyTracker::WriteToVector(HuffmanNode* node,
68 std::vector<uint8_t>* vector) {
69 uint8_t left_value;
70 uint8_t right_value;
71 uint32_t child_position;
72
73 if (node->left()->IsLeaf()) {
74 left_value = 128 | node->left()->value();
75 } else {
76 child_position = WriteToVector(node->left().get(), vector);
77 CHECK(child_position < 512) << "huffman tree too large";
78 left_value = child_position / 2;
79 }
80
81 if (node->right()->IsLeaf()) {
82 right_value = 128 | node->right()->value();
83 } else {
84 child_position = WriteToVector(node->right().get(), vector);
85 CHECK(child_position < 512) << "huffman tree to large";
86 right_value = child_position / 2;
87 }
88
89 uint32_t position = vector->size();
90 vector->push_back(left_value);
91 vector->push_back(right_value);
92 return position;
93 }
94
95 std::unique_ptr<HuffmanNode> HuffmanFrequencyTracker::BuildTree() {
96 std::vector<std::unique_ptr<HuffmanNode>> nodes;
97 nodes.reserve(counts_.size());
98
99 for (const auto& item : counts_) {
100 if (item.second > 0) {
101 std::unique_ptr<HuffmanNode> node(
102 new HuffmanNode(item.first, item.second, nullptr, nullptr));
103 nodes.push_back(std::move(node));
104 }
105 }
106
107 if (nodes.size() < 2) {
108 return std::move(nodes[0]);
109 }
110
111 std::stable_sort(nodes.begin(), nodes.end(), CompareNodes);
112
113 while (nodes.size() > 1) {
114 std::unique_ptr<HuffmanNode> a = std::move(nodes[0]);
115 std::unique_ptr<HuffmanNode> b = std::move(nodes[1]);
116
117 std::unique_ptr<HuffmanNode> parent(new HuffmanNode(
118 0, a->count() + b->count(), std::move(a), std::move(b)));
119
120 nodes.erase(nodes.begin());
121 nodes[0] = std::move(parent);
122
123 std::stable_sort(nodes.begin(), nodes.end(), CompareNodes);
124 }
125
126 return std::move(nodes[0]);
127 }
128
129 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698