1515import  tech .ydb .core .Result ;
1616import  tech .ydb .core .Status ;
1717import  tech .ydb .core .StatusCode ;
18+ import  tech .ydb .core .grpc .GrpcReadStream ;
1819import  tech .ydb .proto .ValueProtos ;
1920import  tech .ydb .table .Session ;
2021import  tech .ydb .table .query .DataQueryResult ;
2526import  tech .ydb .table .query .stats .QueryStats ;
2627import  tech .ydb .table .query .stats .QueryStatsCollectionMode ;
2728import  tech .ydb .table .query .stats .TableAccessStats ;
29+ import  tech .ydb .table .query .ReadTablePart ;
2830import  tech .ydb .table .result .ResultSetReader ;
2931import  tech .ydb .table .settings .BulkUpsertSettings ;
3032import  tech .ydb .table .settings .CommitTxSettings ;
7072import  tech .ydb .yoj .repository .ydb .exception .YdbRepositoryException ;
7173import  tech .ydb .yoj .repository .ydb .merge .QueriesMerger ;
7274import  tech .ydb .yoj .repository .ydb .readtable .ReadTableMapper ;
75+ import  tech .ydb .yoj .repository .ydb .spliterator .ClosableSpliterator ;
76+ import  tech .ydb .yoj .repository .ydb .spliterator .ResultSetIterator ;
77+ import  tech .ydb .yoj .repository .ydb .spliterator .YdbSpliterator ;
78+ import  tech .ydb .yoj .repository .ydb .spliterator .queue .YojQueue ;
79+ import  tech .ydb .yoj .repository .ydb .spliterator .YdbSpliteratorQueueGrpcStreamAdapter ;
80+ import  tech .ydb .yoj .repository .ydb .spliterator .legacy .YdbLegacySpliterator ;
81+ import  tech .ydb .yoj .repository .ydb .spliterator .legacy .YdbNewLegacySpliterator ;
82+ import  tech .ydb .yoj .repository .ydb .spliterator .queue .YojQueueImpl ;
7383import  tech .ydb .yoj .repository .ydb .statement .Statement ;
7484import  tech .ydb .yoj .repository .ydb .table .YdbTable ;
7585import  tech .ydb .yoj .util .lang .Interrupts ;
7888import  javax .annotation .Nullable ;
7989import  java .time .Duration ;
8090import  java .util .ArrayList ;
91+ import  java .util .Iterator ;
8192import  java .util .List ;
8293import  java .util .Map ;
8394import  java .util .concurrent .CompletableFuture ;
@@ -101,7 +112,7 @@ public class YdbRepositoryTransaction<REPO extends YdbRepository>
101112    private  static  final  String  PROP_TRACE_VERBOSE_OBJ_RESULTS  = "tech.ydb.yoj.repository.ydb.trace.verboseObjResults" ;
102113
103114    private  final  List <YdbRepository .Query <?>> pendingWrites  = new  ArrayList <>();
104-     private  final  List <YdbSpliterator <?>> spliterators  = new  ArrayList <>();
115+     private  final  List <ClosableSpliterator <?>> spliterators  = new  ArrayList <>();
105116
106117    @ Getter 
107118    private  final  TxOptions  options ;
@@ -127,8 +138,8 @@ public YdbRepositoryTransaction(REPO repo, TxOptions options) {
127138        this .tablespace  = repo .getSchemaOperations ().getTablespace ();
128139    }
129140
130-     private  <V > YdbSpliterator <V > createSpliterator (String  request , boolean  isOrdered ) {
131-         YdbSpliterator <V > spliterator  = new  YdbSpliterator <>(request , isOrdered );
141+     private  <V > YdbNewLegacySpliterator <V > createSpliterator (String  request , boolean  isOrdered ) {
142+         YdbNewLegacySpliterator <V > spliterator  = new  YdbNewLegacySpliterator <>(request , isOrdered );
132143        spliterators .add (spliterator );
133144        return  spliterator ;
134145    }
@@ -183,7 +194,7 @@ private void doCommit() {
183194
184195    private  void  closeStreams () {
185196        Exception  summaryException  = null ;
186-         for  (YdbSpliterator <?> spliterator  : spliterators ) {
197+         for  (ClosableSpliterator <?> spliterator  : spliterators ) {
187198            try  {
188199                spliterator .close ();
189200            } catch  (Exception  e ) {
@@ -451,7 +462,7 @@ public <PARAMS, RESULT> Stream<RESULT> executeScanQuery(Statement<PARAMS, RESULT
451462        String  yql  = getYql (statement );
452463        Params  sdkParams  = getSdkParams (statement , params );
453464
454-         YdbSpliterator <RESULT > spliterator  = createSpliterator ("scanQuery: "  + yql , false );
465+         YdbNewLegacySpliterator <RESULT > spliterator  = createSpliterator ("scanQuery: "  + yql , false );
455466
456467        initSession ();
457468        session .executeScanQuery (
@@ -559,38 +570,65 @@ public <PARAMS, RESULT> Stream<RESULT> readTable(ReadTableMapper<PARAMS, RESULT>
559570            settings .toKey (TupleValue .of (values ), params .isToInclusive ());
560571        }
561572
562-         if  (params .isUseNewSpliterator ()) {
563-             YdbSpliterator <RESULT > spliterator  = createSpliterator ("readTable: "  + tableName , params .isOrdered ());
573+         return  switch  (params .getSpliteratorType ()) {
574+             case  LEGACY  -> {
575+                 try  {
576+                     YdbLegacySpliterator <RESULT > spliterator  = new  YdbLegacySpliterator <>(params .isOrdered (), action  ->
577+                             doCall ("read table "  + mapper .getTableName ("" ), () -> {
578+                                 Status  status  = YdbOperations .safeJoin (
579+                                         session .readTable (
580+                                                 tableName ,
581+                                                 settings .build (),
582+                                                 rs  -> new  ResultSetConverter (rs ).stream (mapper ::mapResult ).forEach (action )
583+                                         ),
584+                                         params .getTimeout ().plusMinutes (5 )
585+                                 );
586+                                 validate ("readTable" , status .getCode (), status .toString ());
587+                             })
588+                     );
589+                     yield spliterator .makeStream ();
590+                 } catch  (RepositoryException  e ) {
591+                     throw  e ;
592+                 } catch  (Exception  e ) {
593+                     throw  new  UnexpectedException ("Could not read table "  + tableName , e );
594+                 }
595+             }
596+             case  LEGACY_SLOW  -> {
597+                 YdbNewLegacySpliterator <RESULT > spliterator  = createSpliterator ("readTable: "  + tableName , params .isOrdered ());
564598
565-             initSession ();
566-             session .readTable (
567-                     tableName , settings .build (),
568-                     resultSet  -> new  ResultSetConverter (resultSet ).stream (mapper ::mapResult ).forEach (spliterator ::onNext )
569-             ).whenComplete (spliterator ::onSupplierThreadComplete );
599+                  initSession ();
600+                  session .readTable (
601+                          tableName , settings .build (),
602+                          resultSet  -> new  ResultSetConverter (resultSet ).stream (mapper ::mapResult ).forEach (spliterator ::onNext )
603+                  ).whenComplete (spliterator ::onSupplierThreadComplete );
570604
571-             return  spliterator .createStream ();
572-         }
605+                 yield spliterator .createStream ();
606+             }
607+             case  EXPERIMENTAL  -> {
608+                 initSession ();
609+ 
610+                 // TODO: configure stream timeout 
611+                 // TODO: configure batch count 
612+                 YojQueue <Iterator <RESULT >> queue  = YojQueueImpl .create (0 , Duration .ofMinutes (5 ));
613+ 
614+                 var  adapter  = new  YdbSpliteratorQueueGrpcStreamAdapter <>("readTable: "  + tableName , queue );
615+                 GrpcReadStream <ReadTablePart > grpcStream  = session .executeReadTable (tableName , settings .build ());
616+                 CompletableFuture <Status > future  = grpcStream .start (readTablePart  -> {
617+                     ResultSetIterator <RESULT > iterator  = new  ResultSetIterator <>(
618+                             readTablePart .getResultSetReader (),
619+                             mapper ::mapResult 
620+                     );
621+                     adapter .onNext (iterator );
622+                 });
623+                 future .whenComplete (adapter ::onSupplierThreadComplete );
573624
574-         try  {
575-             YdbLegacySpliterator <RESULT > spliterator  = new  YdbLegacySpliterator <>(params .isOrdered (), action  ->
576-                     doCall ("read table "  + mapper .getTableName ("" ), () -> {
577-                         Status  status  = YdbOperations .safeJoin (
578-                                 session .readTable (
579-                                         tableName ,
580-                                         settings .build (),
581-                                         rs  -> new  ResultSetConverter (rs ).stream (mapper ::mapResult ).forEach (action )
582-                                 ),
583-                                 params .getTimeout ().plusMinutes (5 )
584-                         );
585-                         validate ("readTable" , status .getCode (), status .toString ());
586-                     })
587-             );
588-             return  spliterator .makeStream ();
589-         } catch  (RepositoryException  e ) {
590-             throw  e ;
591-         } catch  (Exception  e ) {
592-             throw  new  UnexpectedException ("Could not read table "  + tableName , e );
593-         }
625+                 YdbSpliterator <RESULT > spliterator  = new  YdbSpliterator <>(queue , params .isOrdered ());
626+ 
627+                 spliterators .add (spliterator );
628+ 
629+                 yield spliterator .createStream ();
630+             }
631+         };
594632    }
595633
596634    /** 
0 commit comments