Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
GroupEnumerator.cs
1using System;
3using System.Threading.Tasks;
10
12{
17 {
18 private readonly ScriptNode[] groupBy;
19 private readonly ScriptNode[] groupNames;
20 private readonly bool[] groupByAsynchronous;
21 private readonly IIterativeEvaluator[] iterators;
22 private readonly bool[] iteratorUsesElement;
23 private readonly bool[] iteratorAsynchronous;
24 private readonly Variables variables;
25 private readonly IResultSetEnumerator e;
26 private readonly int iteratorCount;
27 private bool processLast = false;
28 private GroupObject current = null;
29 private ObjectProperties objectVariables = null;
30
41 ScriptNode[] GroupBy, ScriptNode[] GroupNames, ScriptNode[] Columns,
42 ref ScriptNode Having)
43 {
44 this.e = ItemEnumerator;
45 this.variables = Variables;
46 this.groupBy = GroupBy;
47 this.groupNames = GroupNames;
48
49 int i, c = GroupBy.Length;
50
51 this.groupByAsynchronous = new bool[c];
52
53 for (i = 0; i < c; i++)
54 this.groupByAsynchronous[i] = GroupBy[i].IsAsynchronous;
55
57
58 if (!(Columns is null))
59 {
60 for (i = 0, c = Columns.Length; i < c; i++)
61 GroupProcessor.FindIterators(ref Columns[i], Iterators);
62 }
63
64 GroupProcessor.FindIterators(ref Having, Iterators);
65
66 this.iterators = Iterators.ToArray();
67 this.iteratorCount = this.iterators.Length;
68
69 this.iteratorUsesElement = new bool[this.iteratorCount];
70 this.iteratorAsynchronous = new bool[this.iteratorCount];
71
72 for (i = 0; i < this.iteratorCount; i++)
73 {
74 this.iteratorUsesElement[i] = this.iterators[i].UsesElement;
75 this.iteratorAsynchronous[i] = this.iterators[i].IsAsynchronous;
76 }
77 }
78
82 public object Current => this.current;
83
87 public void Dispose()
88 {
89 this.e.Dispose();
90 }
91
95 public bool MoveNext()
96 {
97 return this.MoveNextAsync().Result;
98 }
99
106 public async Task<bool> MoveNextAsync()
107 {
108 IIterativeEvaluator Iterator;
109 IElement E;
110 object[] Last = null;
111 int i, j, c = this.groupBy.Length;
112 object o1, o2;
113 bool Found = false;
114
115 while (this.processLast || await this.e.MoveNextAsync())
116 {
117 this.processLast = false;
118
119 if (this.objectVariables is null)
120 this.objectVariables = new ObjectProperties(this.e.Current, this.variables);
121 else
122 this.objectVariables.Object = this.e.Current;
123
124 if (Last is null)
125 {
126 Last = new object[c];
127
128 for (i = 0; i < c; i++)
129 {
130 if (this.groupByAsynchronous[i])
131 E = await this.groupBy[i].EvaluateAsync(this.objectVariables);
132 else
133 E = this.groupBy[i].Evaluate(this.objectVariables);
134
135 Last[i] = E.AssociatedObjectValue;
136 }
137
138 if (this.iteratorCount > 0)
139 {
140 for (j = 0; j < this.iteratorCount; j++)
141 this.iterators[j].RestartEvaluator();
142 }
143 }
144 else
145 {
146 for (i = 0; i < c; i++)
147 {
148 if (this.groupByAsynchronous[i])
149 E = await this.groupBy[i].EvaluateAsync(this.objectVariables);
150 else
151 E = this.groupBy[i].Evaluate(this.objectVariables);
152
153 o1 = Last[i];
155
156 if (o1 is null ^ o2 is null)
157 break;
158
159 if (!(o1 is null) && !o1.Equals(o2))
160 break;
161 }
162
163 if (i < c)
164 {
165 this.processLast = true;
166 break;
167 }
168 }
169
170 if (this.iteratorCount > 0)
171 {
172 for (j = 0; j < this.iteratorCount; j++)
173 {
174 Iterator = this.iterators[j];
175
176 if (this.iteratorUsesElement[j])
177 {
178 if (this.iteratorAsynchronous[j])
179 E = await Iterator.EvaluateAsync(this.objectVariables);
180 else
181 E = Iterator.Evaluate(this.objectVariables);
182
183 Iterator.AggregateElement(E);
184 }
185 else
187 }
188 }
189
190 Found = true;
191 }
192
193 if (!Found)
194 return false;
195
196 IElement[] Aggregates = new IElement[this.iteratorCount];
197
198 for (i = 0; i < this.iteratorCount; i++)
199 {
200 Iterator = this.iterators[i];
201 Aggregates[i] = Iterator.GetAggregatedResult();
202 Iterator.RestartEvaluator();
203 }
204
205 this.current = new GroupObject(Last, Aggregates, this.groupNames, this.variables);
206
207 return true;
208 }
209
213 public void Reset()
214 {
215 this.e.Reset();
216 this.processLast = false;
217 this.current = null;
218 }
219 }
220}
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
T[] ToArray()
Returns an array containing all elements of the collection.
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
int Length
Length of expression covered by node.
Definition: ScriptNode.cs:101
static readonly ObjectValue Null
Null value.
Definition: ObjectValue.cs:88
Enumerator that groups items into groups, and returns aggregated elements.
async Task< bool > MoveNextAsync()
Advances the enumerator to the next element of the collection.
GroupEnumerator(IResultSetEnumerator ItemEnumerator, Variables Variables, ScriptNode[] GroupBy, ScriptNode[] GroupNames, ScriptNode[] Columns, ref ScriptNode Having)
Enumerator that groups items into groups, and returns aggregated elements.
Represents a collection of objects grouped together useing a GROUP BY construct.
Definition: GroupObject.cs:12
Processor that groups items into groups, and processes aggregated elements.
Collection of variables.
Definition: Variables.cs:25
Basic interface for all types of elements.
Definition: IElement.cs:21
object AssociatedObjectValue
Associated object value.
Definition: IElement.cs:34
An interative evaluator of a function supporting the IIterativeEvaluation interface.
IElement GetAggregatedResult()
Gets the aggregated result.
Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the evaluator, using the variables provided in the Variables collection and an object inst...
IElement Evaluate(Variables Variables)
Evaluates the evaluator, using the variables provided in the Variables collection and an object inst...
void AggregateElement(IElement Element)
Aggregates one new element.
void RestartEvaluator()
Restarts the evaluator.