/**
* 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.hadoop.hdfs.server.namenode.bookkeeper.metadata;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ComparisonChain;
import org.apache.hadoop.hdfs.protocol.FSConstants;
import org.apache.hadoop.hdfs.server.namenode.bookkeeper.BookKeeperEditLogInputStream;
/**
* Metadata for a journal stored in a BookKeeper ledger. Implements equals,
* hashCode, and compareTo method (from Comparable interface) to allow
* equality checking and natural order sorting (by comparing the first
* transaction id).
* </p>
* Currently the metadata is stored inside a ZNode, but it could be stored
* in any other media (e.g., in the path name of a ZNode, or in a database).
* @see BookKeeperEditLogInputStream
* @see BookKeeperEditLogInputStream
*/
public class EditLogLedgerMetadata implements Comparable<EditLogLedgerMetadata> {
private final int logVersion;
private final long ledgerId;
private final long firstTxId;
private final long lastTxId;
/**
* Creates a new metadata object.
* @param logVersion The layout version of the edit log segment stored in
* this ledger.
* @param ledgerId BookKeeper-specific id of the ledger.
* @param firstTxId First HDFS transaction id stored in the segment.
* @param lastTxId Last HDFS transaction id store in the segment or -1 if
* the segment is in progress.
*/
public EditLogLedgerMetadata(int logVersion,
long ledgerId,
long firstTxId,
long lastTxId) {
Preconditions.checkArgument(firstTxId >= 0);
Preconditions.checkArgument(lastTxId >= -1);
if (lastTxId > -1 && lastTxId < firstTxId) {
throw new IllegalArgumentException("Ledger can not be empty!");
}
this.logVersion = logVersion;
this.ledgerId = ledgerId;
this.firstTxId = firstTxId;
this.lastTxId = lastTxId;
}
/**
* Creates a new EditLogLedgerMetadata instance that represents the current
* instance that has been finalized with the specified last transaction id
* @param lastTxId The last transaction id in the finalized ledger
* @return Instance representing the finalized ledger
*/
public EditLogLedgerMetadata finalizeWithLastTxId(long lastTxId) {
return new EditLogLedgerMetadata(this.logVersion, this.ledgerId,
this.firstTxId, lastTxId);
}
/**
* Return layout version version of the edit log segment stored in this ledger.
* Usually specified in {@link FSConstants} by
* <code>FSConstants.LAYOUT_VERSION</code>
*/
public int getLogVersion() {
return logVersion;
}
/**
* Returns BookKeeper specific id of the ledger. Ids are generated by
* BookKeeper itself.
*/
public long getLedgerId() {
return ledgerId;
}
/**
* Returns the first HDFS transaction id of the ledger.
*/
public long getFirstTxId() {
return firstTxId;
}
/**
* Returns the last HDFS transaction id of the ledger if the ledger is
* finalized or -1 if the ledger is in-progress.
*/
public long getLastTxId() {
return lastTxId;
}
/**
* If this instance is identical to the specified instance, return 0.
* If the instances are not identical, return -1 if this instance's first
* transaction id is less than the other instance's first transaction id,
* or 1 otherwise.
*/
@Override
public int compareTo(EditLogLedgerMetadata other) {
if (this.equals(other)) {
return 0;
}
return firstTxId < other.getFirstTxId() ? -1 : 1;
}
/**
* Determine whether two instances are identical by checking whether
* firstTxId, lastTxId, ledgerId, and logVersion are equal.
* @param o The instance to compare to this
* @return True if instances identical
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || !(o instanceof EditLogLedgerMetadata)) {
return false;
}
EditLogLedgerMetadata that = (EditLogLedgerMetadata) o;
return firstTxId == that.firstTxId &&
lastTxId == that.lastTxId &&
ledgerId == that.ledgerId &&
logVersion == that.logVersion;
}
@Override
public int hashCode() {
return Objects.hashCode(logVersion, ledgerId, firstTxId, lastTxId);
}
@Override
public String toString() {
return "EditLogLedgerMetadata{" +
"logVersion=" + logVersion +
", ledgerId=" + ledgerId +
", firstTxId=" + firstTxId +
", lastTxId=" + lastTxId +
'}';
}
}