/**
* Copyright 2013 Benjamin Lerer
*
* 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 io.horizondb.db.commitlog;
import java.io.IOException;
import io.horizondb.io.ByteReader;
import io.horizondb.io.ByteWriter;
import io.horizondb.io.encoding.VarInts;
import io.horizondb.io.serialization.Parser;
import io.horizondb.io.serialization.Serializable;
import javax.annotation.concurrent.Immutable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.CompareToBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
/**
* Represents a position within the commitlog.
*
* @author benjamin
*/
@Immutable
public final class ReplayPosition implements Comparable<ReplayPosition>, Serializable {
/**
* The parser instance.
*/
private static final Parser<ReplayPosition> PARSER = new Parser<ReplayPosition>() {
/**
* {@inheritDoc}
*/
@Override
public ReplayPosition parseFrom(ByteReader reader) throws IOException {
long segment = VarInts.readUnsignedLong(reader);
long position = VarInts.readUnsignedLong(reader);
return new ReplayPosition(segment, position);
}
};
/**
* The ID of commitlog segment.
*/
private final long segment;
/**
* The position within the segment.
*/
private final long position;
/**
* Creates a new <code>ReplayPosition</code> for the specified segment and the specified position.
*
* @param segment the ID of the commitlog segment
* @param position the position within the commit log segment
*/
public ReplayPosition(long segment, long position) {
this.segment = segment;
this.position = position;
}
/**
* Returns the ID of the commitlog segment.
*
* @return the ID of the commitlog segment
*/
public long getSegment() {
return this.segment;
}
/**
* Returns the position within the segment.
*
* @return the position within the segment.
*/
public long getPosition() {
return this.position;
}
/**
* Creates a new <code>ReplayPosition</code> by reading the data from the specified reader.
*
* @param reader the reader to read from.
* @throws IOException if an I/O problem occurs
*/
public static ReplayPosition parseFrom(ByteReader reader) throws IOException {
return getParser().parseFrom(reader);
}
/**
* Returns the parser that can be used to deserialize <code>ReplayPosition</code> instances.
*
* @return the parser that can be used to deserialize <code>ReplayPosition</code> instances.
*/
public static Parser<ReplayPosition> getParser() {
return PARSER;
}
/**
*
* {@inheritDoc}
*/
@Override
public int computeSerializedSize() {
return VarInts.computeUnsignedLongSize(this.segment) + VarInts.computeUnsignedLongSize(this.position);
}
/**
* {@inheritDoc}
*/
@Override
public void writeTo(ByteWriter writer) throws IOException {
VarInts.writeUnsignedLong(writer, this.segment);
VarInts.writeUnsignedLong(writer, this.position);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object object) {
if (!(object instanceof ReplayPosition)) {
return false;
}
ReplayPosition rhs = (ReplayPosition) object;
return new EqualsBuilder().append(this.segment, rhs.segment).append(this.position, rhs.position).isEquals();
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return new HashCodeBuilder(-965631597, -371498275).append(this.segment).append(this.position).toHashCode();
}
/**
* {@inheritDoc}
*/
@Override
public int compareTo(ReplayPosition other) {
return new CompareToBuilder().append(this.segment, other.segment)
.append(this.position, other.position)
.toComparison();
}
/**
* Returns <code>true</code> if this <code>ReplayPosition</code> is after the specified one.
*
* @param replayPosition the other replay position
* @return <code>true</code> if this <code>ReplayPosition</code> is after the specified one, <code>false</code>
* otherwise
*/
public boolean isAfter(ReplayPosition replayPosition) {
return this.compareTo(replayPosition) > 0;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("segment", this.segment)
.append("position", this.position)
.toString();
}
}