2323import  java .net .URLEncoder ;
2424import  java .nio .charset .StandardCharsets ;
2525import  java .util .ArrayList ;
26+ import  java .util .Arrays ;
2627import  java .util .Collection ;
2728import  java .util .Iterator ;
2829import  java .util .List ;
@@ -505,6 +506,8 @@ public TableDescriptor getDescriptor() throws IOException {
505506  class  Scanner  implements  ResultScanner  {
506507
507508    String  uri ;
509+     private  Result [] cachedResults ;
510+     private  int  nextCachedResultsRow  = 0 ;
508511
509512    public  Scanner (Scan  scan ) throws  IOException  {
510513      ScannerModel  model ;
@@ -540,11 +543,8 @@ public Scanner(Scan scan) throws IOException {
540543      throw  new  IOException ("scan request timed out" );
541544    }
542545
543-     @ Override 
544-     public  Result [] next (int  nbRows ) throws  IOException  {
546+     public  Result [] nextBatch () throws  IOException  {
545547      StringBuilder  sb  = new  StringBuilder (uri );
546-       sb .append ("?n=" );
547-       sb .append (nbRows );
548548      for  (int  i  = 0 ; i  < maxRetries ; i ++) {
549549        Response  response  = client .get (sb .toString (), Constants .MIMETYPE_PROTOBUF );
550550        int  code  = response .getCode ();
@@ -570,13 +570,31 @@ public Result[] next(int nbRows) throws IOException {
570570      throw  new  IOException ("scanner.next request timed out" );
571571    }
572572
573+     private  boolean  updateCachedResults () throws  IOException  {
574+       if  (cachedResults  == null  || nextCachedResultsRow  >= cachedResults .length ) {
575+         nextCachedResultsRow  = 0 ;
576+         cachedResults  = nextBatch ();
577+       }
578+       return  !(cachedResults  == null  || cachedResults .length  < 1 );
579+     }
580+ 
581+     @ Override 
582+     public  Result [] next (int  nbRows ) throws  IOException  {
583+       if  (!updateCachedResults ()) {
584+         return  null ;
585+       }
586+       int  endIndex  = Math .min (cachedResults .length , nextCachedResultsRow  + nbRows );
587+       Result [] chunk  = Arrays .copyOfRange (cachedResults , nextCachedResultsRow , endIndex );
588+       nextCachedResultsRow  = endIndex ;
589+       return  chunk ;
590+     }
591+ 
573592    @ Override 
574593    public  Result  next () throws  IOException  {
575-       Result [] results  = next (1 );
576-       if  (results  == null  || results .length  < 1 ) {
594+       if  (!updateCachedResults ()) {
577595        return  null ;
578596      }
579-       return  results [ 0 ];
597+       return  cachedResults [ nextCachedResultsRow ++ ];
580598    }
581599
582600    class  Iter  implements  Iterator <Result > {
0 commit comments