title: Android Paging 3 Library (3.0.0-alpha03) - How to load ClosestToCurrentPosition items quickly by enabled placeholder with fastscroll bar
body: <p>I'am using paging 3 library(3.0.0-alpha03), my local cache is Room(160,000 rows).</p>
  <p>How to speed up loading &quot;ClosestToCurrentPosition&quot; from local cache items when I use scrollbar and drag to specific position in RecyclerView(GridLayoutManager)?</p>
  <p>Suppose I drag scrollbar directly to the position 150,000, the &quot;Flow&quot; map function will be triggered from 0 to 150,000 and that is extreme slow and is not efficient</p>
  <pre><code>/**
   * Returns a [PagingData] containing the result of applying the given [transform] to each
   * element, as it is loaded.
   */
  @CheckResult
  @JvmSynthetic
  fun &lt;T : Any, R : Any&gt; PagingData&lt;T&gt;.map(
      transform: suspend (T) -&gt; R
  ): PagingData&lt;R&gt; = transform { it.map(transform) }
  </code></pre>
  <p><strong>what I expected is something like:</strong> when I use scrollbar and drag to 150,000 , the load behavior will load around 154,500~150,500</p>
  <pre><code>PagingConfig(pageSize = 500, initialLoadSize = 1000, prefetchDistance = 50, enablePlaceholders = true)
  </code></pre>
  <p>Can someone help me see this issue? or Dustin Lam could u help me?
  thanks</p>
  <p>EDIT: i try to wrap data source as jumping source, but something strange happen. this is my jumping source</p>
  <pre><code>class XnMediaFileJumpingPositionPagingSource(
  
          private val roomPagingSource: PagingSource&lt;Int, SimpleXnMediaFile&gt;
  
  ) : PagingSource&lt;Int, SimpleXnMediaFile&gt;() {
  
      override val jumpingSupported = true
  
      val roomInvalidateCallback = roomPagingSource.registerInvalidatedCallback {
          Timber.e(&quot;[jumping] PagingSource invalidate()&quot;)
          invalidate()
          
          // cannot compile
  //        unregisterInvalidatedCallback {
  //            invalidateCallback
  //        }
  //        roomPagingSource.unregisterInvalidatedCallback { 
  //            roomInvalidateCallback
  //        }
      }
  
      val invalidateCallback = registerInvalidatedCallback {
          Timber.e(&quot;[jumping] RoomPagingSource invalidate()&quot;)
          roomPagingSource.invalidate()
  
          // cannot compile
  //        unregisterInvalidatedCallback {
  //            invalidateCallback
  //        }
  //        roomPagingSource.unregisterInvalidatedCallback {
  //            this.roomInvalidateCallback
  //        }
      }
  
      override suspend fun load(params: LoadParams&lt;Int&gt;): LoadResult&lt;Int, SimpleXnMediaFile&gt; {
          Timber.e(&quot;[jumping] Load key %s loadsize %s placeholder %s &quot;, params.key, params.loadSize, params.placeholdersEnabled)
          return roomPagingSource.load(params)
      }
  
      @ExperimentalPagingApi
      override fun getRefreshKey(state: PagingState&lt;Int, SimpleXnMediaFile&gt;): Int? {
          Timber.e(&quot;[jumping] getRefreshKey %s&quot;, state.anchorPosition)
          return state.anchorPosition
      }
  </code></pre>
  <p>the <strong>params.key</strong> keep changing when I drag scroll bar to half of list (maybe is position 80,000 , my db dataset rows amount is 160,000 as I mention above) and finally app ANR</p>
  <p>here is the log</p>
  <pre><code>2020-07-27 13:06:22.590 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key null loadsize 800 placeholder true 
  2020-07-27 13:06:29.107 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 85749
  2020-07-27 13:06:29.108 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:06:29.109 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:06:29.127 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 85749 loadsize 800 placeholder true 
  2020-07-27 13:06:30.920 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 171060
  2020-07-27 13:06:30.920 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:06:30.920 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:06:30.926 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 171060 loadsize 800 placeholder true 
  2020-07-27 13:06:32.808 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 85869
  2020-07-27 13:06:32.809 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:06:32.809 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:06:32.816 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 85869 loadsize 800 placeholder true 
  2020-07-27 13:06:34.572 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 85200 loadsize 400 placeholder true 
  2020-07-27 13:06:34.724 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 163199
  2020-07-27 13:06:34.725 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:06:34.725 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:06:34.729 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 163199 loadsize 800 placeholder true 
  2020-07-27 13:07:06.274 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 162400 loadsize 400 placeholder true 
  2020-07-27 13:07:06.443 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 85199
  2020-07-27 13:07:06.443 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:07:06.443 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:07:06.447 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 85199 loadsize 800 placeholder true 
  2020-07-27 13:07:09.094 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 84400 loadsize 400 placeholder true 
  2020-07-27 13:07:09.236 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 162399
  2020-07-27 13:07:09.237 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:07:09.238 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:07:09.249 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 162399 loadsize 800 placeholder true 
  2020-07-27 13:07:40.931 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 161600 loadsize 400 placeholder true 
  2020-07-27 13:07:41.158 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 84419
  2020-07-27 13:07:41.158 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:07:41.159 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:07:41.162 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 84419 loadsize 800 placeholder true 
  2020-07-27 13:07:43.690 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 84000 loadsize 400 placeholder true 
  2020-07-27 13:07:43.837 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 161599
  2020-07-27 13:07:43.837 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:07:43.838 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:07:43.840 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 161599 loadsize 800 placeholder true 
  2020-07-27 13:08:15.157 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 160800 loadsize 400 placeholder true 
  2020-07-27 13:08:15.338 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 84019
  2020-07-27 13:08:15.339 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:08:15.339 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:08:15.342 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 84019 loadsize 800 placeholder true 
  2020-07-27 13:08:17.980 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 83600 loadsize 400 placeholder true 
  2020-07-27 13:08:18.123 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 160799
  2020-07-27 13:08:18.124 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:08:18.125 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:08:18.136 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 160799 loadsize 800 placeholder true 
  2020-07-27 13:08:49.178 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 160000 loadsize 400 placeholder true 
  2020-07-27 13:08:49.359 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 83619
  2020-07-27 13:08:49.360 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:08:49.360 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:08:49.364 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 83619 loadsize 800 placeholder true 
  2020-07-27 13:08:51.997 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 83200 loadsize 400 placeholder true 
  2020-07-27 13:08:52.148 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 159999
  2020-07-27 13:08:52.148 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:08:52.149 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:08:52.152 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 159999 loadsize 800 placeholder true 
  2020-07-27 13:09:22.903 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 159200 loadsize 400 placeholder true 
  2020-07-27 13:09:23.090 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 83219
  2020-07-27 13:09:23.090 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:09:23.090 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:09:23.094 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 83219 loadsize 800 placeholder true 
  2020-07-27 13:09:25.713 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 82800 loadsize 400 placeholder true 
  2020-07-27 13:09:25.856 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 159199
  2020-07-27 13:09:25.857 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:09:25.857 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:09:25.860 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 159199 loadsize 800 placeholder true 
  2020-07-27 13:09:56.329 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 158400 loadsize 400 placeholder true 
  2020-07-27 13:09:56.494 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 82819
  2020-07-27 13:09:56.494 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:09:56.494 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:09:56.497 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 82819 loadsize 800 placeholder true 
  2020-07-27 13:09:59.132 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 82400 loadsize 400 placeholder true 
  2020-07-27 13:09:59.273 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 158399
  2020-07-27 13:09:59.273 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:09:59.273 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:09:59.276 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 158399 loadsize 800 placeholder true 
  2020-07-27 13:10:29.469 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 157600 loadsize 400 placeholder true 
  2020-07-27 13:10:29.629 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 82419
  2020-07-27 13:10:29.629 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:10:29.629 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:10:29.633 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 82419 loadsize 800 placeholder true 
  2020-07-27 13:10:32.251 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 82000 loadsize 400 placeholder true 
  2020-07-27 13:10:32.397 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 157599
  2020-07-27 13:10:32.397 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:10:32.397 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:10:32.401 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 157599 loadsize 800 placeholder true 
  2020-07-27 13:11:02.096 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 156800 loadsize 400 placeholder true 
  2020-07-27 13:11:02.250 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 81999
  2020-07-27 13:11:02.250 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:11:02.250 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:11:02.253 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 81999 loadsize 800 placeholder true 
  2020-07-27 13:11:04.901 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 81200 loadsize 400 placeholder true 
  2020-07-27 13:11:05.043 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] getRefreshKey 156799
  2020-07-27 13:11:05.043 12810-12810/com.app.fun E/JumpingPagingSource$invalidateCallback: [jumping] RoomPagingSource invalidate()
  2020-07-27 13:11:05.044 12810-12810/com.app.fun E/JumpingPagingSource$roomInvalidateCallback: [jumping] PagingSource invalidate()
  2020-07-27 13:11:05.046 12810-12810/com.app.fun E/JumpingPagingSource: [jumping] Load key 156799 loadsize 800 placeholder true
  </code></pre>
  <p>and PagingConfig</p>
  <pre><code>return Pager(
          config = PagingConfig(
                  pageSize = 400,
                  initialLoadSize = 800,
                  prefetchDistance = 160,
                  enablePlaceholders = true,
                  maxSize = (pageSize + prefetchDistance) * 5,
                  jumpThreshold = 4000
          ),
          remoteMediator = XnMediaFileRemoteMediator(xnbay, contract, db),
          pagingSourceFactory = pagingSourceFactory
  ).flow
  </code></pre>
  <p>Did I miss something ?</p>