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

Side by Side Diff: src/core/SkTTopoSort.h

Issue 1414503003: Add SkTTopoSort (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: clean up Created 5 years, 2 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 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #ifndef SkTTopoSort_DEFINED
9 #define SkTTopoSort_DEFINED
10
11 #include "SkTDArray.h"
12
13 #ifdef SK_DEBUG
14 template <typename T, typename Traits = T>
15 void SkTTopoSort_CheckAllUnmarked(const SkTDArray<T*>& graph) {
16 for (int i = 0; i < graph.count(); ++i) {
17 SkASSERT(!Traits::IsTempMarked(graph[i]));
18 SkASSERT(!Traits::WasOutput(graph[i]));
19 }
20 }
21
22 template <typename T, typename Traits = T>
23 void SkTTopoSort_CleanExit(const SkTDArray<T*>& graph) {
24 for (int i = 0; i < graph.count(); ++i) {
25 SkASSERT(!Traits::IsTempMarked(graph[i]));
26 SkASSERT(Traits::WasOutput(graph[i]));
27 }
28 }
29 #endif
30
31 // Recursively visit a node and all the other nodes it depends on.
32 // Return false if there is a loop.
33 template <typename T, typename Traits = T>
34 bool SkTTopoSort_Visit(T* node, SkTDArray<T*>* result) {
35 if (Traits::IsTempMarked(node)) {
36 // There is a loop.
37 return false;
38 }
39
40 // If the node under consideration has been already been output it means it
41 // (and all the nodes it depends on) are already in 'result'.
42 if (!Traits::WasOutput(node)) {
43 // This node hasn't been output yet. Recursively assess all the
44 // nodes it depends on outputing them first.
45 Traits::SetTempMark(node);
46 for (int i = 0; i < Traits::NumDependencies(node); ++i) {
47 if (!SkTTopoSort_Visit<T, Traits>(Traits::Dependency(node, i), resul t)) {
48 return false;
49 }
50 }
51 Traits::Output(node, result->count()); // mark this node as output
52 Traits::ResetTempMark(node);
53
54 *result->append() = node;
55 }
56
57 return true;
58 }
59
60 // Topologically sort the nodes in 'graph'. For this sort, when node 'i' depends
61 // on node 'j' it means node 'j' must appear in the result before node 'i'.
62 // A false return value means there was a loop and the contents of 'graph' will
63 // be in some arbitrary state.
64 template <typename T, typename Traits = T>
bsalomon 2015/10/19 14:19:13 Maybe comment about what signatures are required o
robertphillips 2015/10/19 16:21:07 Done.
65 bool SkTTopoSort(SkTDArray<T*>* graph) {
bsalomon 2015/10/19 14:19:13 Wondering in consideration of GrDT graph if the gr
robertphillips 2015/10/19 16:21:07 Interesting. I think we could just call SkTTopoSor
66 SkTDArray<T*> result;
67
68 #ifdef SK_DEBUG
69 SkTTopoSort_CheckAllUnmarked<T, Traits>(*graph);
70 #endif
71
72 result.setReserve(graph->count());
73
74 for (int i = 0; i < graph->count(); ++i) {
75 if (Traits::WasOutput((*graph)[i])) {
76 // This node was depended on by some earlier node and has already
77 // been output
78 continue;
79 }
80
81 // Output this node after all the nodes it depends on have been output.
82 if (!SkTTopoSort_Visit<T, Traits>((*graph)[i], &result)) {
83 return false;
84 }
85 }
86
87 SkASSERT(graph->count() == result.count());
88 graph->swap(result);
89
90 #ifdef SK_DEBUG
91 SkTTopoSort_CleanExit<T, Traits>(*graph);
92 #endif
93 return true;
94 }
95
96 #endif
OLDNEW
« no previous file with comments | « gyp/core.gypi ('k') | tests/TopoSortTest.cpp » ('j') | tests/TopoSortTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698