public static NodeSequence skip ( final NodeSequence sequence , final int skip ) { if ( sequence == null ) return emptySequence ( 0 ) ; if ( skip <= 0 || sequence . isEmpty ( ) ) return sequence ; return new NodeSequence ( ) { private int rowsToSkip = skip ; @ Override public long getRowCount ( ) { long count = sequence . getRowCount ( ) ; if ( count < skip ) return - 1 ; return count == skip ? 0 : count - skip ; } @ Override public int width ( ) { return sequence . width ( ) ; } @ Override public boolean isEmpty ( ) { return false ; } @ Override public Batch nextBatch ( ) { Batch next = sequence . nextBatch ( ) ; while ( next != null ) { if ( rowsToSkip <= 0 ) return next ; long size = next . rowCount ( ) ; if ( size >= 0 ) { // The size of this batch is known ... if ( size == 0 ) { // but it is empty, so just skip this batch altogether ... next = sequence . nextBatch ( ) ; continue ; } if ( size <= rowsToSkip ) { // The entire batch is smaller than the number of rows we're skipping, so skip the whole batch ... rowsToSkip -= size ; next = sequence . nextBatch ( ) ; continue ; } // Otherwise, we have to skip the first `rowsToSkip` rows in the batch ... for ( int i = 0 ; i != rowsToSkip ; ++ i ) { if ( ! next . hasNext ( ) ) return null ; next . nextRow ( ) ; -- size ; } rowsToSkip = 0 ; return new AlternateSizeBatch ( next , size ) ; } // Otherwise the size of the batch is not known, so we need to skip the rows individually ... while ( rowsToSkip > 0 && next . hasNext ( ) ) { next . nextRow ( ) ; -- rowsToSkip ; } if ( next . hasNext ( ) ) return next ; // Otherwise, we've used up all of this batch so just continue to the next ... next = sequence . nextBatch ( ) ; } return next ; } @ Override public void close ( ) { sequence . close ( ) ; } @ Override public String toString ( ) { return "(skip " + skip + " " + sequence + " )" ; } } ; }
Create a sequence of nodes that skips a specified number of rows before returning any rows .