@@ -24,8 +24,9 @@ public class OneToManyRingBuffer
24
24
private final UnsafeBuffer pointers ;
25
25
26
26
private final int capacity ;
27
- private final int maxMsgLength ;
27
+ private final int maxRecordLength ;
28
28
private final int lastConsumerIndex ;
29
+ private final int consumerSize ;
29
30
30
31
private final int producerPointerIndex ;
31
32
private final int [] consumerPointerIndexes ;
@@ -36,6 +37,8 @@ public class OneToManyRingBuffer
36
37
*/
37
38
public static final int HEADER_LENGTH = Integer .BYTES * 2 ; // length, type
38
39
40
+ public static final int EXTRA_PADDING_LENGTH = Long .BYTES * 8 ;
41
+
39
42
/**
40
43
* Alignment as a multiple of bytes for each record.
41
44
* Padding to align the record in order to prevent false sharing.
@@ -61,14 +64,15 @@ public OneToManyRingBuffer(int powSize, int consumerSize)
61
64
62
65
producerPointerIndex = Long .BYTES * 8 ;
63
66
consumerPointerIndexes = new int [consumerSize ];
67
+ this .consumerSize = consumerSize ;
64
68
65
69
consumerPointerIndexes [0 ] = Long .BYTES * 8 + Long .BYTES + Long .BYTES * 7 ; // padding + producer-pointer-block + padding
66
70
for (int i = 1 ; i < consumerSize ; i ++)
67
71
{
68
72
consumerPointerIndexes [i ] = consumerPointerIndexes [i - 1 ] + Long .BYTES + Long .BYTES * 7 ; // padding + consumer-pointer-block + padding
69
73
}
70
74
71
- maxMsgLength = capacity >> 3 ;
75
+ maxRecordLength = capacity >> 3 ;
72
76
}
73
77
74
78
/**
@@ -80,13 +84,15 @@ public OneToManyRingBuffer(int powSize, int consumerSize)
80
84
*/
81
85
public boolean write (int msgTypeId , ByteBuffer message )
82
86
{
83
- int msgLength = message .limit ();
84
- checkMsgLength (msgLength , maxMsgLength );
87
+ int messageLength = message .limit ();
88
+ final int recordLength = calculateRecordLength (messageLength );
89
+ final int alignedRecordLength = BitUtil .align (recordLength , ALIGNMENT );
90
+ checkMsgLength (alignedRecordLength , maxRecordLength );
85
91
86
92
// [1] happen-before guarantee for reads
87
93
long currentProducerPosition = pointers .getLongVolatile (producerPointerIndex );
88
94
long firstConsumerPosition = pointers .getLongVolatile (consumerPointerIndexes [0 ]);
89
- long lastConsumerPosition = pointers .getLongVolatile (consumerPointerIndexes [lastConsumerIndex ]);
95
+ long lastConsumerPosition = consumerSize == 1 ? firstConsumerPosition : pointers .getLongVolatile (consumerPointerIndexes [lastConsumerIndex ]);
90
96
91
97
int currentProducerOffset = offset (currentProducerPosition );
92
98
boolean currentProducerFlip = flip (currentProducerPosition );
@@ -95,9 +101,6 @@ public boolean write(int msgTypeId, ByteBuffer message)
95
101
int lastConsumerOffset = offset (lastConsumerPosition );
96
102
boolean lastConsumerFlip = flip (lastConsumerPosition );
97
103
98
- final int recordLength = msgLength + HEADER_LENGTH ;
99
- final int alignedRecordLength = BitUtil .align (recordLength , ALIGNMENT );
100
-
101
104
final int expectedEndOffsetOfRecord = currentProducerOffset + alignedRecordLength - 1 ;
102
105
103
106
boolean sameCircleWithFirstConsumer = sameCircle (currentProducerFlip , firstConsumerFlip );
@@ -151,8 +154,8 @@ else if (!sameCircleWithLastConsumer) // !sameCircleWithFirstConsumer, the produ
151
154
int nextProducerOffset = (realStartOfRecord + alignedRecordLength ) % capacity ; // maybe nextProducerOffset == 0
152
155
153
156
// when [2] happened, the [2] ensures that the these instructions are synchronized into main memory as well
154
- buffer .putBytes (realStartOfRecord + HEADER_LENGTH , message , 0 , msgLength );
155
- buffer .putInt (realStartOfRecord , msgLength );
157
+ buffer .putBytes (realStartOfRecord + HEADER_LENGTH , message , 0 , messageLength );
158
+ buffer .putInt (realStartOfRecord , messageLength );
156
159
buffer .putInt (realStartOfRecord + Integer .BYTES , msgTypeId );
157
160
158
161
shouldFlip |= nextProducerOffset == 0 ;
@@ -284,7 +287,7 @@ public boolean readOne(int consumerIndex, final MessageHandler handler)
284
287
return false ;
285
288
}
286
289
287
- int recordLength = messageLength + HEADER_LENGTH ;
290
+ int recordLength = calculateRecordLength ( messageLength ) ;
288
291
int alignedRecordLength = BitUtil .align (recordLength , ALIGNMENT );
289
292
int endRecordOffset = currentConsumerOffset + alignedRecordLength - 1 ;
290
293
@@ -305,4 +308,9 @@ public boolean readOne(int consumerIndex, final MessageHandler handler)
305
308
306
309
return true ;
307
310
}
311
+
312
+ private int calculateRecordLength (int messageLength )
313
+ {
314
+ return messageLength + HEADER_LENGTH + EXTRA_PADDING_LENGTH ;
315
+ }
308
316
}
0 commit comments