Improvement: simplified AbstractConstant compareTo.

Motivation:

AbstractConstant.compareTo seems complex and hard to understand. Also it allocates unnecessary 1 byte in direct buffer and holds unnecessary pointer to this byte butter.

Modifications:

uniquifier (id) variable now initialized during Constant creation and thus no need in volatile and no need in uniquifier() method as it could be easily replaced with AtomicLong.

Result:

Every Constant instance now consumes less bytes for pointer, don't consume anything in direct buffer.
This commit is contained in:
Dmitriy Dumanskiy 2016-08-03 00:24:45 +03:00 committed by Norman Maurer
parent 26aa34853a
commit a06afe8b77

View File

@ -15,20 +15,17 @@
*/ */
package io.netty.util; package io.netty.util;
import io.netty.util.internal.PlatformDependent; import java.util.concurrent.atomic.AtomicLong;
import io.netty.util.internal.ThreadLocalRandom;
import java.nio.ByteBuffer;
/** /**
* Base implementation of {@link Constant}. * Base implementation of {@link Constant}.
*/ */
public abstract class AbstractConstant<T extends AbstractConstant<T>> implements Constant<T> { public abstract class AbstractConstant<T extends AbstractConstant<T>> implements Constant<T> {
private static final AtomicLong uniqueIdGenerator = new AtomicLong();
private final int id; private final int id;
private final String name; private final String name;
private volatile long uniquifier; private final long uniquifier;
private ByteBuffer directBuffer;
/** /**
* Creates a new instance. * Creates a new instance.
@ -36,6 +33,7 @@ public abstract class AbstractConstant<T extends AbstractConstant<T>> implements
protected AbstractConstant(int id, String name) { protected AbstractConstant(int id, String name) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.uniquifier = uniqueIdGenerator.getAndIncrement();
} }
@Override @Override
@ -78,34 +76,14 @@ public abstract class AbstractConstant<T extends AbstractConstant<T>> implements
return returnCode; return returnCode;
} }
long thisUV = uniquifier(); if (uniquifier < other.uniquifier) {
long otherUV = other.uniquifier();
if (thisUV < otherUV) {
return -1; return -1;
} }
if (thisUV > otherUV) { if (uniquifier > other.uniquifier) {
return 1; return 1;
} }
throw new Error("failed to compare two different constants"); throw new Error("failed to compare two different constants");
} }
private long uniquifier() {
long uniquifier;
if ((uniquifier = this.uniquifier) == 0) {
synchronized (this) {
while ((uniquifier = this.uniquifier) == 0) {
if (PlatformDependent.hasUnsafe()) {
directBuffer = ByteBuffer.allocateDirect(1);
this.uniquifier = PlatformDependent.directBufferAddress(directBuffer);
} else {
directBuffer = null;
this.uniquifier = ThreadLocalRandom.current().nextLong();
}
}
}
}
return uniquifier;
}
} }