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

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

Issue 2591533002: cc: Change RTree nodes container to be a vector (with reserve). (Closed)
Patch Set: compile fix 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') | no next file with comments »
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;
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(),
89 static_cast<size_t>(kMinChildren));
72 } 90 }
73 91
74 template <typename Container> 92 template <typename Container>
75 void Build(const Container& items) { 93 void Build(const Container& items) {
76 Build(items, [](const gfx::Rect& bounds) { return bounds; }); 94 Build(items, [](const gfx::Rect& bounds) { return bounds; });
77 } 95 }
78 96
79 void Search(const gfx::Rect& query, std::vector<size_t>* results) const; 97 void Search(const gfx::Rect& query, std::vector<size_t>* results) const;
80 98
81 gfx::Rect GetBounds() const; 99 gfx::Rect GetBounds() const;
82 100
83 private: 101 private:
84 // These values were empirically determined to produce reasonable performance 102 // These values were empirically determined to produce reasonable performance
85 // in most cases. 103 // in most cases.
86 enum { MIN_CHILDREN = 6, MAX_CHILDREN = 11 }; 104 enum { kMinChildren = 6 };
105 enum { kMaxChildren = 11 };
87 106
88 struct Node; 107 struct Node;
89 struct Branch { 108 struct Branch {
90 // When the node level is 0, then the node is a leaf and the branch has a 109 // 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 110 // 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 111 // this rtree. When the level is not 0, it's an internal node and it has a
93 // valid subtree pointer. 112 // valid subtree pointer.
94 union { 113 union {
95 Node* subtree; 114 Node* subtree;
96 size_t index; 115 size_t index;
97 }; 116 };
98 gfx::Rect bounds; 117 gfx::Rect bounds;
99 }; 118 };
100 119
101 struct Node { 120 struct Node {
102 uint16_t num_children; 121 uint16_t num_children;
103 uint16_t level; 122 uint16_t level;
104 Branch children[MAX_CHILDREN]; 123 Branch children[kMaxChildren];
105 }; 124 };
106 125
107 void SearchRecursive(Node* root, 126 void SearchRecursive(Node* root,
108 const gfx::Rect& query, 127 const gfx::Rect& query,
109 std::vector<size_t>* results) const; 128 std::vector<size_t>* results) const;
110 129
111 // Consumes the input array. 130 // Consumes the input array.
112 Branch BuildRecursive(std::vector<Branch>* branches, int level); 131 Branch BuildRecursive(std::vector<Branch>* branches, int level);
113 Node* AllocateNodeAtLevel(int level); 132 Node* AllocateNodeAtLevel(int level);
114 133
115 // This is the count of data elements (rather than total nodes in the tree) 134 // This is the count of data elements (rather than total nodes in the tree)
116 size_t num_data_elements_; 135 size_t num_data_elements_;
117 Branch root_; 136 Branch root_;
118 ContiguousContainer<Node> nodes_; 137 std::vector<Node> nodes_;
119 }; 138 };
120 139
121 } // namespace cc 140 } // namespace cc
122 141
123 #endif // CC_BASE_RTREE_H_ 142 #endif // CC_BASE_RTREE_H_
OLDNEW
« no previous file with comments | « no previous file | cc/base/rtree.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698