summaryrefslogtreecommitdiff
path: root/src/TFunction/TFunction_Iterator.cxx
blob: 2e6c990df5ec68caa0e350ebc26b3c91062a04a8 (plain)
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
// File:	TFunction_Iterator.cxx
// Created:	Mon Jun 23 13:56:35 2008
// Author:	Vladislav ROMASHKO
//		<vladislav.romashko@opencascade.com>


#include <TFunction_Iterator.ixx>
#include <TFunction_IFunction.hxx>
#include <TFunction_GraphNode.hxx>
#include <TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel.hxx>

#include <TDF_LabelMap.hxx>
#include <TDF_MapIteratorOfLabelMap.hxx>
#include <TDF_ListIteratorOfLabelList.hxx>
#include <TDF_LabelIntegerMap.hxx>
#include <TDF_DataMapIteratorOfLabelIntegerMap.hxx>

#include <TDataStd_Name.hxx>

#include <TColStd_MapIteratorOfMapOfInteger.hxx>

//=======================================================================
//function : Create
//purpose  : Constructor
//=======================================================================

TFunction_Iterator::TFunction_Iterator():myUsageOfExecutionStatus(Standard_False)
{  

}

//=======================================================================
//function : Create
//purpose  : Constructor
//=======================================================================

TFunction_Iterator::TFunction_Iterator(const TDF_Label& Access):myUsageOfExecutionStatus(Standard_False)
{
  Init(Access);
}

//=======================================================================
//function : Init
//purpose  : Initializes the Iterator.
//=======================================================================

void TFunction_Iterator::Init(const TDF_Label& Access)
{
  myCurrent.Clear();
  myPassedFunctions.Clear();

  // Get the scope of functions
  myScope = TFunction_Scope::Set(Access);

  // Find the roots
  TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrm(myScope->GetFunctions());
  for (; itrm.More(); itrm.Next())
  {
    const TDF_Label& L = itrm.Key2();

    TFunction_IFunction iFunction(L);
    Handle(TFunction_GraphNode) graphNode = iFunction.GetGraphNode();
    TFunction_ExecutionStatus status = graphNode->GetStatus();

    // Check whether the function is a root function
    if (!graphNode->GetPrevious().IsEmpty())
      continue;

    // In execution mode we consider only "not executed" functions.
    if (myUsageOfExecutionStatus && status != TFunction_ES_NotExecuted)
      continue;

    myCurrent.Append(L);

    // Register already passed functions
    if (!myUsageOfExecutionStatus)
      myPassedFunctions.Add(L);
  }
}

//=======================================================================
//function : SetUsageOfExecutionStatus
//purpose  : Defines usage of execution status
//=======================================================================

void TFunction_Iterator::SetUsageOfExecutionStatus(const Standard_Boolean usage)
{
  myUsageOfExecutionStatus = usage;
}

//=======================================================================
//function : GetUsageOfExecutionStatus
//purpose  : Returns usage of execution status
//=======================================================================

Standard_Boolean TFunction_Iterator::GetUsageOfExecutionStatus() const
{
  return myUsageOfExecutionStatus;
}

//=======================================================================
//function : GetMaxNbThreads
//purpose  : Defines the maximum number of threads
//=======================================================================

Standard_Integer TFunction_Iterator::GetMaxNbThreads() const
{
  int nb_threads = 0;
  TFunction_Iterator fIterator;
  fIterator.myUsageOfExecutionStatus = Standard_False;

  // Start iteration from current functions
  TDF_ListIteratorOfLabelList itrl(myCurrent);
  for (; itrl.More(); itrl.Next())
  {
    fIterator.myCurrent.Append(itrl.Value());
  }

  // Check number of semultenious current functions
  while (!fIterator.Current().IsEmpty())
  {
    const TDF_LabelList& current = fIterator.Current();
    if (nb_threads < current.Extent())
      nb_threads = current.Extent();
    fIterator.Next();
  }

  return nb_threads;
}

//=======================================================================
//function : Current
//purpose  : Returns the current list of functions
//=======================================================================

const TDF_LabelList& TFunction_Iterator::Current() const
{
  return myCurrent;
}

//=======================================================================
//function : More
//purpose  : Returns true if the iteration is ended
//=======================================================================

Standard_Boolean TFunction_Iterator::More() const
{
  if (myUsageOfExecutionStatus)
  {
    TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrm(myScope->GetFunctions());
    for (; itrm.More(); itrm.Next())
    {
      const TDF_Label& L = itrm.Key2();
      if (GetStatus(L) == TFunction_ES_NotExecuted)
	return Standard_True;
    }
    return Standard_False;
  }
  return myPassedFunctions.Extent() < myScope->GetFunctions().Extent();
}

//=======================================================================
//function : Next
//purpose  : Switches the iterator to the next functions
//=======================================================================

