import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
-import org.opendaylight.yangtools.concepts.Identifier;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+import org.opendaylight.yangtools.concepts.WritableObjects;
/**
* A cluster-wide unique identifier of a frontend instance. This identifier discerns between individual incarnations
* @author Robert Varga
*/
@Beta
-public final class ClientIdentifier implements Identifier, WritableObject {
+public final class ClientIdentifier implements WritableIdentifier {
private static final class Proxy implements Externalizable {
private static final long serialVersionUID = 1L;
private FrontendIdentifier frontendId;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Objects;
-import org.opendaylight.yangtools.concepts.Identifier;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
/**
* A cluster-wide unique identifier of a frontend type located at a cluster member.
* @author Robert Varga
*/
@Beta
-public final class FrontendIdentifier implements Identifier, WritableObject {
+public final class FrontendIdentifier implements WritableIdentifier {
private static final class Proxy implements Externalizable {
private static final long serialVersionUID = 1L;
private MemberName memberName;
import java.util.regex.Pattern;
import javax.annotation.RegEx;
import org.opendaylight.yangtools.concepts.Identifier;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
/**
* An {@link Identifier} identifying a data store frontend type, which is able to access the data store backend.
* @author Robert Varga
*/
@Beta
-public final class FrontendType implements Comparable<FrontendType>, Identifier, WritableObject {
+public final class FrontendType implements Comparable<FrontendType>, WritableIdentifier {
private static final class Proxy implements Externalizable {
private static final long serialVersionUID = 1L;
private byte[] serialized;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
-import org.opendaylight.yangtools.concepts.Identifier;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+import org.opendaylight.yangtools.concepts.WritableObjects;
/**
* Globally-unique identifier of a local history.
*
* @author Robert Varga
*/
-public final class LocalHistoryIdentifier implements Identifier, WritableObject {
+public final class LocalHistoryIdentifier implements WritableIdentifier {
private static final class Proxy implements Externalizable {
private static final long serialVersionUID = 1L;
private ClientIdentifier clientId;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.nio.charset.StandardCharsets;
-import org.opendaylight.yangtools.concepts.Identifier;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
/**
* Type-safe encapsulation of a cluster member name.
* @author Robert Varga
*/
@Beta
-public final class MemberName implements Comparable<MemberName>, Identifier, WritableObject {
+public final class MemberName implements Comparable<MemberName>, WritableIdentifier {
private static final class Proxy implements Externalizable {
private static final long serialVersionUID = 1L;
private byte[] serialized;
}
@Override
- public void writeExternal(ObjectOutput out) throws IOException {
+ public void writeExternal(final ObjectOutput out) throws IOException {
out.writeInt(serialized.length);
out.write(serialized);
}
@Override
- public void readExternal(ObjectInput in) throws IOException {
+ public void readExternal(final ObjectInput in) throws IOException {
serialized = new byte[in.readInt()];
in.readFully(serialized);
}
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.concepts.Identifier;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+import org.opendaylight.yangtools.concepts.WritableObjects;
/**
* Globally-unique identifier of a transaction.
* @author Robert Varga
*/
@Beta
-public final class TransactionIdentifier implements Identifier, WritableObject {
+public final class TransactionIdentifier implements WritableIdentifier {
private static final class Proxy implements Externalizable {
private static final long serialVersionUID = 1L;
private LocalHistoryIdentifier historyId;
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.cluster.access.concepts;
-
-import com.google.common.annotations.Beta;
-import java.io.DataOutput;
-import java.io.IOException;
-import javax.annotation.Nonnull;
-
-/**
- * Marker interface for an object which can be written out to an {@link DataOutput}. Classes implementing this
- * interface should declare a corresponding
- *
- * <pre>
- * public static CLASS readFrom(DataInput in) throws IOException;
- * </pre>
- *
- * The serialization format provided by this abstraction does not guarantee versioning. Callers are responsible for
- * ensuring the source stream is correctly positioned.
- *
- * @author Robert Varga
- */
-// FIXME: this really should go into yangtools/common/concepts.
-@Beta
-public interface WritableObject {
- /**
- * Serialize this object into a {@link DataOutput} as a fixed-format stream.
- *
- * @param out Output
- * @throws IOException if the output fails
- * @throws NullPointerException if out is null
- */
- void writeTo(@Nonnull DataOutput out) throws IOException;
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.cluster.access.concepts;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-//FIXME: this really should go into yangtools/common/concepts.
-public final class WritableObjects {
- private WritableObjects() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Write a long value into a {@link DataOutput}, compressing potential zero bytes. This method is useful for
- * serializing counters and similar, which have a wide range, but typically do not use it. The value provided is
- * treated as unsigned.
- *
- * This methods writes the number of trailing non-zero in the value. It then writes the minimum required bytes
- * to reconstruct the value by left-padding zeroes. Inverse operation is performed by {@link #readLong(DataInput)}.
- *
- * @param out Output
- * @param value long value to write
- */
- public static void writeLong(final DataOutput out, final long value) throws IOException {
- final int bytes = valueBytes(value);
- out.writeByte(bytes);
- writeValue(out, value, bytes);
- }
-
- public static long readLong(final DataInput in) throws IOException {
- return readValue(in, in.readByte());
- }
-
- private static long readValue(final DataInput in, final int flags) throws IOException {
- int bytes = flags & 0xf;
- if (bytes < 8) {
- if (bytes > 0) {
- long value = 0;
- if (bytes >= 4) {
- bytes -= 4;
- value = (in.readInt() & 0xFFFFFFFFL) << (bytes * Byte.SIZE);
- }
- if (bytes >= 2) {
- bytes -= 2;
- value |= in.readUnsignedShort() << (bytes * Byte.SIZE);
- }
- if (bytes > 0) {
- value |= in.readUnsignedByte();
- }
- return value;
- } else {
- return 0;
- }
- } else {
- return in.readLong();
- }
- }
-
- private static void writeValue(final DataOutput out, final long value, final int bytes) throws IOException {
- if (bytes < 8) {
- int left = bytes;
- if (left >= 4) {
- left -= 4;
- out.writeInt((int)(value >>> (left * Byte.SIZE)));
- }
- if (left >= 2) {
- left -= 2;
- out.writeShort((int)(value >>> (left * Byte.SIZE)));
- }
- if (left > 0) {
- out.writeByte((int)(value & 0xFF));
- }
- } else {
- out.writeLong(value);
- }
- }
-
- private static int valueBytes(final long value) {
- // This is a binary search for the first match. Note that we need to mask bits from the most significant one
- if ((value & 0xFFFFFFFF00000000L) != 0) {
- if ((value & 0xFFFF000000000000L) != 0) {
- return (value & 0xFF00000000000000L) != 0 ? 8 : 7;
- } else {
- return (value & 0xFF0000000000L) != 0 ? 6 : 5;
- }
- } else if ((value & 0xFFFFFFFFL) != 0) {
- if ((value & 0xFFFF0000L) != 0) {
- return (value & 0xFF000000L) != 0 ? 4 : 3;
- } else {
- return (value & 0xFF00L) != 0 ? 2 : 1;
- }
- } else {
- return 0;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.cluster.access.concepts;
-
-import static org.junit.Assert.assertEquals;
-import com.google.common.io.ByteArrayDataOutput;
-import com.google.common.io.ByteStreams;
-import java.io.IOException;
-import org.junit.Test;
-
-public class WritableObjectsTest {
-
- private static void assertRecovery(final long expected) throws IOException {
- final ByteArrayDataOutput out = ByteStreams.newDataOutput();
- WritableObjects.writeLong(out, expected);
- final long actual = WritableObjects.readLong(ByteStreams.newDataInput(out.toByteArray()));
- assertEquals(Long.toUnsignedString(expected, 16), Long.toUnsignedString(actual, 16));
- }
-
- @Test
- public void testReadWriteLong() throws IOException {
- assertRecovery(0L);
- assertRecovery(1L);
- assertRecovery(255L);
- assertRecovery(256L);
-
- assertRecovery(Long.MAX_VALUE);
- assertRecovery(Long.MIN_VALUE);
-
- assertRecovery(0xF000000000000000L);
- assertRecovery(0x0F00000000000000L);
- assertRecovery(0x00F0000000000000L);
- assertRecovery(0x000F000000000000L);
- assertRecovery(0x0000F00000000000L);
- assertRecovery(0x00000F0000000000L);
- assertRecovery(0x000000F000000000L);
- assertRecovery(0x0000000F00000000L);
- assertRecovery(0x00000000F0000000L);
- assertRecovery(0x000000000F000000L);
- assertRecovery(0x0000000000F00000L);
- assertRecovery(0x00000000000F0000L);
- assertRecovery(0x000000000000F000L);
- assertRecovery(0x0000000000000F00L);
- assertRecovery(0x00000000000000F0L);
-
- assertRecovery(0xF0F0F0F0F0F0F0F0L);
- assertRecovery(0x0FF0F0F0F0F0F0F0L);
- assertRecovery(0x00F0F0F0F0F0F0F0L);
- assertRecovery(0x000FF0F0F0F0F0F0L);
- assertRecovery(0x0000F0F0F0F0F0F0L);
- assertRecovery(0x00000F00F0F0F0F0L);
- assertRecovery(0x000000F0F0F0F0F0L);
- assertRecovery(0x0000000FF0F0F0F0L);
- assertRecovery(0x00000000F0F0F0F0L);
- assertRecovery(0x000000000FF0F0F0L);
- assertRecovery(0x0000000000F0F0F0L);
- assertRecovery(0x00000000000FF0F0L);
- assertRecovery(0x000000000000F0F0L);
- assertRecovery(0x0000000000000FF0L);
- assertRecovery(0x00000000000000F0L);
-
- assertRecovery(0x8000000000000000L);
- assertRecovery(0x0800000000000000L);
- assertRecovery(0x0080000000000000L);
- assertRecovery(0x0008000000000000L);
- assertRecovery(0x0000800000000000L);
- assertRecovery(0x0000080000000000L);
- assertRecovery(0x0000008000000000L);
- assertRecovery(0x0000000800000000L);
- assertRecovery(0x0000000080000000L);
- assertRecovery(0x0000000008000000L);
- assertRecovery(0x0000000000800000L);
- assertRecovery(0x0000000000080000L);
- assertRecovery(0x0000000000008000L);
- assertRecovery(0x0000000000000800L);
- assertRecovery(0x0000000000000080L);
- assertRecovery(0x0000000000000008L);
- }
-}