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

Side by Side Diff: cc/base/rtree.h

Issue 2591533002: cc: Change RTree nodes container to be a vector (with reserve). (Closed)
Patch Set: cont: update 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
« no previous file with comments | « no previous file | cc/base/rtree.cc » ('j') | cc/base/rtree.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CC_BASE_RTREE_H_ 5 #ifndef CC_BASE_RTREE_H_
6 #define CC_BASE_RTREE_H_ 6 #define CC_BASE_RTREE_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
11 #include <vector> 11 #include <vector>
12 12
13 #include "cc/base/cc_export.h" 13 #include "cc/base/cc_export.h"
14 #include "cc/base/contiguous_container.h"
15 #include "ui/gfx/geometry/rect.h" 14 #include "ui/gfx/geometry/rect.h"
16 15
17 namespace cc { 16 namespace cc {
18 17
19 // The following description and most of the implementation is borrowed from 18 // The following description and most of the implementation is borrowed from
20 // Skia's SkRTree implementation. 19 // Skia's SkRTree implementation.
21 // 20 //
22 // An R-Tree implementation. In short, it is a balanced n-ary tree containing a 21 // An R-Tree implementation. In short, it is a balanced n-ary tree containing a
23 // hierarchy of bounding rectangles. 22 // hierarchy of bounding rectangles.
24 // 23 //
(...skipping 29 matching lines...) Expand all
54 continue; 53 continue;
55 54
56 branches.push_back(Branch()); 55 branches.push_back(Branch());
57 Branch& branch = branches.back(); 56 Branch& branch = branches.back();
58 branch.bounds = bounds; 57 branch.bounds = bounds;
59 branch.index = i; 58 branch.index = i;
60 } 59 }
61 60
62 num_data_elements_ = branches.size(); 61 num_data_elements_ = branches.size();
63 if (num_data_elements_ == 1u) { 62 if (num_data_elements_ == 1u) {
63 nodes_.reserve(1);
64 Node* node = AllocateNodeAtLevel(0); 64 Node* node = AllocateNodeAtLevel(0);
65 node->num_children = 1; 65 node->num_children = 1;
66 node->children[0] = branches[0]; 66 node->children[0] = branches[0];
67 root_.subtree = node; 67 root_.subtree = node;
68 root_.bounds = branches[0].bounds; 68 root_.bounds = branches[0].bounds;
69 } else if (num_data_elements_ > 1u) { 69 } else if (num_data_elements_ > 1u) {
70 // Determine a reasonable upper bound on the number of nodes to prevent
71 // reallocations. This is basically (n**d - 1) / (n - 1), which is the
72 // number of nodes in a complete tree with n branches at each node. In the
73 // code n = |branch_count|, d = |depth|. However, we normally would have
74 // kMaxChildren branch factor, but that can be broken if some children
75 // don't have enough nodes. That can happen for at most kMinChildren nodes
76 // (since otherwise, we'd create a new node).
77 size_t branch_count = kMaxChildren;
78 double depth = log(branches.size()) / log(branch_count);
79 size_t node_count =
80 static_cast<size_t>((std::pow(branch_count, depth) - 1) /
81 (branch_count - 1)) +
82 kMinChildren;
danakj 2016/12/19 22:20:50 clang format why
vmpstr 2016/12/19 22:51:27 v_v
83 nodes_.reserve(node_count);
84
70 root_ = BuildRecursive(&branches, 0); 85 root_ = BuildRecursive(&branches, 0);
71 } 86 }
87 // We should've wasted at most kMinChildren nodes.
88 DCHECK_LE(nodes_.capacity() - nodes_.size(), kMinChildren);
72 } 89 }
73 90
74 template <typename Container> 91 template <typename Container>
75 void Build(const Container& items) { 92 void Build(const Container& items) {
76 Build(items, [](const gfx::Rect& bounds) { return bounds; }); 93 Build(items, [](const gfx::Rect& bounds) { return bounds; });
77 } 94 }
78 95
79 void Search(const gfx::Rect& query, std::vector<size_t>* results) const; 96 void Search(const gfx::Rect& query, std::vector<size_t>* results) const;
80 97
81 gfx::Rect GetBounds() const; 98 gfx::Rect GetBounds() const;
82 99
83 private: 100 private:
84 // These values were empirically determined to produce reasonable performance 101 // These values were empirically determined to produce reasonable performance
85 // in most cases. 102 // in most cases.
86 enum { MIN_CHILDREN = 6, MAX_CHILDREN = 11 }; 103 enum { kMinChildren = 6 };
104 enum { kMaxChildren = 11 };
87 105
88 struct Node; 106 struct Node;
89 struct Branch { 107 struct Branch {
90 // When the node level is 0, then the node is a leaf and the branch has a 108 // When the node level is 0, then the node is a leaf and the branch has a
91 // valid index pointing to an element in the vector that was used to build 109 // valid index pointing to an element in the vector that was used to build
92 // this rtree. When the level is not 0, it's an internal node and it has a 110 // this rtree. When the level is not 0, it's an internal node and it has a
93 // valid subtree pointer. 111 // valid subtree pointer.
94 union { 112 union {
95 Node* subtree; 113 Node* subtree;
96 size_t index; 114 size_t index;
97 }; 115 };
98 gfx::Rect bounds; 116 gfx::Rect bounds;
99 }; 117 };
100 118
101 struct Node { 119 struct Node {
102 uint16_t num_children; 120 uint16_t num_children;
103 uint16_t level; 121 uint16_t level;
104 Branch children[MAX_CHILDREN]; 122 Branch children[kMaxChildren];
105 }; 123 };
106 124
107 void SearchRecursive(Node* root, 125 void SearchRecursive(Node* root,
108 const gfx::Rect& query, 126 const gfx::Rect& query,
109 std::vector<size_t>* results) const; 127 std::vector<size_t>* results) const;
110 128
111 // Consumes the input array. 129 // Consumes the input array.
112 Branch BuildRecursive(std::vector<Branch>* branches, int level); 130 Branch BuildRecursive(std::vector<Branch>* branches, int level);
113 Node* AllocateNodeAtLevel(int level); 131 Node* AllocateNodeAtLevel(int level);
114 132
115 // This is the count of data elements (rather than total nodes in the tree) 133 // This is the count of data elements (rather than total nodes in the tree)
116 size_t num_data_elements_; 134 size_t num_data_elements_;
117 Branch root_; 135 Branch root_;
118 ContiguousContainer<Node> nodes_; 136 std::vector<Node> nodes_;
119 }; 137 };
120 138
121 } // namespace cc 139 } // namespace cc
122 140
123 #endif // CC_BASE_RTREE_H_ 141 #endif // CC_BASE_RTREE_H_
OLDNEW
« no previous file with comments | « no previous file | cc/base/rtree.cc » ('j') | cc/base/rtree.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698