void TFunction_Iterator::Next()
{
  TDF_LabelMap next_current;
  TDF_ListIteratorOfLabelList itrl(myCurrent);
  for (; itrl.More(); itrl.Next())
  {
    const TDF_Label& L = itrl.Value();
    TFunction_IFunction iFunction(L);

    Handle(TFunction_GraphNode) graphNode = iFunction.GetGraphNode();
    const TColStd_MapOfInteger& next      = graphNode->GetNext();
    TFunction_ExecutionStatus   status    = graphNode->GetStatus();

    // Consider the execution status
    if (myUsageOfExecutionStatus)
    {
      if (status == TFunction_ES_NotExecuted || status == TFunction_ES_Executing)
      {
	next_current.Add(L);
	continue;
      }
      else if (status == TFunction_ES_WrongDefinition || status == TFunction_ES_Failed)
      {
	continue;
      }

      // if "succeeded", we consider the next functions... see below.
    }

    // Add next functions
    TColStd_MapIteratorOfMapOfInteger itrm(next);
    for (; itrm.More(); itrm.Next())
    {
      const Standard_Integer IDnext = itrm.Key();
      const TDF_Label& Lnext = myScope->GetFunctions().Find1(IDnext);

      if (myUsageOfExecutionStatus)
      {
	// A previous function is "succeeded", check status of next functions and 
	// all other previous functions of the next functions.

	// Check status, it should be "not executed"
	TFunction_IFunction iNextFunction(Lnext);
	Handle(TFunction_GraphNode) nextGraphNode = iNextFunction.GetGraphNode();
	TFunction_ExecutionStatus next_status = nextGraphNode->GetStatus();
	if (next_status != TFunction_ES_NotExecuted && next_status != TFunction_ES_Executing)
	{
	  continue;
	}

	// Check all previous functions: all of them should be "succeeded"
	Standard_Boolean is_prev_succeeded = Standard_True;
	const TColStd_MapOfInteger& prevOfNext = nextGraphNode->GetPrevious();
	TColStd_MapIteratorOfMapOfInteger itrp(prevOfNext);
	for (; itrp.More(); itrp.Next())
	{
	  const Standard_Integer IDprevOfNext = itrp.Key();
	  const TDF_Label& LprevOfNext = myScope->GetFunctions().Find1(IDprevOfNext);
	  Handle(TFunction_GraphNode) GprevOfNext;
	  LprevOfNext.FindAttribute(TFunction_GraphNode::GetID(), GprevOfNext);
	  TFunction_ExecutionStatus prev_status = GprevOfNext->GetStatus();
	  if (prev_status != TFunction_ES_Succeeded)
	  {
	    is_prev_succeeded = Standard_False;
	    break;
	  }
	}
	if (!is_prev_succeeded)
	{
	  continue;
	}
      }

      // Ignore already passed fucntions (for the mode of ignoring the execution status).
      if (!myUsageOfExecutionStatus && myPassedFunctions.Contains(Lnext))
	continue;

      next_current.Add(Lnext);

      // Register already passed functions
      if (!myUsageOfExecutionStatus)
	myPassedFunctions.Add(Lnext);
    }
  }

  myCurrent.Clear();
  TDF_MapIteratorOfLabelMap itrm(next_current);
  for (; itrm.More(); itrm.Next())
  {
    myCurrent.Append(itrm.Key());
  }
}

//=======================================================================
//function : GetStatus
//purpose  : Returns the execution status of the function
//=======================================================================

TFunction_ExecutionStatus TFunction_Iterator::GetStatus(const TDF_Label& func) const
{
  TFunction_IFunction iFunction(func);
  return iFunction.GetGraphNode()->GetStatus();
}

//=======================================================================
//function : SetStatus
//purpose  : Defines an execution status for a function
//=======================================================================

void TFunction_Iterator::SetStatus(const TDF_Label& func,
				   const TFunction_ExecutionStatus status) const
{
  TFunction_IFunction iFunction(func);
  iFunction.GetGraphNode()->SetStatus(status);
}

//=======================================================================
//function : Dump
//purpose  : 
//=======================================================================
Standard_OStream& TFunction_Iterator::Dump (Standard_OStream& anOS) const
{  
  anOS << "Functions:" << endl ;

  if (myCurrent.IsEmpty())
    return anOS;

  // Memorize the status of each function
  // in order to recover it after iteration.
  TDF_LabelIntegerMap saved_status;
  Handle(TFunction_Scope) scope = TFunction_Scope::Set(myCurrent.First());
  TFunction_DoubleMapIteratorOfDoubleMapOfIntegerLabel itrd(scope->GetFunctions());
  for (; itrd.More(); itrd.Next())
  {
    const TDF_Label& L = itrd.Key2();
    Handle(TFunction_GraphNode) G;
    if (L.FindAttribute(TFunction_GraphNode::GetID(), G))
    {
      saved_status.Bind(L, (Standard_Integer) G->GetStatus());
      G->SetStatus(TFunction_ES_NotExecuted);
    }
  }

  TFunction_Iterator fIterator(myCurrent.First());
  fIterator.myUsageOfExecutionStatus = Standard_True;

  while (fIterator.More())
  {
    const TDF_LabelList& current = fIterator.Current();

    TDF_ListIteratorOfLabelList itrl(current);
    for (; itrl.More(); itrl.Next())
    {

      const TDF_Label& L = itrl.Value();

      Handle(TDataStd_Name) N;
      if (L.FindAttribute(TDataStd_Name::GetID(), N))
      {
	anOS << TCollection_AsciiString(N->Get()).ToCString() ;
      }

      Handle(TFunction_GraphNode) G;
      if (L.FindAttribute(TFunction_GraphNode::GetID(), G))
      {
	G->SetStatus(TFunction_ES_Succeeded);
      }

      anOS << "\t" ;
    }

    fIterator.Next();
    
    anOS << endl;
  }

  // Recover the status of functions
  TDF_DataMapIteratorOfLabelIntegerMap itrm(saved_status);
  for (; itrm.More(); itrm.Next())
  {
    const TDF_Label& L = itrm.Key();
    TFunction_ExecutionStatus status = (TFunction_ExecutionStatus) itrm.Value();
    
    Handle(TFunction_GraphNode) G;
    if (L.FindAttribute(TFunction_GraphNode::GetID(), G))
    {
      G->SetStatus(status);
    }
  }

  return anOS;
}