@Override
  public void aggregate(final ByteBuffer buf, final int position)
  {
    final HllSketch sketch = selector.getObject();
    if (sketch == null) {
      return;
    }
    final WritableMemory mem = WritableMemory.wrap(buf, ByteOrder.LITTLE_ENDIAN).writableRegion(position, size);
    final Lock lock = stripedLock.getAt(HllSketchBuildBufferAggregator.lockIndex(position)).writeLock();
    lock.lock();
    try {
      final Union union = Union.writableWrap(mem);
      union.update(sketch);
    }
    finally {
      lock.unlock();
    }
  }
@ Override public void aggregate ( final ByteBuffer buf , final int position ) { final HllSketch sketch = selector . getObject ( ) ; if ( sketch == null ) { return ; } final WritableMemory mem = WritableMemory . wrap ( buf , ByteOrder . LITTLE_ENDIAN ) . writableRegion ( position , size ) ; final Lock lock = stripedLock . getAt ( HllSketchBuildBufferAggregator . lockIndex ( position ) ) . writeLock ( ) ; lock . lock ( ) ; try { final Union union = Union . writableWrap ( mem ) ; union . update ( sketch ) ; } finally { lock . unlock ( ) ; } }
This method uses locks because it can be used during indexing,
and Druid can call aggregate() and get() concurrently
See https://github.com/druid-io/druid/pull/3956