24
24
import java .util .LinkedList ;
25
25
import java .util .PriorityQueue ;
26
26
import java .util .Queue ;
27
+ import java .util .concurrent .BlockingQueue ;
27
28
import java .util .concurrent .ExecutorService ;
29
+ import java .util .concurrent .LinkedBlockingQueue ;
28
30
import java .util .concurrent .ScheduledExecutorService ;
29
31
import java .util .concurrent .TimeUnit ;
30
32
import java .util .concurrent .atomic .AtomicBoolean ;
@@ -62,6 +64,8 @@ public class SlidingWindowService {
62
64
* The lock of {@link #pendingBlocks}, {@link #writingBlocks}, {@link #currentBlock}.
63
65
*/
64
66
private final Lock blockLock = new ReentrantLock ();
67
+
68
+ private final Lock pollBlocKLock = new ReentrantLock ();
65
69
/**
66
70
* Blocks that are being written.
67
71
*/
@@ -80,11 +84,11 @@ public class SlidingWindowService {
80
84
* Blocks that are waiting to be written.
81
85
* All blocks in this queue are ordered by the start offset.
82
86
*/
83
- private Queue <Block > pendingBlocks = new LinkedList <>();
87
+ private BlockingQueue <Block > pendingBlocks = new LinkedBlockingQueue <>();
84
88
/**
85
89
* The current block, records are added to this block.
86
90
*/
87
- private Block currentBlock ;
91
+ private volatile Block currentBlock ;
88
92
89
93
/**
90
94
* The thread pool for write operations.
@@ -98,7 +102,7 @@ public class SlidingWindowService {
98
102
/**
99
103
* The last time when a batch of blocks is written to the disk.
100
104
*/
101
- private long lastWriteTimeNanos = 0 ;
105
+ private volatile long lastWriteTimeNanos = 0 ;
102
106
103
107
public SlidingWindowService (WALChannel walChannel , int ioThreadNums , long upperLimit , long scaleUnit ,
104
108
long blockSoftLimit , int writeRateLimit , WALHeaderFlusher flusher ) {
@@ -276,38 +280,43 @@ private Block nextBlock(Block previousBlock) {
276
280
* Get all blocks to be written. If there is no non-empty block, return null.
277
281
*/
278
282
private BlockBatch pollBlocks () {
279
- blockLock .lock ();
280
- try {
281
- return pollBlocksLocked ();
282
- } finally {
283
- blockLock .unlock ();
283
+ if (this .pollBlocKLock .tryLock ()) {
284
+ try {
285
+ return pollBlocksLocked ();
286
+ } finally {
287
+ this .pollBlocKLock .unlock ();
288
+ }
284
289
}
290
+ return null ;
285
291
}
286
292
287
293
/**
288
294
* Get all blocks to be written. If there is no non-empty block, return null.
289
295
* Note: this method is NOT thread safe, and it should be called with {@link #blockLock} locked.
290
296
*/
291
297
private BlockBatch pollBlocksLocked () {
292
- Block currentBlock = getCurrentBlockLocked ();
293
-
294
- boolean isPendingBlockEmpty = pendingBlocks .isEmpty ();
295
- boolean isCurrentBlockEmpty = currentBlock == null || currentBlock .isEmpty ();
296
- if (isPendingBlockEmpty && isCurrentBlockEmpty ) {
297
- // No record to be written
298
- return null ;
298
+ Block currentBlock = this .currentBlock ;
299
+ boolean isCurrentBlockNotEmpty = currentBlock != null && !currentBlock .isEmpty ();
300
+ if (isCurrentBlockNotEmpty ) {
301
+ long time = System .nanoTime ();
302
+ if (time - currentBlock .startTime () > minWriteIntervalNanos ) {
303
+ if (this .blockLock .tryLock ()) {
304
+ try {
305
+ currentBlock = this .getCurrentBlockLocked ();
306
+ if (time - currentBlock .startTime () > minWriteIntervalNanos ) {
307
+ pendingBlocks .add (currentBlock );
308
+ setCurrentBlockLocked (nextBlock (currentBlock ));
309
+ }
310
+ } finally {
311
+ this .blockLock .unlock ();
312
+ }
313
+ }
314
+ }
299
315
}
300
316
301
- Collection <Block > blocks ;
302
- if (!isPendingBlockEmpty ) {
303
- blocks = pendingBlocks ;
304
- pendingBlocks = new LinkedList <>();
305
- } else {
306
- blocks = new LinkedList <>();
307
- }
308
- if (!isCurrentBlockEmpty ) {
309
- blocks .add (currentBlock );
310
- setCurrentBlockLocked (nextBlock (currentBlock ));
317
+ Collection <Block > blocks = new LinkedList <>();
318
+ while (!pendingBlocks .isEmpty ()) {
319
+ blocks .add (pendingBlocks .poll ());
311
320
}
312
321
313
322
BlockBatch blockBatch = new BlockBatch (blocks );
0 commit comments