Browse Source

[PLinq] Make QueryCheckerVisitor aware of Take query node.

QueryCheckerVisitor can then eventually decide if it's pertinent to run the query in parallel and set accordingly a boolean value (though not used by the engine at the moment).
Jérémie Laval 15 years ago
parent
commit
5d41d6b47f

+ 1 - 0
mcs/class/System.Core/System.Linq.Parallel/INodeVisitor.cs

@@ -39,6 +39,7 @@ namespace System.Linq.Parallel
 		void Visit<T, TParent> (QueryStreamNode<T, TParent> node);
 		void Visit<T> (QueryOrderGuardNode<T> node);
 		void Visit<TFirst, TSecond, TResult> (QueryMuxNode<TFirst, TSecond, TResult> node);
+		void Visit<T> (QueryHeadWorkerNode<T> node);
 	}
 }
 #endif

+ 19 - 8
mcs/class/System.Core/System.Linq.Parallel/QueryCheckerVisitor.cs

@@ -40,7 +40,6 @@ namespace System.Linq.Parallel
 		ParallelExecutionMode? mode = null;
 		CancellationToken? token = null;
 		int? degreeOfParallelism = null;
-		bool useStrip;
 		CancellationToken implementerToken = CancellationToken.None;
 
 		int partitionCount;
@@ -55,7 +54,7 @@ namespace System.Linq.Parallel
 		public void Visit<T> (QueryBaseNode<T> node)
 		{
 			// Nothing to do atm. Later we can check if the node is a
-			// Take or a Skip and set accordingly useStrip
+			// Take or a Skip and set accordingly UseStrip
 		}
 
 		public void Visit<U, V> (QueryChildNode<U, V> node)
@@ -81,7 +80,7 @@ namespace System.Linq.Parallel
 		public void Visit<T, TParent> (QueryStreamNode<T, TParent> node)
 		{
 			if (node.IsIndexed)
-				useStrip = true;
+				UseStrip = true;
 
 			Visit<T, TParent> ((QueryChildNode<T, TParent>)node);
 		}
@@ -91,7 +90,7 @@ namespace System.Linq.Parallel
 			if (behindOrderGuard == null) {
 				if (node.EnsureOrder) {
 					behindOrderGuard = true;
-					//useStrip = true;
+					//UseStrip = true;
 				} else {
 					behindOrderGuard = false;
 				}
@@ -105,19 +104,26 @@ namespace System.Linq.Parallel
 			Visit<TResult, TFirst> ((QueryChildNode<TResult, TFirst>)node);
 		}
 
+		public void Visit<T> (QueryHeadWorkerNode<T> node)
+		{
+			// Wouldn't it be better with standard Linq?
+			if (node.Count.HasValue && node.Count < partitionCount)
+				ShouldBeSequential = true;
+
+			Visit<T, T> ((QueryStreamNode<T, T>)node);
+		}
 		#endregion
 
 		internal QueryOptions Options {
 			get {
 				return new QueryOptions (options, mode, token == null ? CancellationToken.None : token.Value,
-				                         useStrip, behindOrderGuard, partitionCount, implementerToken);
+				                         UseStrip, behindOrderGuard, partitionCount, implementerToken);
 			}
 		}
 
 		internal bool UseStrip {
-			get {
-				return useStrip;
-			}
+			get;
+			private set;
 		}
 
 		internal bool BehindOrderGuard {
@@ -126,6 +132,11 @@ namespace System.Linq.Parallel
 			}
 		}
 
+		internal bool ShouldBeSequential {
+			get;
+			private set;
+		}
+
 		void MergeOptions (OptionsList list)
 		{
 			if (list.Item1 != null) {