blob: 73ab127cebe16d313fcecb5e212e1dd94526d940 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.lang;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryRawReader;
import org.apache.ignite.binary.BinaryRawWriter;
import org.apache.ignite.binary.BinaryReader;
import org.apache.ignite.binary.BinaryWriter;
import org.apache.ignite.binary.Binarylizable;
import org.apache.ignite.internal.util.lang.GridIterator;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.A;
import org.apache.ignite.internal.util.typedef.internal.U;
/**
* This is a faster performing version of {@link UUID}. On basic tests this version is at least
* 10x time faster for ID creation. It uses extra memory for 8-byte counter additionally to
* internal UUID.
*/
public final class IgniteUuid implements Comparable<IgniteUuid>, Iterable<IgniteUuid>, Cloneable, Externalizable, Binarylizable {
/** */
private static final long serialVersionUID = 0L;
/** VM ID. */
public static final UUID VM_ID = UUID.randomUUID();
/** */
private static final AtomicLong cntGen = new AtomicLong(U.currentTimeMillis());
/** */
private UUID gid;
/** */
private long locId;
/**
* Empty constructor required for {@link Externalizable}.
*/
public IgniteUuid() {
// No-op.
}
/**
* Constructs {@code IgniteUuid} from a global and local identifiers.
*
* @param gid UUID.
* @param locId Counter.
*/
public IgniteUuid(UUID gid, long locId) {
assert gid != null;
this.gid = gid;
this.locId = locId;
}
/**
* Gets {@link UUID} associated with local VM.
*
* @return {@link UUID} associated with local VM.
*/
public static UUID vmId() {
return VM_ID;
}
/**
* Gets last generated local ID.
*
* @return Last generated local ID.
*/
public static long lastLocalId() {
return cntGen.get();
}
/**
* Creates new pseudo-random ID.
*
* @return Newly created pseudo-random ID.
*/
public static IgniteUuid randomUuid() {
return new IgniteUuid(VM_ID, cntGen.incrementAndGet());
}
/**
* Constructs new {@code IgniteUuid} based on global and local ID portions.
*
* @param id UUID instance.
* @return Newly created pseudo-random ID.
*/
public static IgniteUuid fromUuid(UUID id) {
A.notNull(id, "id");
return new IgniteUuid(id, cntGen.getAndIncrement());
}
/**
* Converts string into {@code IgniteUuid}. The String must be in the format generated
* by {@link IgniteUuid#toString()} method.
*
* @param s String to convert to {@code IgniteUuid}.
* @return {@code IgniteUuid} instance representing given string.
*/
public static IgniteUuid fromString(String s) {
int firstDash = s.indexOf('-');
return new IgniteUuid(
UUID.fromString(s.substring(firstDash + 1)),
Long.valueOf(new StringBuilder(s.substring(0, firstDash)).reverse().toString(), 16)
);
}
/**
* Gets a short string version of this ID. Use it only for UI where full version is
* available to the application.
*
* @return Short string version of this ID.
*/
public String shortString() {
return new StringBuilder(Long.toHexString(locId)).reverse().toString();
}
/**
* Gets global ID portion of this {@code IgniteUuid}.
*
* @return Global ID portion of this {@code IgniteUuid}.
*/
public UUID globalId() {
return gid;
}
/**
* Gets local ID portion of this {@code IgniteUuid}.
*
* @return Local ID portion of this {@code IgniteUuid}.
*/
public long localId() {
return locId;
}
/** {@inheritDoc} */
@Override public void writeExternal(ObjectOutput out) throws IOException {
U.writeUuid(out, gid);
out.writeLong(locId);
}
/** {@inheritDoc} */
@Override public void readExternal(ObjectInput in) throws IOException {
gid = U.readUuid(in);
locId = in.readLong();
}
/** {@inheritDoc} */
@Override public int compareTo(IgniteUuid o) {
if (o == this)
return 0;
if (o == null)
return 1;
int res = Long.compare(locId, o.locId);
if (res == 0)
res = gid.compareTo(o.globalId());
return res;
}
/** {@inheritDoc} */
@Override public GridIterator<IgniteUuid> iterator() {
return F.iterator(Collections.singleton(this), F.<IgniteUuid>identity(), true);
}
/** {@inheritDoc} */
@Override public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof IgniteUuid))
return false;
IgniteUuid that = (IgniteUuid)obj;
return that.locId == locId && that.gid.equals(gid);
}
/** {@inheritDoc} */
@Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
BinaryRawWriter out = writer.rawWriter();
out.writeLong(locId);
out.writeLong(gid.getMostSignificantBits());
out.writeLong(gid.getLeastSignificantBits());
}
/** {@inheritDoc} */
@Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
BinaryRawReader in = reader.rawReader();
locId = in.readLong();
gid = new UUID(in.readLong(), in.readLong());
}
/** {@inheritDoc} */
@Override public int hashCode() {
return 31 * gid.hashCode() + (int)(locId ^ (locId >>> 32));
}
/** {@inheritDoc} */
@Override public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/** {@inheritDoc} */
@Override public String toString() {
return shortString() + '-' + gid.toString();
}
}