blob: df5a4e290b43a1d8c625fc8b6a300982e7eefbfd [file] [log] [blame]
package com.baidu.hugegraph.serializer.direct.util;
import com.baidu.hugegraph.util.E;
import com.baidu.hugegraph.util.LongEncoding;
import com.baidu.hugegraph.util.NumericUtil;
import com.baidu.hugegraph.serializer.direct.util.Id.IdType;
import java.util.Objects;
import java.util.UUID;
public abstract class IdGenerator {
public static final Id ZERO = IdGenerator.of(0L);
public final static Id of(String id) {
return new StringId(id);
}
public final static Id of(UUID id) {
return new UuidId(id);
}
public final static Id of(String id, boolean uuid) {
return uuid ? new UuidId(id) : new StringId(id);
}
public final static Id of(long id) {
return new LongId(id);
}
public static Id of(Object id) {
if (id instanceof Id) {
return (Id) id;
} else if (id instanceof String) {
return of((String) id);
} else if (id instanceof Number) {
return of(((Number) id).longValue());
} else if (id instanceof UUID) {
return of((UUID) id);
}
return new ObjectId(id);
}
public final static Id of(byte[] bytes, IdType type) {
switch (type) {
case LONG:
return new LongId(bytes);
case UUID:
return new UuidId(bytes);
case STRING:
return new StringId(bytes);
default:
throw new AssertionError("Invalid id type " + type);
}
}
public final static Id ofStoredString(String id, IdType type) {
switch (type) {
case LONG:
return of(LongEncoding.decodeSignedB64(id));
case UUID:
byte[] bytes = StringEncoding.decodeBase64(id);
return of(bytes, IdType.UUID);
case STRING:
return of(id);
default:
throw new AssertionError("Invalid id type " + type);
}
}
public final static String asStoredString(Id id) {
switch (id.type()) {
case LONG:
return LongEncoding.encodeSignedB64(id.asLong());
case UUID:
return StringEncoding.encodeBase64(id.asBytes());
case STRING:
return id.asString();
default:
throw new AssertionError("Invalid id type " + id.type());
}
}
public final static IdType idType(Id id) {
if (id instanceof LongId) {
return IdType.LONG;
}
if (id instanceof UuidId) {
return IdType.UUID;
}
if (id instanceof StringId) {
return IdType.STRING;
}
return IdType.UNKNOWN;
}
private final static int compareType(Id id1, Id id2) {
return idType(id1).ordinal() - idType(id2).ordinal();
}
/****************************** id defines ******************************/
public static final class StringId implements Id {
private final String id;
public StringId(String id) {
E.checkArgument(!id.isEmpty(), "The id can't be empty");
this.id = id;
}
public StringId(byte[] bytes) {
this.id = StringEncoding.decode(bytes);
}
@Override
public IdType type() {
return IdType.STRING;
}
@Override
public Object asObject() {
return this.id;
}
@Override
public String asString() {
return this.id;
}
@Override
public long asLong() {
return Long.parseLong(this.id);
}
@Override
public byte[] asBytes() {
return StringEncoding.encode(this.id);
}
@Override
public int length() {
return this.id.length();
}
@Override
public int compareTo(Id other) {
int cmp = compareType(this, other);
if (cmp != 0) {
return cmp;
}
return this.id.compareTo(other.asString());
}
@Override
public int hashCode() {
return this.id.hashCode();
}
@Override
public boolean equals(Object other) {
if (!(other instanceof StringId)) {
return false;
}
return this.id.equals(((StringId) other).id);
}
@Override
public String toString() {
return this.id;
}
}
public static final class LongId extends Number implements Id {
private static final long serialVersionUID = -7732461469037400190L;
private final long id;
public LongId(long id) {
this.id = id;
}
public LongId(byte[] bytes) {
this.id = NumericUtil.bytesToLong(bytes);
}
@Override
public IdType type() {
return IdType.LONG;
}
@Override
public Object asObject() {
return this.id;
}
@Override
public String asString() {
// TODO: encode with base64
return Long.toString(this.id);
}
@Override
public long asLong() {
return this.id;
}
@Override
public byte[] asBytes() {
return NumericUtil.longToBytes(this.id);
}
@Override
public int length() {
return Long.BYTES;
}
@Override
public int compareTo(Id other) {
int cmp = compareType(this, other);
if (cmp != 0) {
return cmp;
}
return Long.compare(this.id, other.asLong());
}
@Override
public int hashCode() {
return Long.hashCode(this.id);
}
@Override
public boolean equals(Object other) {
if (!(other instanceof Number)) {
return false;
}
return this.id == ((Number) other).longValue();
}
@Override
public String toString() {
return String.valueOf(this.id);
}
@Override
public int intValue() {
return (int) this.id;
}
@Override
public long longValue() {
return this.id;
}
@Override
public float floatValue() {
return this.id;
}
@Override
public double doubleValue() {
return this.id;
}
}
public static final class UuidId implements Id {
private final UUID uuid;
public UuidId(String string) {
this(StringEncoding.uuid(string));
}
public UuidId(byte[] bytes) {
this(fromBytes(bytes));
}
public UuidId(UUID uuid) {
E.checkArgument(uuid != null, "The uuid can't be null");
this.uuid = uuid;
}
@Override
public IdType type() {
return IdType.UUID;
}
@Override
public Object asObject() {
return this.uuid;
}
@Override
public String asString() {
return this.uuid.toString();
}
@Override
public long asLong() {
throw new UnsupportedOperationException();
}
@Override
public byte[] asBytes() {
BytesBuffer buffer = BytesBuffer.allocate(16);
buffer.writeLong(this.uuid.getMostSignificantBits());
buffer.writeLong(this.uuid.getLeastSignificantBits());
return buffer.bytes();
}
private static UUID fromBytes(byte[] bytes) {
E.checkArgument(bytes != null, "The UUID can't be null");
BytesBuffer buffer = BytesBuffer.wrap(bytes);
long high = buffer.readLong();
long low = buffer.readLong();
return new UUID(high, low);
}
@Override
public int length() {
return UUID_LENGTH;
}
@Override
public int compareTo(Id other) {
E.checkNotNull(other, "compare id");
int cmp = compareType(this, other);
if (cmp != 0) {
return cmp;
}
return this.uuid.compareTo(((UuidId) other).uuid);
}
@Override
public int hashCode() {
return this.uuid.hashCode();
}
@Override
public boolean equals(Object other) {
if (!(other instanceof UuidId)) {
return false;
}
return this.uuid.equals(((UuidId) other).uuid);
}
@Override
public String toString() {
return this.uuid.toString();
}
}
/**
* This class is just used by backend store for wrapper object as Id
*/
private static final class ObjectId implements Id {
private final Object object;
public ObjectId(Object object) {
E.checkNotNull(object, "object");
this.object = object;
}
@Override
public IdType type() {
return IdType.UNKNOWN;
}
@Override
public Object asObject() {
return this.object;
}
@Override
public String asString() {
throw new UnsupportedOperationException();
}
@Override
public long asLong() {
throw new UnsupportedOperationException();
}
@Override
public byte[] asBytes() {
throw new UnsupportedOperationException();
}
@Override
public int length() {
throw new UnsupportedOperationException();
}
@Override
public int compareTo(Id o) {
throw new UnsupportedOperationException();
}
@Override
public int hashCode() {
return this.object.hashCode();
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ObjectId)) {
return false;
}
return Objects.equals(this.object, ((ObjectId) other).object);
}
@Override
public String toString() {
return this.object.toString();
}
}
}