-
Notifications
You must be signed in to change notification settings - Fork 28
/
TreeWalk.h
152 lines (132 loc) · 5.32 KB
/
TreeWalk.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#ifndef __TREEWALK_H__
#define __TREEWALK_H__
#include "codes.h"
class State;
class Compute;
class TreePiece;
/// @brief Base class for walking trees
class TreeWalk{
protected:
Compute *comp;
TreePiece *ownerTP;
WalkType type;
#ifdef BENCHMARK_TIME_WALK
double walkTime, keepTime, finishNodeTime, doWorkTime;
#endif
TreeWalk(Compute *_comp, TreePiece *tp, WalkType _type): ownerTP(tp), comp(_comp), type(_type){
#ifdef BENCHMARK_TIME_WALK
walkTime = keepTime = finishNodeTime = doWorkTime = 0.0;
#endif
}
TreeWalk() : comp(NULL), ownerTP(NULL), type(InvalidWalk){
#ifdef BENCHMARK_TIME_WALK
walkTime = keepTime = finishNodeTime = doWorkTime = 0.0;
#endif
}
TreeWalk(WalkType t) : comp(NULL), ownerTP(NULL), type(t){
#ifdef BENCHMARK_TIME_WALK
walkTime = keepTime = finishNodeTime = doWorkTime = 0.0;
#endif
}
public:
virtual ~TreeWalk() {
#ifdef BENCHMARK_TIME_WALK
CkPrintf("walk,keep,finishNode,doWork time: %lf %lf %lf %lf\n",walkTime,keepTime,finishNodeTime,doWorkTime);
#endif
}
// must tell compute the ownerTP so it can perform its openCriterion() test
TreePiece *getOwnerTP(){return ownerTP;}
Compute *getCompute(){return comp;}
/// @brief Associate a compute object and a treepiece with this walk.
virtual void init(Compute *c, TreePiece *owner);
void reassoc(Compute *c);
virtual void reset() {};
virtual void walk(GenericTreeNode *node, State *state, int chunk, int reqID, int activeWalkIndex) = 0;
// when resuming a walk after a missed node is received, use this function
virtual void resumeWalk(GenericTreeNode *node, State *state, int chunk, int reqID, int activeWalkIndex) {
walk(node, state, chunk, reqID, activeWalkIndex);
}
// beware of using default implementation - always returns 'false'
//virtual bool ancestorCheck(GenericTreeNode *node, int reqID) {return false;};
WalkType getSelfType() {return type;}
};
/// @brief Walk a tree starting with the root node.
class TopDownTreeWalk : public TreeWalk{
private:
#ifndef CHANGA_REFACTOR_WALKCHECK
void dft(GenericTreeNode *node, State *state, int chunk, int reqID, bool isRoot, int awi);
void bft(GenericTreeNode *node, State *state, int chunk, int reqID, bool isRoot, int awi);
#else
void dft(GenericTreeNode *node, State *state, int chunk, int reqID, bool isRoot, int shift, bool doprint);
#endif
public:
TopDownTreeWalk(Compute *_comp, TreePiece *tp):TreeWalk(_comp,tp,TopDown){}
TopDownTreeWalk() : TreeWalk(TopDown) {}
//bool ancestorCheck(GenericTreeNode *node, int reqID);
void walk(GenericTreeNode *node, State *state, int chunk, int reqID, int awi);
};
/// Walk a tree starting with a leaf node and working up the tree.
/// This class is used for the k-th nearest neighbor search (Smooth).
class BottomUpTreeWalk : public TreeWalk{
public:
BottomUpTreeWalk(Compute *_comp, TreePiece *tp):TreeWalk(_comp,tp,BottomUp){}
BottomUpTreeWalk() : TreeWalk(BottomUp) {}
void walk(GenericTreeNode *node, State *state, int chunk, int reqID, int awi);
};
#if INTERLIST_VER > 0
/// Traverses local tree instead of global one.
/// Heads towards a target local bucket until told to DUMP.
/// The class is used in the local tree part of the
/// double (interaction list) walk.
/// It is given a new target node and a DoubleWalkState object
/// whose checklists and undecidedlists it uses while walking
/// down toward the new target node.
/// When it returns, the walk function will have modified
/// the state object to reflect what the next target bucket
/// should be.
class LocalTargetWalk : public TreeWalk {
NodeKey targetKey;
private:
/// @brief Depth First TreeWalk
/// @param localNode Node to work on.
/// @param state DoubleWalkState containing check lists.
/// @param chunk Chunk of remote tree we are working on.
/// @param reqID Target bucket index
/// @param isRoot Is localNode the root.
/// @param awi Active Walk Index.
/// @param level Level in the tree.
void dft(GenericTreeNode *localNode, State *state, int chunk, int reqID,
bool isRoot, int awi, int level);
/// @brief process a node from the check list
/// @brief glblNode Source node to be checked.
bool processNode(
GenericTreeNode *glblNode,
State *state,
int chunk, int reqID,
bool isRoot, bool &didcomp,
int awi);
public:
LocalTargetWalk(Compute *_comp, TreePiece *tp):TreeWalk(_comp,tp,LocalTarget){}
LocalTargetWalk() : TreeWalk(LocalTarget) { targetKey = 0;}
void walk(GenericTreeNode *startAncestor, State *state, int chunk, int reqID, int awi);
void resumeWalk(GenericTreeNode *node, State *state, int chunk, int reqID, int activeWalkIndex);
NodeKey getTargetKey() {return targetKey;}
};
#endif
/// @brief class to walk just the local treepiece.
class LocalTreeTraversal {
public:
/// Depth First Treewalk.
/// @param node Node on which we are working.
/// @param worker Describes work to be done on each node.
/// @param level Level of the tree we are on.
void dft(GenericTreeNode *node, TreeNodeWorker *worker, int level){
if(worker->work(node,level)){
for(int i = 0; i < node->numChildren(); i++){
dft(node->getChildren(i),worker,level+1);
}
if(node->numChildren() > 0) worker->doneChildren(node,level);
}
}
};
#endif