Skip to content

Commit

Permalink
DATAREDIS-1212 Add helper methods to Message to avoid allocation in…
Browse files Browse the repository at this point in the history
… `DefaultMessage`
  • Loading branch information
theigl committed Sep 4, 2020
1 parent 3022efa commit 247424a
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
*/
package org.springframework.data.redis.connection;

import org.springframework.data.redis.connection.util.ByteArrayWrapper;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

/**
* Default message implementation.
*
* @author Costin Leau
* @author Christoph Strobl
* @author Thomas Heigl
*/
public class DefaultMessage implements Message {

Expand All @@ -39,9 +42,6 @@ public DefaultMessage(byte[] channel, byte[] body) {
this.channel = channel;
}

/**
* @return
*/
public byte[] getChannel() {
return channel.clone();
}
Expand All @@ -50,9 +50,28 @@ public byte[] getBody() {
return body.clone();
}

public boolean hasChannel() {
return !ObjectUtils.isEmpty(channel);
}

public boolean hasBody() {
return !ObjectUtils.isEmpty(body);
}

public String getChannelAsString() {
return new String(channel);
}

public String getBodyAsString() {
return new String(body);
}

public ByteArrayWrapper getChannelAsWrapper() {
return new ByteArrayWrapper(channel);
}

@Override
public String toString() {

if (toString == null) {
toString = new String(body);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@

import java.io.Serializable;

import org.springframework.lang.Nullable;
import org.springframework.data.redis.connection.util.ByteArrayWrapper;
import org.springframework.util.ObjectUtils;

/**
* Class encapsulating a Redis message body and its properties.
*
* @author Costin Leau
* @author Christoph Strobl
* @author Thomas Heigl
*/
public interface Message extends Serializable {

Expand All @@ -40,4 +42,50 @@ public interface Message extends Serializable {
* @return message channel. Never {@literal null}.
*/
byte[] getChannel();

/**
* Check if the message has a channel
*
* @return {@code true} if the message has a channel, otherwise {@code false}
*/
default boolean hasChannel() {
return !ObjectUtils.isEmpty(getChannel());
}

/**
* Check if the message has a body
*
* @return {@code true} if the message has a body, otherwise {@code false}
*/
default boolean hasBody() {
return !ObjectUtils.isEmpty(getBody());
}

/**
* Returns the string representation of the channel associated with the message.
*
* @return message channel as string. Never {@literal null}.
*/
default String getChannelAsString() {
return new String(getChannel());
}

/**
* Returns the string representation of the body (or the payload) of the message
*
* @return body as string. Never {@literal null}.
*/
default String getBodyAsString() {
return new String(getBody());
}

/**
* Returns the channel associated with the message wrapped in a {@link ByteArrayWrapper}
*
* @return the wrapped channel
*/
default ByteArrayWrapper getChannelAsWrapper() {
return new ByteArrayWrapper(getChannel());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ public void onMessage(Message message, @Nullable byte[] pattern) {

Object value = CollectionUtils.isEmpty(hash) ? null : converter.read(Object.class, new RedisData(hash));

String channel = !ObjectUtils.isEmpty(message.getChannel())
String channel = message.hasChannel()
? converter.getConversionService().convert(message.getChannel(), String.class)
: null;

Expand All @@ -826,7 +826,7 @@ public void onMessage(Message message, @Nullable byte[] pattern) {

private boolean isKeyExpirationMessage(Message message) {

if (message == null || message.getChannel() == null || message.getBody() == null) {
if (message == null || !message.hasChannel() || !message.hasBody()) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public KeyspaceEventMessageListener(RedisMessageListenerContainer listenerContai
@Override
public void onMessage(Message message, @Nullable byte[] pattern) {

if (message == null || ObjectUtils.isEmpty(message.getChannel()) || ObjectUtils.isEmpty(message.getBody())) {
if (message == null || !message.hasChannel() || !message.hasBody()) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,7 @@ public void onMessage(Message message, @Nullable byte[] pattern) {
} else {
pattern = null;
// do channel matching first
listeners = channelMapping.get(new ByteArrayWrapper(message.getChannel()));
listeners = channelMapping.get(message.getChannelAsWrapper());
}

if (!CollectionUtils.isEmpty(listeners)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.redis.connection;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import org.springframework.data.redis.connection.util.ByteArrayWrapper;

/**
* @author Thomas Heigl
*/
class DefaultMessageTest {

private static final String CHANNEL = "AnyChannel";
private static final String BODY = "AnyBody";
private static final byte[] EMPTY_BYTES = {};
private static final byte[] CHANNEL_BYTES = CHANNEL.getBytes();
private static final byte[] BODY_BYTES = BODY.getBytes();

@Test
void testHasChannel() {
assertThat(aMessageWithChannel(EMPTY_BYTES).hasChannel()).isFalse();
assertThat(aMessageWithChannel(CHANNEL_BYTES).hasChannel()).isTrue();
}

@Test
void testHasBody() {
assertThat(aMessageWithBody(EMPTY_BYTES).hasBody()).isFalse();
assertThat(aMessageWithBody(BODY_BYTES).hasBody()).isTrue();
}

@Test
void testGetChannelAsString() {
assertThat(aMessageWithChannel(EMPTY_BYTES).getChannelAsString()).isEmpty();
assertThat(aMessageWithChannel(CHANNEL_BYTES).getChannelAsString()).isEqualTo(CHANNEL);
}

@Test
void testGetBodyAsString() {
assertThat(aMessageWithBody(EMPTY_BYTES).getBodyAsString()).isEmpty();
assertThat(aMessageWithBody(BODY_BYTES).getBodyAsString()).isEqualTo(BODY);
}

@Test
void testGetChannelAsWrapper() {
assertThat(aMessageWithChannel(EMPTY_BYTES).getChannelAsWrapper()).isEqualTo(new ByteArrayWrapper(EMPTY_BYTES));
assertThat(aMessageWithChannel(CHANNEL_BYTES).getChannelAsWrapper()).isEqualTo(new ByteArrayWrapper(CHANNEL_BYTES));
}

private DefaultMessage aMessageWithChannel(byte[] channel) {
return new DefaultMessage(channel, EMPTY_BYTES);
}

private DefaultMessage aMessageWithBody(byte[] body) {
return new DefaultMessage(EMPTY_BYTES, body);
}
}

0 comments on commit 247424a

Please sign in to comment.