Skip to content

Commit

Permalink
Backport of Agrona collections into Hazelcast.
Browse files Browse the repository at this point in the history
Reusing existing HZ functions where applicable.
Also fix a few CheckStyle issues in old code.
created
  • Loading branch information
Marko Topolnik committed Jul 10, 2015
1 parent cccd37b commit 69dd55c
Show file tree
Hide file tree
Showing 37 changed files with 3,630 additions and 203 deletions.
6 changes: 6 additions & 0 deletions NOTICE
@@ -0,0 +1,6 @@
The package com.hazelcast.util.collection and the classes:
com.hazelcast.util.QuickMath
com.hazelcast.client.impl.protocol.util.UnsafeBuffer
com.hazelcast.client.impl.protocol.util.BufferBuilder
contain code originating from the Agrona project
(https://github.com/real-logic/Agrona).
10 changes: 6 additions & 4 deletions checkstyle/suppressions.xml
Expand Up @@ -213,10 +213,8 @@
<suppress checks="JavadocMethod" files="com.hazelcast.client.impl[\\/]"/>

<!--CLIENT PROTOCOL-->
<!--TODO: we will refactor these External utils-->
<suppress checks="" files="com.hazelcast.client.impl.protocol.util[\\/]"/>
<!--TODO we will refactor these encode-decode code-->
<!--Parameters class are gonna be auto generated-->
<suppress checks="IllegalImport" files="com/hazelcast/client/impl/protocol/util/UnsafeBuffer"/>
<!--Parameters classes are auto-generated-->
<suppress checks="" files="com.hazelcast.client.impl.protocol.map.*Parameters"/>
<suppress checks="" files="com.hazelcast.client.impl.protocol.*Parameters"/>
<suppress checks="" files="com.hazelcast.client.impl.protocol.*Codec"/>
Expand Down Expand Up @@ -554,6 +552,10 @@
<suppress checks="JavadocVariable" files="com.hazelcast.internal.management.request.ConsoleRequestConstants"/>
<suppress checks="JavadocVariable|VisibilityModifier" files="com.hazelcast.internal.management.dto.*"/>

<!-- Agrona backport -->
<suppress checks="MagicNumber" files="com/hazelcast/util/collection/" />
<suppress checks="JavadocType" files="com/hazelcast/util/collection/.*2ObjectHashMap" />
<suppress checks="MethodCount" files="com/hazelcast/util/collection/.*HashSet" />

<!-- Map -->
<suppress checks="JavadocMethod" files="com.hazelcast.map[\\/]"/>
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2014 - 2015 Real Logic Ltd.
* Copyright (c) 2008-2015, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hazelcast.client.impl.protocol.util;

import com.hazelcast.util.QuickMath;
Expand All @@ -23,6 +24,7 @@
* Builder for appending buffers that grows capacity as necessary.
*/
public class BufferBuilder {
/** Buffer's default initial capacity */
public static final int INITIAL_CAPACITY = 4096;

private static final String PROP_HAZELCAST_PROTOCOL_UNSAFE = "hazelcast.protocol.unsafe.enabled";
Expand Down
@@ -1,5 +1,22 @@
/*
* Copyright (c) 2008-2015, Hazelcast, Inc. All Rights Reserved.
*
* 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
*
* http://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 com.hazelcast.client.impl.protocol.util;

import com.hazelcast.util.collection.Int2ObjectHashMap;
import com.hazelcast.client.impl.protocol.ClientMessage;

import java.nio.ByteBuffer;
Expand Down Expand Up @@ -37,7 +54,8 @@ public void onData(final ByteBuffer buffer) {
continue;
}

if (message.isFlagSet(BEGIN_FLAG)) { // first fragment
// first fragment
if (message.isFlagSet(BEGIN_FLAG)) {
final BufferBuilder builder = new BufferBuilder();
builderBySessionIdMap.put(message.getCorrelationId(), builder);
builder.append(message.buffer(), 0, message.getFrameLength());
Expand Down
@@ -1,3 +1,19 @@
/*
* Copyright (c) 2008-2015, Hazelcast, Inc. All Rights Reserved.
*
* 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
*
* http://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 com.hazelcast.client.impl.protocol.util;

import com.hazelcast.nio.Bits;
Expand Down Expand Up @@ -27,9 +43,11 @@ public class MessageFlyweight {
*/
private static final short SHORT_MASK = 0x00FF;

private int offset; //initialized in wrap method by user , does not change.
private int index; //starts from zero, incremented each tome something set to buffer
protected ClientProtocolBuffer buffer;
//initialized in wrap method by user , does not change.
private int offset;
//starts from zero, incremented each tome something set to buffer
private int index;


public MessageFlyweight() {
Expand Down
Expand Up @@ -19,10 +19,14 @@
import com.hazelcast.nio.Bits;
import com.hazelcast.nio.serialization.Data;

public class ParameterUtil {
public final class ParameterUtil {

private static final int UTF8_MAX_BYTES_PER_CHAR = 4;

private ParameterUtil() { }

public static int calculateStringDataSize(String string) {
return Bits.INT_SIZE_IN_BYTES + string.length() * 4;
return Bits.INT_SIZE_IN_BYTES + string.length() * UTF8_MAX_BYTES_PER_CHAR;
}

public static int calculateByteArrayDataSize(byte[] bytes) {
Expand Down
Expand Up @@ -20,7 +20,6 @@

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;

/**
* Implementation of ClientProtocolBuffer that is used by default in clients.
Expand All @@ -29,7 +28,6 @@
*/
public class SafeBuffer implements ClientProtocolBuffer {

public static final Charset UTF_8 = Charset.forName("utf-8");
private ByteBuffer byteBuffer;

public SafeBuffer(byte[] buffer) {
Expand Down Expand Up @@ -74,7 +72,7 @@ public int putStringUtf8(int index, String value) {

@Override
public int putStringUtf8(int index, String value, int maxEncodedSize) {
final byte[] bytes = value.getBytes(UTF_8);
final byte[] bytes = value.getBytes(Bits.UTF_8);
if (bytes.length > maxEncodedSize) {
throw new IllegalArgumentException("Encoded string larger than maximum size: " + maxEncodedSize);
}
Expand Down Expand Up @@ -138,7 +136,7 @@ public String getStringUtf8(int offset, int length) {
final byte[] stringInBytes = new byte[length];
getBytes(offset + Bits.INT_SIZE_IN_BYTES, stringInBytes);

return new String(stringInBytes, UTF_8);
return new String(stringInBytes, Bits.UTF_8);
}

}
@@ -1,5 +1,5 @@
/*
* Copyright 2014 Real Logic Ltd.
* Copyright (c) 2008-2015, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -13,27 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hazelcast.client.impl.protocol.util;

import com.hazelcast.nio.Bits;
import com.hazelcast.nio.UnsafeHelper;
import sun.misc.Unsafe;

import java.nio.ByteOrder;
import java.nio.charset.Charset;

;

/**
* Supports regular, byte ordered, access to an underlying buffer.
*/
@edu.umd.cs.findbugs.annotations.SuppressWarnings({"EI_EXPOSE_REP", "EI_EXPOSE_REP2"})
@edu.umd.cs.findbugs.annotations.SuppressWarnings({ "EI_EXPOSE_REP", "EI_EXPOSE_REP2" })
public class UnsafeBuffer implements ClientProtocolBuffer {
/**
* UTF-8 charset
*/
public static final Charset UTF_8 = Charset.forName("utf-8");

private static final String DISABLE_BOUNDS_CHECKS_PROP_NAME = "hazelcast.disable.bounds.checks";
private static final boolean SHOULD_BOUNDS_CHECK = !Boolean.getBoolean(DISABLE_BOUNDS_CHECKS_PROP_NAME);

Expand Down Expand Up @@ -197,7 +190,7 @@ public String getStringUtf8(final int offset, final int length) {
final byte[] stringInBytes = new byte[length];
getBytes(offset + Bits.INT_SIZE_IN_BYTES, stringInBytes);

return new String(stringInBytes, UTF_8);
return new String(stringInBytes, Bits.UTF_8);
}

@Override
Expand All @@ -207,7 +200,7 @@ public int putStringUtf8(final int index, final String value) {

@Override
public int putStringUtf8(final int index, final String value, final int maxEncodedSize) {
final byte[] bytes = value.getBytes(UTF_8);
final byte[] bytes = value.getBytes(Bits.UTF_8);
if (bytes.length > maxEncodedSize) {
throw new IllegalArgumentException("Encoded string larger than maximum size: " + maxEncodedSize);
}
Expand Down
11 changes: 11 additions & 0 deletions hazelcast/src/main/java/com/hazelcast/nio/Bits.java
Expand Up @@ -16,6 +16,8 @@

package com.hazelcast.nio;

import java.nio.charset.Charset;

/**
* Access and manipulate bits, bytes, primitives ...
*/
Expand Down Expand Up @@ -58,6 +60,15 @@ public final class Bits {
*/
public static final int CACHE_LINE_LENGTH = 64;

/**
* A reusable instance of the UTF-8 charset
* */
public static final Charset UTF_8 = Charset.forName("UTF-8");
/**
* A reusable instance of the ISO Latin-1 charset
* */
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");

private Bits() {
}

Expand Down
32 changes: 23 additions & 9 deletions hazelcast/src/main/java/com/hazelcast/util/Preconditions.java
Expand Up @@ -28,6 +28,22 @@ private Preconditions() {
}


/**
* Tests if a string contains text.
*
* @param argument the string tested to see if it contains text.
* @param errorMessage the errorMessage
* @return the string argument that was tested.
* @throws java.lang.IllegalArgumentException if the string is empty
*/
public static String checkHasText(String argument, String errorMessage) {
if (argument == null || argument.isEmpty()) {
throw new IllegalArgumentException(errorMessage);
}

return argument;
}

/**
* Tests if an argument is not null.
*
Expand All @@ -44,18 +60,16 @@ public static <T> T checkNotNull(T argument, String errorMessage) {
}

/**
* Tests if a string contains text.
* Tests if an argument is not null.
*
* @param argument the string tested to see if it contains text.
* @param errorMessage the errorMessage
* @return the string argument that was tested.
* @throws java.lang.IllegalArgumentException if the string is empty
* @param argument the argument tested to see if it is not null.
* @return the argument that was tested.
* @throws java.lang.NullPointerException if argument is null
*/
public static String checkHasText(String argument, String errorMessage) {
if (argument == null || argument.isEmpty()) {
throw new IllegalArgumentException(errorMessage);
public static <T> T checkNotNull(T argument) {
if (argument == null) {
throw new NullPointerException();
}

return argument;
}

Expand Down
48 changes: 18 additions & 30 deletions hazelcast/src/main/java/com/hazelcast/util/QuickMath.java
Expand Up @@ -67,42 +67,31 @@ public static long modPowerOfTwo(long a, int b) {
}

/**
* Returns the next power of two that is larger than the specified int value.
* Fast method of finding the next power of 2 greater than or equal to the supplied value.
* <p/>
* If the value is &lt;= 0 then 1 will be returned.
* <p/>
* This method is not suitable for {@link Integer#MIN_VALUE} or numbers greater than 2^30.
*
* @param value the int value
* @return the next power of two that is larger than the specified int value.
* @param value from which to search for next power of 2
* @return The next power of 2 or the value itself if it is a power of 2
*/
public static int nextPowerOfTwo(int value) {
if (!isPowerOfTwo(value)) {
value--;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value++;
}
return value;
public static int nextPowerOfTwo(final int value) {
return 1 << (32 - Integer.numberOfLeadingZeros(value - 1));
}

/**
* Returns the next power of two that is larger than the specified long value.
* Fast method of finding the next power of 2 greater than or equal to the supplied value.
* <p/>
* If the value is &lt;= 0 then 1 will be returned.
* <p/>
* This method is not suitable for {@link Long#MIN_VALUE} or numbers greater than 2^62.
*
* @param value the long value
* @return the next power of two that is larger than the specified long value
* @param value from which to search for next power of 2
* @return The next power of 2 or the value itself if it is a power of 2
*/
public static long nextPowerOfTwo(long value) {
if (!isPowerOfTwo(value)) {
value--;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value |= value >> 32;
value++;
}
return value;
public static long nextPowerOfTwo(final long value) {
return 1L << (64 - Long.numberOfLeadingZeros(value - 1));
}

/**
Expand Down Expand Up @@ -238,5 +227,4 @@ public static int compareLongs(long l1, long l2) {
return 0;
}
}

}

0 comments on commit 69dd55c

Please sign in to comment.