blob: d8a7de2b7b62ed4739c41d9bbc2c1347a1aede15 [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.hadoop.hdfs.protocol;
import java.util.Date;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.fs.Path;
import com.google.common.base.Preconditions;
import org.apache.hadoop.hdfs.DFSUtilClient;
/**
* Describes a path-based cache directive.
*/
@InterfaceStability.Evolving
@InterfaceAudience.Public
public class CacheDirectiveInfo {
/**
* A builder for creating new CacheDirectiveInfo instances.
*/
public static class Builder {
private Long id;
private Path path;
private Short replication;
private String pool;
private Expiration expiration;
/**
* Builds a new CacheDirectiveInfo populated with the set properties.
*
* @return New CacheDirectiveInfo.
*/
public CacheDirectiveInfo build() {
return new CacheDirectiveInfo(id, path, replication, pool, expiration);
}
/**
* Creates an empty builder.
*/
public Builder() {
}
/**
* Creates a builder with all elements set to the same values as the
* given CacheDirectiveInfo.
*/
public Builder(CacheDirectiveInfo directive) {
this.id = directive.getId();
this.path = directive.getPath();
this.replication = directive.getReplication();
this.pool = directive.getPool();
this.expiration = directive.getExpiration();
}
/**
* Sets the id used in this request.
*
* @param id The id used in this request.
* @return This builder, for call chaining.
*/
public Builder setId(Long id) {
this.id = id;
return this;
}
/**
* Sets the path used in this request.
*
* @param path The path used in this request.
* @return This builder, for call chaining.
*/
public Builder setPath(Path path) {
this.path = path;
return this;
}
/**
* Sets the replication used in this request.
*
* @param replication The replication used in this request.
* @return This builder, for call chaining.
*/
public Builder setReplication(Short replication) {
this.replication = replication;
return this;
}
/**
* Sets the pool used in this request.
*
* @param pool The pool used in this request.
* @return This builder, for call chaining.
*/
public Builder setPool(String pool) {
this.pool = pool;
return this;
}
/**
* Sets when the CacheDirective should expire. A
* {@link CacheDirectiveInfo.Expiration} can specify either an absolute or
* relative expiration time.
*
* @param expiration when this CacheDirective should expire
* @return This builder, for call chaining
*/
public Builder setExpiration(Expiration expiration) {
this.expiration = expiration;
return this;
}
}
/**
* Denotes a relative or absolute expiration time for a CacheDirective. Use
* factory methods {@link CacheDirectiveInfo.Expiration#newAbsolute(Date)} and
* {@link CacheDirectiveInfo.Expiration#newRelative(long)} to create an
* Expiration.
* <p>
* In either case, the server-side clock is used to determine when a
* CacheDirective expires.
*/
public static class Expiration {
/**
* The maximum value we accept for a relative expiry.
*/
public static final long MAX_RELATIVE_EXPIRY_MS =
Long.MAX_VALUE / 4; // This helps prevent weird overflow bugs
/**
* An relative Expiration that never expires.
*/
public static final Expiration NEVER = newRelative(MAX_RELATIVE_EXPIRY_MS);
/**
* Create a new relative Expiration.
* <p>
* Use {@link Expiration#NEVER} to indicate an Expiration that never
* expires.
*
* @param ms how long until the CacheDirective expires, in milliseconds
* @return A relative Expiration
*/
public static Expiration newRelative(long ms) {
return new Expiration(ms, true);
}
/**
* Create a new absolute Expiration.
* <p>
* Use {@link Expiration#NEVER} to indicate an Expiration that never
* expires.
*
* @param date when the CacheDirective expires
* @return An absolute Expiration
*/
public static Expiration newAbsolute(Date date) {
return new Expiration(date.getTime(), false);
}
/**
* Create a new absolute Expiration.
* <p>
* Use {@link Expiration#NEVER} to indicate an Expiration that never
* expires.
*
* @param ms when the CacheDirective expires, in milliseconds since the Unix
* epoch.
* @return An absolute Expiration
*/
public static Expiration newAbsolute(long ms) {
return new Expiration(ms, false);
}
private final long ms;
private final boolean isRelative;
private Expiration(long ms, boolean isRelative) {
if (isRelative) {
Preconditions.checkArgument(ms <= MAX_RELATIVE_EXPIRY_MS,
"Expiration time is too far in the future!");
}
this.ms = ms;
this.isRelative = isRelative;
}
/**
* @return true if Expiration was specified as a relative duration, false if
* specified as an absolute time.
*/
public boolean isRelative() {
return isRelative;
}
/**
* @return The raw underlying millisecond value, either a relative duration
* or an absolute time as milliseconds since the Unix epoch.
*/
public long getMillis() {
return ms;
}
/**
* @return Expiration time as a {@link Date} object. This converts a
* relative Expiration into an absolute Date based on the local
* clock.
*/
public Date getAbsoluteDate() {
return new Date(getAbsoluteMillis());
}
/**
* @return Expiration time in milliseconds from the Unix epoch. This
* converts a relative Expiration into an absolute time based on the
* local clock.
*/
public long getAbsoluteMillis() {
if (!isRelative) {
return ms;
} else {
return new Date().getTime() + ms;
}
}
@Override
public String toString() {
if (isRelative) {
return DFSUtilClient.durationToString(ms);
}
return DFSUtilClient.dateToIso8601String(new Date(ms));
}
}
private final Long id;
private final Path path;
private final Short replication;
private final String pool;
private final Expiration expiration;
CacheDirectiveInfo(Long id, Path path, Short replication, String pool,
Expiration expiration) {
this.id = id;
this.path = path;
this.replication = replication;
this.pool = pool;
this.expiration = expiration;
}
/**
* @return The ID of this directive.
*/
public Long getId() {
return id;
}
/**
* @return The path used in this request.
*/
public Path getPath() {
return path;
}
/**
* @return The number of times the block should be cached.
*/
public Short getReplication() {
return replication;
}
/**
* @return The pool used in this request.
*/
public String getPool() {
return pool;
}
/**
* @return When this directive expires.
*/
public Expiration getExpiration() {
return expiration;
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (getClass() != o.getClass()) {
return false;
}
CacheDirectiveInfo other = (CacheDirectiveInfo)o;
return new EqualsBuilder().append(getId(), other.getId()).
append(getPath(), other.getPath()).
append(getReplication(), other.getReplication()).
append(getPool(), other.getPool()).
append(getExpiration(), other.getExpiration()).
isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(id).
append(path).
append(replication).
append(pool).
append(expiration).
hashCode();
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("{");
String prefix = "";
if (id != null) {
builder.append(prefix).append("id: ").append(id);
prefix = ", ";
}
if (path != null) {
builder.append(prefix).append("path: ").append(path);
prefix = ", ";
}
if (replication != null) {
builder.append(prefix).append("replication: ").append(replication);
prefix = ", ";
}
if (pool != null) {
builder.append(prefix).append("pool: ").append(pool);
prefix = ", ";
}
if (expiration != null) {
builder.append(prefix).append("expiration: ").append(expiration);
}
builder.append("}");
return builder.toString();
}
}