99using System . Threading ;
1010using System . Threading . Tasks ;
1111using ShardingCore . Core ;
12+ using ShardingCore . Core . VirtualRoutes . TableRoutes . RoutingRuleEngine ;
1213using ShardingCore . Sharding . MergeEngines . Common ;
14+ using ShardingCore . Sharding . MergeEngines . Common . Abstractions ;
1315using ShardingCore . Sharding . StreamMergeEngines ;
1416
1517namespace ShardingCore . Sharding . MergeEngines . Abstractions
@@ -66,62 +68,16 @@ internal abstract class AbstractBaseMergeEngine<TEntity>
6668
6769 //}
6870
69- public Task < LinkedList < TResult2 > > [ ] GetDataSourceGroupAndExecutorGroup < TResult , TResult2 > ( Func < SqlExecutorUnit , Task < TResult2 > > sqlExecutorUnitExecuteAsync , CancellationToken cancellationToken = new CancellationToken ( ) )
71+ public Task < LinkedList < TResult > > [ ] GetDataSourceGroupAndExecutorGroup < TResult > ( IEnumerable < ISqlRouteUnit > sqlRouteUnits , Func < SqlExecutorUnit , Task < TResult > > sqlExecutorUnitExecuteAsync , CancellationToken cancellationToken = new CancellationToken ( ) )
7072 {
71- var streamMergeContext = GetStreamMergeContext ( ) ;
72- var maxQueryConnectionsLimit = streamMergeContext . GetMaxQueryConnectionsLimit ( ) ;
73-
74- var waitTaskQueue = streamMergeContext . DataSourceRouteResult . IntersectDataSources . SelectMany (
75- dataSourceName =>
76- {
77- return streamMergeContext . TableRouteResults . Select ( routeResult =>
78- new SqlRouteUnit ( dataSourceName , routeResult ) ) ;
79- } ) . GroupBy ( o => o . DataSourceName ) . Select ( sqlGroups =>
80- {
81- var sqlCount = sqlGroups . Count ( ) ;
82- //根据用户配置单次查询期望并发数
83- int exceptCount =
84- Math . Max (
85- 0 == sqlCount % maxQueryConnectionsLimit
86- ? sqlCount / maxQueryConnectionsLimit
87- : sqlCount / maxQueryConnectionsLimit + 1 , 1 ) ;
88- //计算应该使用那种链接模式
89- ConnectionModeEnum connectionMode = CalcConnectionMode ( streamMergeContext . GetConnectionMode ( ) ,
90- streamMergeContext . GetUseMemoryLimitWhileSkip ( ) , maxQueryConnectionsLimit , sqlCount ,
91- streamMergeContext . Skip ) ;
92- var sqlExecutorUnitPartitions = sqlGroups
93- . Select ( ( o , i ) => new { Obj = o , index = i % exceptCount } ) . GroupBy ( o => o . index )
94- . Select ( o => o . Select ( g => new SqlExecutorUnit ( connectionMode , g . Obj ) ) . ToList ( ) ) . ToList ( ) ;
95- return sqlExecutorUnitPartitions . Select ( o => new SqlExecutorGroup < SqlExecutorUnit > ( o ) ) . ToList ( ) ;
96- } ) . Select ( executorGroups =>
73+ var waitTaskQueue = AggregateQueryByDataSourceName ( sqlRouteUnits ) . Select ( GetSqlExecutorGroups ) . Select ( executorGroups =>
9774 {
9875 return Task . Run ( async ( ) =>
9976 {
100- LinkedList < TResult2 > result = new LinkedList < TResult2 > ( ) ;
77+ LinkedList < TResult > result = new LinkedList < TResult > ( ) ;
10178 foreach ( var executorGroup in executorGroups )
10279 {
103- var executorGroupParallelExecuteTasks = executorGroup . Groups . Select ( executor =>
104- {
105- return Task . Run ( async ( ) =>
106- {
107- return await sqlExecutorUnitExecuteAsync ( executor ) ;
108- //var dataSourceName = executor.RouteUnit.DataSourceName;
109- //var routeResult = executor.RouteUnit.TableRouteResult;
110-
111- //var asyncExecuteQueryable =
112- // CreateAsyncExecuteQueryable<TResult>(dataSourceName, routeResult);
113-
114-
115- //var queryResult = await efQuery(asyncExecuteQueryable);
116-
117- //return new RouteQueryResult<TResult>(dataSourceName, routeResult, queryResult);
118- //return await AsyncParallelResultExecute(asyncExecuteQueryable, dataSourceName,
119- // routeResult, efQuery,
120- // cancellationToken);
121-
122- } , cancellationToken ) ;
123- } ) . ToArray ( ) ;
124- var routeQueryResults = ( await Task . WhenAll ( executorGroupParallelExecuteTasks ) ) . ToList ( ) ;
80+ var routeQueryResults = await ExecuteAsync < TResult > ( executorGroup . Groups , sqlExecutorUnitExecuteAsync , cancellationToken ) ;
12581 foreach ( var routeQueryResult in routeQueryResults )
12682 {
12783 result . AddLast ( routeQueryResult ) ;
@@ -134,25 +90,78 @@ public Task<LinkedList<TResult2>>[] GetDataSourceGroupAndExecutorGroup<TResult,T
13490 return waitTaskQueue ;
13591 }
13692
93+ protected virtual IEnumerable < ISqlRouteUnit > GetDefaultSqlRouteUnits ( )
94+ {
95+
96+ var streamMergeContext = GetStreamMergeContext ( ) ;
97+
98+ return streamMergeContext . DataSourceRouteResult . IntersectDataSources . SelectMany (
99+ dataSourceName =>
100+ {
101+ return streamMergeContext . TableRouteResults . Select ( routeResult =>
102+ new SqlRouteUnit ( dataSourceName , routeResult ) ) ;
103+ } ) ;
104+ }
105+ protected virtual IEnumerable < IGrouping < string , ISqlRouteUnit > > AggregateQueryByDataSourceName ( IEnumerable < ISqlRouteUnit > sqlRouteUnits )
106+ {
107+ return sqlRouteUnits . GroupBy ( o => o . DataSourceName ) ;
108+ }
137109
110+ protected List < SqlExecutorGroup < SqlExecutorUnit > > GetSqlExecutorGroups ( IGrouping < string , ISqlRouteUnit > sqlGroups )
111+ {
112+ var streamMergeContext = GetStreamMergeContext ( ) ;
113+ var maxQueryConnectionsLimit = streamMergeContext . GetMaxQueryConnectionsLimit ( ) ;
114+ var sqlCount = sqlGroups . Count ( ) ;
115+ //根据用户配置单次查询期望并发数
116+ int exceptCount =
117+ Math . Max (
118+ 0 == sqlCount % maxQueryConnectionsLimit
119+ ? sqlCount / maxQueryConnectionsLimit
120+ : sqlCount / maxQueryConnectionsLimit + 1 , 1 ) ;
121+ //计算应该使用那种链接模式
122+ ConnectionModeEnum connectionMode = streamMergeContext . GetConnectionMode ( sqlCount ) ;
123+ var sqlExecutorUnitPartitions = sqlGroups
124+ . Select ( ( o , i ) => new { Obj = o , index = i % exceptCount } ) . GroupBy ( o => o . index )
125+ . Select ( o => o . Select ( g => new SqlExecutorUnit ( connectionMode , g . Obj ) ) . ToList ( ) ) . ToList ( ) ;
126+ return sqlExecutorUnitPartitions . Select ( o => new SqlExecutorGroup < SqlExecutorUnit > ( o ) ) . ToList ( ) ;
127+ }
138128
139- protected ConnectionModeEnum CalcConnectionMode ( ConnectionModeEnum currentConnectionMode , int useMemoryLimitWhileSkip , int maxQueryConnectionsLimit , int sqlCount , int ? skip )
129+ protected async Task < LinkedList < TResult > > ExecuteAsync < TResult > ( List < SqlExecutorUnit > sqlExecutorUnits , Func < SqlExecutorUnit , Task < TResult > > sqlExecutorUnitExecuteAsync , CancellationToken cancellationToken = new CancellationToken ( ) )
140130 {
141- switch ( currentConnectionMode )
131+ if ( sqlExecutorUnits . Count <= 0 )
132+ {
133+ return new LinkedList < TResult > ( ) ;
134+ }
135+ else
142136 {
143- case ConnectionModeEnum . STREAM_MERGE :
144- case ConnectionModeEnum . IN_MEMORY_MERGE : return currentConnectionMode ;
145- default :
137+ var result = new LinkedList < TResult > ( ) ;
138+ Task < TResult > [ ] tasks = null ;
139+ if ( sqlExecutorUnits . Count > 1 )
146140 {
147- if ( skip . HasValue && skip . Value > useMemoryLimitWhileSkip )
141+ tasks = sqlExecutorUnits . Skip ( 1 ) . Select ( sqlExecutorUnit =>
148142 {
149- return ConnectionModeEnum . STREAM_MERGE ;
150- }
151- return maxQueryConnectionsLimit < sqlCount
152- ? ConnectionModeEnum . IN_MEMORY_MERGE
153- : ConnectionModeEnum . STREAM_MERGE ; ;
143+ return Task . Run ( async ( ) =>
144+ {
145+ return await sqlExecutorUnitExecuteAsync ( sqlExecutorUnit ) ;
146+
147+ } , cancellationToken ) ;
148+ } ) . ToArray ( ) ;
149+ }
150+ else
151+ {
152+ tasks = Array . Empty < Task < TResult > > ( ) ;
153+ }
154+ var firstResult = await sqlExecutorUnitExecuteAsync ( sqlExecutorUnits [ 0 ] ) ;
155+ result . AddLast ( firstResult ) ;
156+ var otherResults = await Task . WhenAll ( tasks ) ;
157+ foreach ( var otherResult in otherResults )
158+ {
159+ result . AddLast ( otherResult ) ;
154160 }
161+
162+ return result ;
155163 }
164+
156165 }
157166 }
158167}
0 commit comments