-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eliminate array copies #31
base: main
Are you sure you want to change the base?
Changes from 4 commits
18fffad
cfd4ec0
ae2cd67
f20e57d
471bfe3
0b157ac
a7de790
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,7 +33,9 @@ | |
import java.lang.invoke.MethodHandles; | ||
import java.nio.ByteBuffer; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
@@ -68,9 +70,9 @@ void setMaxEventSize(int val) { | |
maxEventSize = Argument.expectNotGreater(val, EventHeader.MAX_SIZE_SOFT, "max event size"); | ||
} | ||
|
||
public void pack(PutMessageImpl... msgs) { | ||
public void pack(Collection<PutMessageImpl> msgs) { | ||
Argument.expectNonNull(msgs, "msgs"); | ||
Argument.expectPositive(msgs.length, "message array length"); | ||
Argument.expectPositive(msgs.size(), "message array length"); | ||
for (PutMessageImpl m : msgs) { | ||
Argument.expectNonNull(m, "put message"); | ||
|
||
|
@@ -87,11 +89,19 @@ public void flush() { | |
} | ||
} | ||
|
||
public void post(PutMessageImpl... msgs) { | ||
public void post(Collection<PutMessageImpl> msgs) { | ||
pack(msgs); | ||
flush(); | ||
} | ||
|
||
public void post(PutMessageImpl msg) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question here |
||
post(Collections.singletonList(msg)); | ||
} | ||
|
||
public void post(PutMessageImpl... msgs) { | ||
post(Arrays.asList(msgs)); | ||
} | ||
|
||
private void sendEvent() { | ||
PutEventBuilder putBuilder = new PutEventBuilder(); | ||
putBuilder.setMaxEventSize(maxEventSize); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,8 @@ | |
import java.lang.invoke.MethodHandles; | ||
import java.time.Duration; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
import javax.annotation.Nonnull; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
@@ -48,6 +50,7 @@ public class QueueImpl implements QueueHandle { | |
static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); | ||
|
||
static final int INVALID_QUEUE_ID = -1; | ||
private static final int INITIAL_PUTMESSAGES_SIZE = 100; | ||
|
||
// Immutable fields | ||
private final BrokerSession brokerSession; | ||
|
@@ -61,7 +64,8 @@ public class QueueImpl implements QueueHandle { | |
// Fields exposed to user thread | ||
private final QueueHandleParameters parameters; // mutable object and final field | ||
private volatile QueueState state; | ||
private final ArrayList<PutMessageImpl> putMessages = new ArrayList<>(); | ||
private final AtomicReference<Collection<PutMessageImpl>> putMessages = | ||
new AtomicReference<>(new ArrayList<>(INITIAL_PUTMESSAGES_SIZE)); | ||
private volatile boolean isSuspended = false; | ||
// Whether the queue is suspended. | ||
// While suspended, a queue receives no | ||
|
@@ -261,20 +265,11 @@ public BmqFuture<CloseQueueCode> closeAsync(Duration timeout) { | |
} | ||
|
||
public void pack(PutMessageImpl message) throws BMQException { | ||
synchronized (lock) { | ||
putMessages.add(message); | ||
} | ||
putMessages.get().add(message); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. .get() itself is atomic, and so is the .getAndSet() in flush, so afaik I don't think its possible to get the array that is being flushed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, Correct? |
||
} | ||
|
||
public PutMessageImpl[] flush() throws BMQException { | ||
PutMessageImpl[] msgs; | ||
synchronized (lock) { | ||
msgs = new PutMessageImpl[putMessages.size()]; | ||
msgs = putMessages.toArray(msgs); | ||
putMessages.clear(); | ||
} | ||
brokerSession.post(this, msgs); | ||
return msgs; | ||
public void flush() throws BMQException { | ||
brokerSession.post(this, putMessages.getAndSet(new ArrayList<>(INITIAL_PUTMESSAGES_SIZE))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should not we check here if there are messages to send? Otherwise we may just replace empty array with another empty array |
||
} | ||
|
||
@Override | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need there there two methods here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Collections.singletonList() is more efficient for a single element than Arrays.asList()