@@ -39,16 +39,15 @@ public class DataBlockList extends AbstractDataBlock
3939 private static final long serialVersionUID = -413032909256132305L ;
4040 protected List <DataBlock > blockList ; // either ArrayList or LinkedList so it's serializable
4141 protected int blockAtomCount = -1 ;
42- protected boolean equalBlockSize ;
43- transient protected int blockIndex ;
44- transient protected int localIndex ;
42+ protected boolean equalBlockSize ;
4543 transient ThreadLocal <CachedIndex > cachedIndex = new ThreadLocal <>();
4644
4745 static class CachedIndex
4846 {
4947 int lastIndex ; // last requested index
5048 int cumulIndex ;
51- int blockIndex ;
49+ int blockIndex ;
50+ int localIndex ;
5251 }
5352
5453
@@ -154,8 +153,8 @@ public DataType getDataType()
154153 @ Override
155154 public DataType getDataType (int index )
156155 {
157- selectBlock (index );
158- return blockList .get (blockIndex ).getDataType ();
156+ var cachedIndex = selectBlock (index );
157+ return blockList .get (cachedIndex . blockIndex ).getDataType ();
159158 }
160159
161160
@@ -190,30 +189,38 @@ public void updateAtomCount()
190189 }
191190
192191
193- protected final void selectBlock (int index )
192+ protected final CachedIndex selectBlock (int index )
194193 {
195- int desiredIndex = index + startIndex ;
194+ int desiredIndex = index + startIndex ;
196195
196+ // use thread local index so we can read concurrently from multiple threads
197+ CachedIndex cachedIdx = cachedIndex .get ();
198+ if (cachedIdx == null ) {
199+ cachedIdx = new CachedIndex ();
200+ cachedIndex .set (cachedIdx );
201+ }
202+
197203 if (equalBlockSize )
198204 {
199- blockIndex = desiredIndex / blockAtomCount ;
200- localIndex = desiredIndex % blockAtomCount ;
205+ cachedIdx . blockIndex = desiredIndex / blockAtomCount ;
206+ cachedIdx . localIndex = desiredIndex % blockAtomCount ;
201207 }
202208 else
203209 {
204- // use thread local cached index to speed up sequential scans
205- CachedIndex cachedIdx = cachedIndex .get ();
206- if (cachedIdx == null || index <= cachedIdx .lastIndex )
207- {
208- cachedIdx = new CachedIndex ();
209- cachedIndex .set (cachedIdx );
210+ // speed up sequential scans by restarting from previous index
211+ // but reset if desired index is going back down
212+ if (index <= cachedIdx .lastIndex ) {
213+ cachedIdx .lastIndex = 0 ;
214+ cachedIdx .cumulIndex = 0 ;
215+ cachedIdx .blockIndex = 0 ;
216+ cachedIdx .localIndex = 0 ;
210217 }
211218
212219 int size = 0 ;
213220 int cumul = cachedIdx .cumulIndex ;
214221 int i = cachedIdx .blockIndex ;
215222
216- while (desiredIndex >= cumul )
223+ while (desiredIndex >= cumul )
217224 {
218225 size = blockList .get (i ).getAtomCount ();
219226 cumul += size ;
@@ -222,14 +229,15 @@ protected final void selectBlock(int index)
222229
223230 // actually use previous block because we went one block too far
224231 cumul -= size ;
225- blockIndex = i - 1 ;
226- localIndex = desiredIndex - cumul ;
232+ cachedIdx . blockIndex = i - 1 ;
233+ cachedIdx . localIndex = desiredIndex - cumul ;
227234
228235 // save indexing variables in cache for next call
229236 cachedIdx .lastIndex = index ;
230237 cachedIdx .cumulIndex = cumul ;
231- cachedIdx .blockIndex = blockIndex ;
232- }
238+ }
239+
240+ return cachedIdx ;
233241 }
234242
235243
@@ -313,159 +321,159 @@ public String toString()
313321 @ Override
314322 public boolean getBooleanValue (int index )
315323 {
316- selectBlock (index );
317- return blockList .get (blockIndex ).getBooleanValue (localIndex );
324+ var idx = selectBlock (index );
325+ return blockList .get (idx . blockIndex ).getBooleanValue (idx . localIndex );
318326 }
319327
320328
321329 @ Override
322330 public byte getByteValue (int index )
323331 {
324- selectBlock (index );
325- return blockList .get (blockIndex ).getByteValue (localIndex );
332+ var idx = selectBlock (index );
333+ return blockList .get (idx . blockIndex ).getByteValue (idx . localIndex );
326334 }
327335
328336
329337 @ Override
330338 public short getShortValue (int index )
331339 {
332- selectBlock (index );
333- return blockList .get (blockIndex ).getShortValue (localIndex );
340+ var idx = selectBlock (index );
341+ return blockList .get (idx . blockIndex ).getShortValue (idx . localIndex );
334342 }
335343
336344
337345 @ Override
338346 public int getIntValue (int index )
339347 {
340- selectBlock (index );
341- return blockList .get (blockIndex ).getIntValue (localIndex );
348+ var idx = selectBlock (index );
349+ return blockList .get (idx . blockIndex ).getIntValue (idx . localIndex );
342350 }
343351
344352
345353 @ Override
346354 public long getLongValue (int index )
347355 {
348- selectBlock (index );
349- return blockList .get (blockIndex ).getLongValue (localIndex );
356+ var idx = selectBlock (index );
357+ return blockList .get (idx . blockIndex ).getLongValue (idx . localIndex );
350358 }
351359
352360
353361 @ Override
354362 public float getFloatValue (int index )
355363 {
356- selectBlock (index );
357- return blockList .get (blockIndex ).getFloatValue (localIndex );
364+ var idx = selectBlock (index );
365+ return blockList .get (idx . blockIndex ).getFloatValue (idx . localIndex );
358366 }
359367
360368
361369 @ Override
362370 public double getDoubleValue (int index )
363371 {
364- selectBlock (index );
365- return blockList .get (blockIndex ).getDoubleValue (localIndex );
372+ var idx = selectBlock (index );
373+ return blockList .get (idx . blockIndex ).getDoubleValue (idx . localIndex );
366374 }
367375
368376
369377 @ Override
370378 public String getStringValue (int index )
371379 {
372- selectBlock (index );
373- return blockList .get (blockIndex ).getStringValue (localIndex );
380+ var idx = selectBlock (index );
381+ return blockList .get (idx . blockIndex ).getStringValue (idx . localIndex );
374382 }
375383
376384
377385 @ Override
378386 public Instant getTimeStamp (int index )
379387 {
380- selectBlock (index );
381- return blockList .get (blockIndex ).getTimeStamp (localIndex );
388+ var idx = selectBlock (index );
389+ return blockList .get (idx . blockIndex ).getTimeStamp (idx . localIndex );
382390 }
383391
384392
385393 @ Override
386394 public OffsetDateTime getDateTime (int index )
387395 {
388- selectBlock (index );
389- return blockList .get (blockIndex ).getDateTime (localIndex );
396+ var idx = selectBlock (index );
397+ return blockList .get (idx . blockIndex ).getDateTime (idx . localIndex );
390398 }
391399
392400
393401 @ Override
394402 public void setBooleanValue (int index , boolean value )
395403 {
396- selectBlock (index );
397- blockList .get (blockIndex ).setBooleanValue (localIndex , value );
404+ var idx = selectBlock (index );
405+ blockList .get (idx . blockIndex ).setBooleanValue (idx . localIndex , value );
398406 }
399407
400408
401409 @ Override
402410 public void setByteValue (int index , byte value )
403411 {
404- selectBlock (index );
405- blockList .get (blockIndex ).setByteValue (localIndex , value );
412+ var idx = selectBlock (index );
413+ blockList .get (idx . blockIndex ).setByteValue (idx . localIndex , value );
406414 }
407415
408416
409417 @ Override
410418 public void setShortValue (int index , short value )
411419 {
412- selectBlock (index );
413- blockList .get (blockIndex ).setShortValue (localIndex , value );
420+ var idx = selectBlock (index );
421+ blockList .get (idx . blockIndex ).setShortValue (idx . localIndex , value );
414422 }
415423
416424
417425 @ Override
418426 public void setIntValue (int index , int value )
419427 {
420- selectBlock (index );
421- blockList .get (blockIndex ).setIntValue (localIndex , value );
428+ var idx = selectBlock (index );
429+ blockList .get (idx . blockIndex ).setIntValue (idx . localIndex , value );
422430 }
423431
424432
425433 @ Override
426434 public void setLongValue (int index , long value )
427435 {
428- selectBlock (index );
429- blockList .get (blockIndex ).setLongValue (localIndex , value );
436+ var idx = selectBlock (index );
437+ blockList .get (idx . blockIndex ).setLongValue (idx . localIndex , value );
430438 }
431439
432440
433441 @ Override
434442 public void setFloatValue (int index , float value )
435443 {
436- selectBlock (index );
437- blockList .get (blockIndex ).setFloatValue (localIndex , value );
444+ var idx = selectBlock (index );
445+ blockList .get (idx . blockIndex ).setFloatValue (idx . localIndex , value );
438446 }
439447
440448
441449 @ Override
442450 public void setDoubleValue (int index , double value )
443451 {
444- selectBlock (index );
445- blockList .get (blockIndex ).setDoubleValue (localIndex , value );
452+ var idx = selectBlock (index );
453+ blockList .get (idx . blockIndex ).setDoubleValue (idx . localIndex , value );
446454 }
447455
448456
449457 @ Override
450458 public void setStringValue (int index , String value )
451459 {
452- selectBlock (index );
453- blockList .get (blockIndex ).setStringValue (localIndex , value );
460+ var idx = selectBlock (index );
461+ blockList .get (idx . blockIndex ).setStringValue (idx . localIndex , value );
454462 }
455463
456464
457465 @ Override
458466 public void setTimeStamp (int index , Instant value )
459467 {
460- selectBlock (index );
461- blockList .get (blockIndex ).setTimeStamp (localIndex , value );
468+ var idx = selectBlock (index );
469+ blockList .get (idx . blockIndex ).setTimeStamp (idx . localIndex , value );
462470 }
463471
464472
465473 @ Override
466474 public void setDateTime (int index , OffsetDateTime value )
467475 {
468- selectBlock (index );
469- blockList .get (blockIndex ).setDateTime (localIndex , value );
476+ var idx = selectBlock (index );
477+ blockList .get (idx . blockIndex ).setDateTime (idx . localIndex , value );
470478 }
471479}
0 commit comments