HDFS-5531. Combine the getNsQuota() and getDsQuota() methods in INode.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1544018 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Tsz-wo Sze 2013-11-21 03:17:47 +00:00
parent d1fe9e4142
commit 5f458ef23f
16 changed files with 98 additions and 87 deletions

View File

@ -207,6 +207,9 @@ Trunk (Unreleased)
HDFS-5451. Add byte and file statistics to PathBasedCacheEntry. HDFS-5451. Add byte and file statistics to PathBasedCacheEntry.
(Colin Patrick McCabe via Andrew Wang) (Colin Patrick McCabe via Andrew Wang)
HDFS-5531. Combine the getNsQuota() and getDsQuota() methods in INode.
(szetszwo)
OPTIMIZATIONS OPTIMIZATIONS
HDFS-5349. DNA_CACHE and DNA_UNCACHE should be by blockId only. (cmccabe) HDFS-5349. DNA_CACHE and DNA_UNCACHE should be by blockId only. (cmccabe)

View File

@ -47,7 +47,7 @@ public enum Content {
} }
private Counts() { private Counts() {
super(Content.values()); super(Content.class);
} }
} }

View File

@ -2406,8 +2406,9 @@ public class FSDirectory implements Closeable {
if (dirNode.isRoot() && nsQuota == HdfsConstants.QUOTA_RESET) { if (dirNode.isRoot() && nsQuota == HdfsConstants.QUOTA_RESET) {
throw new IllegalArgumentException("Cannot clear namespace quota on root."); throw new IllegalArgumentException("Cannot clear namespace quota on root.");
} else { // a directory inode } else { // a directory inode
long oldNsQuota = dirNode.getNsQuota(); final Quota.Counts oldQuota = dirNode.getQuotaCounts();
long oldDsQuota = dirNode.getDsQuota(); final long oldNsQuota = oldQuota.get(Quota.NAMESPACE);
final long oldDsQuota = oldQuota.get(Quota.DISKSPACE);
if (nsQuota == HdfsConstants.QUOTA_DONT_SET) { if (nsQuota == HdfsConstants.QUOTA_DONT_SET) {
nsQuota = oldNsQuota; nsQuota = oldNsQuota;
} }
@ -2459,8 +2460,9 @@ public class FSDirectory implements Closeable {
try { try {
INodeDirectory dir = unprotectedSetQuota(src, nsQuota, dsQuota); INodeDirectory dir = unprotectedSetQuota(src, nsQuota, dsQuota);
if (dir != null) { if (dir != null) {
fsImage.getEditLog().logSetQuota(src, dir.getNsQuota(), final Quota.Counts q = dir.getQuotaCounts();
dir.getDsQuota()); fsImage.getEditLog().logSetQuota(src,
q.get(Quota.NAMESPACE), q.get(Quota.DISKSPACE));
} }
} finally { } finally {
writeUnlock(); writeUnlock();

View File

@ -777,18 +777,22 @@ public class FSImage implements Closeable {
if (dir.isQuotaSet()) { if (dir.isQuotaSet()) {
// check if quota is violated. It indicates a software bug. // check if quota is violated. It indicates a software bug.
final Quota.Counts q = dir.getQuotaCounts();
final long namespace = counts.get(Quota.NAMESPACE) - parentNamespace; final long namespace = counts.get(Quota.NAMESPACE) - parentNamespace;
if (Quota.isViolated(dir.getNsQuota(), namespace)) { final long nsQuota = q.get(Quota.NAMESPACE);
if (Quota.isViolated(nsQuota, namespace)) {
LOG.error("BUG: Namespace quota violation in image for " LOG.error("BUG: Namespace quota violation in image for "
+ dir.getFullPathName() + dir.getFullPathName()
+ " quota = " + dir.getNsQuota() + " < consumed = " + namespace); + " quota = " + nsQuota + " < consumed = " + namespace);
} }
final long diskspace = counts.get(Quota.DISKSPACE) - parentDiskspace; final long diskspace = counts.get(Quota.DISKSPACE) - parentDiskspace;
if (Quota.isViolated(dir.getDsQuota(), diskspace)) { final long dsQuota = q.get(Quota.DISKSPACE);
if (Quota.isViolated(dsQuota, diskspace)) {
LOG.error("BUG: Diskspace quota violation in image for " LOG.error("BUG: Diskspace quota violation in image for "
+ dir.getFullPathName() + dir.getFullPathName()
+ " quota = " + dir.getDsQuota() + " < consumed = " + diskspace); + " quota = " + dsQuota + " < consumed = " + diskspace);
} }
((INodeDirectoryWithQuota)dir).setSpaceConsumed(namespace, diskspace); ((INodeDirectoryWithQuota)dir).setSpaceConsumed(namespace, diskspace);

View File

@ -371,8 +371,9 @@ public class FSImageFormat {
/** Update the root node's attributes */ /** Update the root node's attributes */
private void updateRootAttr(INodeWithAdditionalFields root) { private void updateRootAttr(INodeWithAdditionalFields root) {
long nsQuota = root.getNsQuota(); final Quota.Counts q = root.getQuotaCounts();
long dsQuota = root.getDsQuota(); final long nsQuota = q.get(Quota.NAMESPACE);
final long dsQuota = q.get(Quota.DISKSPACE);
FSDirectory fsDir = namesystem.dir; FSDirectory fsDir = namesystem.dir;
if (nsQuota != -1 || dsQuota != -1) { if (nsQuota != -1 || dsQuota != -1) {
fsDir.rootDir.setQuota(nsQuota, dsQuota); fsDir.rootDir.setQuota(nsQuota, dsQuota);

View File

@ -219,6 +219,12 @@ public class FSImageSerialization {
out.writeLong(file.getPreferredBlockSize()); out.writeLong(file.getPreferredBlockSize());
} }
private static void writeQuota(Quota.Counts quota, DataOutput out)
throws IOException {
out.writeLong(quota.get(Quota.NAMESPACE));
out.writeLong(quota.get(Quota.DISKSPACE));
}
/** /**
* Serialize a {@link INodeDirectory} * Serialize a {@link INodeDirectory}
* @param node The node to write * @param node The node to write
@ -234,8 +240,8 @@ public class FSImageSerialization {
out.writeLong(0); // preferred block size out.writeLong(0); // preferred block size
out.writeInt(-1); // # of blocks out.writeInt(-1); // # of blocks
out.writeLong(node.getNsQuota()); writeQuota(node.getQuotaCounts(), out);
out.writeLong(node.getDsQuota());
if (node instanceof INodeDirectorySnapshottable) { if (node instanceof INodeDirectorySnapshottable) {
out.writeBoolean(true); out.writeBoolean(true);
} else { } else {
@ -256,9 +262,7 @@ public class FSImageSerialization {
writeLocalName(a, out); writeLocalName(a, out);
writePermissionStatus(a, out); writePermissionStatus(a, out);
out.writeLong(a.getModificationTime()); out.writeLong(a.getModificationTime());
writeQuota(a.getQuotaCounts(), out);
out.writeLong(a.getNsQuota());
out.writeLong(a.getDsQuota());
} }
/** /**

View File

@ -383,10 +383,11 @@ public abstract class INode implements INodeAttributes, Diff.Element<byte[]> {
public final ContentSummary computeAndConvertContentSummary( public final ContentSummary computeAndConvertContentSummary(
ContentSummaryComputationContext summary) { ContentSummaryComputationContext summary) {
Content.Counts counts = computeContentSummary(summary).getCounts(); Content.Counts counts = computeContentSummary(summary).getCounts();
final Quota.Counts q = getQuotaCounts();
return new ContentSummary(counts.get(Content.LENGTH), return new ContentSummary(counts.get(Content.LENGTH),
counts.get(Content.FILE) + counts.get(Content.SYMLINK), counts.get(Content.FILE) + counts.get(Content.SYMLINK),
counts.get(Content.DIRECTORY), getNsQuota(), counts.get(Content.DIRECTORY), q.get(Quota.NAMESPACE),
counts.get(Content.DISKSPACE), getDsQuota()); counts.get(Content.DISKSPACE), q.get(Quota.DISKSPACE));
} }
/** /**
@ -412,18 +413,15 @@ public abstract class INode implements INodeAttributes, Diff.Element<byte[]> {
/** /**
* Get the quota set for this inode * Get the quota set for this inode
* @return the quota if it is set; -1 otherwise * @return the quota counts. The count is -1 if it is not set.
*/ */
public long getNsQuota() { public Quota.Counts getQuotaCounts() {
return -1; return Quota.Counts.newInstance(-1, -1);
}
public long getDsQuota() {
return -1;
} }
public final boolean isQuotaSet() { public final boolean isQuotaSet() {
return getNsQuota() >= 0 || getDsQuota() >= 0; final Quota.Counts q = getQuotaCounts();
return q.get(Quota.NAMESPACE) >= 0 || q.get(Quota.DISKSPACE) >= 0;
} }
/** /**

View File

@ -612,8 +612,7 @@ public class INodeDirectory extends INodeWithAdditionalFields
@Override @Override
public boolean metadataEquals(INodeDirectoryAttributes other) { public boolean metadataEquals(INodeDirectoryAttributes other) {
return other != null return other != null
&& getNsQuota() == other.getNsQuota() && getQuotaCounts().equals(other.getQuotaCounts())
&& getDsQuota() == other.getDsQuota()
&& getPermissionLong() == other.getPermissionLong(); && getPermissionLong() == other.getPermissionLong();
} }

View File

@ -27,9 +27,7 @@ import com.google.common.base.Preconditions;
*/ */
@InterfaceAudience.Private @InterfaceAudience.Private
public interface INodeDirectoryAttributes extends INodeAttributes { public interface INodeDirectoryAttributes extends INodeAttributes {
public long getNsQuota(); public Quota.Counts getQuotaCounts();
public long getDsQuota();
public boolean metadataEquals(INodeDirectoryAttributes other); public boolean metadataEquals(INodeDirectoryAttributes other);
@ -46,20 +44,14 @@ public interface INodeDirectoryAttributes extends INodeAttributes {
} }
@Override @Override
public long getNsQuota() { public Quota.Counts getQuotaCounts() {
return -1; return Quota.Counts.newInstance(-1, -1);
}
@Override
public long getDsQuota() {
return -1;
} }
@Override @Override
public boolean metadataEquals(INodeDirectoryAttributes other) { public boolean metadataEquals(INodeDirectoryAttributes other) {
return other != null return other != null
&& getNsQuota() == other.getNsQuota() && this.getQuotaCounts().equals(other.getQuotaCounts())
&& getDsQuota() == other.getDsQuota()
&& getPermissionLong() == other.getPermissionLong(); && getPermissionLong() == other.getPermissionLong();
} }
} }
@ -68,6 +60,7 @@ public interface INodeDirectoryAttributes extends INodeAttributes {
private final long nsQuota; private final long nsQuota;
private final long dsQuota; private final long dsQuota;
public CopyWithQuota(byte[] name, PermissionStatus permissions, public CopyWithQuota(byte[] name, PermissionStatus permissions,
long modificationTime, long nsQuota, long dsQuota) { long modificationTime, long nsQuota, long dsQuota) {
super(name, permissions, modificationTime); super(name, permissions, modificationTime);
@ -78,18 +71,14 @@ public interface INodeDirectoryAttributes extends INodeAttributes {
public CopyWithQuota(INodeDirectory dir) { public CopyWithQuota(INodeDirectory dir) {
super(dir); super(dir);
Preconditions.checkArgument(dir.isQuotaSet()); Preconditions.checkArgument(dir.isQuotaSet());
this.nsQuota = dir.getNsQuota(); final Quota.Counts q = dir.getQuotaCounts();
this.dsQuota = dir.getDsQuota(); this.nsQuota = q.get(Quota.NAMESPACE);
this.dsQuota = q.get(Quota.DISKSPACE);
} }
@Override @Override
public final long getNsQuota() { public Quota.Counts getQuotaCounts() {
return nsQuota; return Quota.Counts.newInstance(nsQuota, dsQuota);
}
@Override
public final long getDsQuota() {
return dsQuota;
} }
} }
} }

View File

@ -44,7 +44,7 @@ public class INodeDirectoryWithQuota extends INodeDirectory {
* @param dsQuota Diskspace quota to be assigned to this indoe * @param dsQuota Diskspace quota to be assigned to this indoe
* @param other The other inode from which all other properties are copied * @param other The other inode from which all other properties are copied
*/ */
public INodeDirectoryWithQuota(INodeDirectory other, boolean adopt, INodeDirectoryWithQuota(INodeDirectory other, boolean adopt,
long nsQuota, long dsQuota) { long nsQuota, long dsQuota) {
super(other, adopt); super(other, adopt);
final Quota.Counts counts = other.computeQuotaUsage(); final Quota.Counts counts = other.computeQuotaUsage();
@ -54,6 +54,11 @@ public class INodeDirectoryWithQuota extends INodeDirectory {
this.dsQuota = dsQuota; this.dsQuota = dsQuota;
} }
public INodeDirectoryWithQuota(INodeDirectory other, boolean adopt,
Quota.Counts quota) {
this(other, adopt, quota.get(Quota.NAMESPACE), quota.get(Quota.DISKSPACE));
}
/** constructor with no quota verification */ /** constructor with no quota verification */
INodeDirectoryWithQuota(long id, byte[] name, PermissionStatus permissions, INodeDirectoryWithQuota(long id, byte[] name, PermissionStatus permissions,
long modificationTime, long nsQuota, long dsQuota) { long modificationTime, long nsQuota, long dsQuota) {
@ -67,20 +72,9 @@ public class INodeDirectoryWithQuota extends INodeDirectory {
super(id, name, permissions, 0L); super(id, name, permissions, 0L);
} }
/** Get this directory's namespace quota
* @return this directory's namespace quota
*/
@Override @Override
public long getNsQuota() { public Quota.Counts getQuotaCounts() {
return nsQuota; return Quota.Counts.newInstance(nsQuota, dsQuota);
}
/** Get this directory's diskspace quota
* @return this directory's diskspace quota
*/
@Override
public long getDsQuota() {
return dsQuota;
} }
/** Set this directory's quota /** Set this directory's quota
@ -120,7 +114,7 @@ public class INodeDirectoryWithQuota extends INodeDirectory {
} }
private void checkDiskspace(final long computed) { private void checkDiskspace(final long computed) {
if (-1 != getDsQuota() && diskspace != computed) { if (-1 != getQuotaCounts().get(Quota.DISKSPACE) && diskspace != computed) {
NameNode.LOG.error("BUG: Inconsistent diskspace for directory " NameNode.LOG.error("BUG: Inconsistent diskspace for directory "
+ getFullPathName() + ". Cached = " + diskspace + getFullPathName() + ". Cached = " + diskspace
+ " != Computed = " + computed); + " != Computed = " + computed);

View File

@ -295,13 +295,8 @@ public abstract class INodeReference extends INode {
} }
@Override @Override
public final long getNsQuota() { public Quota.Counts getQuotaCounts() {
return referred.getNsQuota(); return referred.getQuotaCounts();
}
@Override
public final long getDsQuota() {
return referred.getDsQuota();
} }
@Override @Override

View File

@ -23,7 +23,6 @@ import java.io.IOException;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean; import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage; import java.lang.management.MemoryUsage;
import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI; import java.net.URI;
import java.net.URLEncoder; import java.net.URLEncoder;
@ -62,7 +61,6 @@ import org.apache.hadoop.hdfs.server.namenode.startupprogress.Status;
import org.apache.hadoop.hdfs.server.namenode.startupprogress.Step; import org.apache.hadoop.hdfs.server.namenode.startupprogress.Step;
import org.apache.hadoop.hdfs.server.namenode.startupprogress.StepType; import org.apache.hadoop.hdfs.server.namenode.startupprogress.StepType;
import org.apache.hadoop.hdfs.server.protocol.NamenodeProtocols; import org.apache.hadoop.hdfs.server.protocol.NamenodeProtocols;
import org.apache.hadoop.http.HttpConfig;
import org.apache.hadoop.io.Text; import org.apache.hadoop.io.Text;
import org.apache.hadoop.net.NodeBase; import org.apache.hadoop.net.NodeBase;
import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation;
@ -1092,7 +1090,7 @@ class NamenodeJspHelper {
doc.endTag(); doc.endTag();
doc.startTag("ds_quota"); doc.startTag("ds_quota");
doc.pcdata(""+inode.getDsQuota()); doc.pcdata(""+inode.getQuotaCounts().get(Quota.DISKSPACE));
doc.endTag(); doc.endTag();
doc.startTag("permission_status"); doc.startTag("permission_status");

View File

@ -41,7 +41,7 @@ public enum Quota {
} }
Counts() { Counts() {
super(Quota.values()); super(Quota.class);
} }
} }

View File

@ -491,7 +491,7 @@ public class INodeDirectoryWithSnapshot extends INodeDirectoryWithQuota {
INodeDirectoryWithSnapshot(INodeDirectory that, boolean adopt, INodeDirectoryWithSnapshot(INodeDirectory that, boolean adopt,
DirectoryDiffList diffs) { DirectoryDiffList diffs) {
super(that, adopt, that.getNsQuota(), that.getDsQuota()); super(that, adopt, that.getQuotaCounts());
this.diffs = diffs != null? diffs: new DirectoryDiffList(); this.diffs = diffs != null? diffs: new DirectoryDiffList();
} }

View File

@ -17,6 +17,7 @@
*/ */
package org.apache.hadoop.hdfs.util; package org.apache.hadoop.hdfs.util;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
@ -34,21 +35,19 @@ import com.google.common.base.Preconditions;
* @param <E> the enum type * @param <E> the enum type
*/ */
public class EnumCounters<E extends Enum<E>> { public class EnumCounters<E extends Enum<E>> {
/** An array of enum constants. */ /** The class of the enum. */
private final E[] enumConstants; private final Class<E> enumClass;
/** The counter array, counters[i] corresponds to the enumConstants[i]. */ /** The counter array, counters[i] corresponds to the enumConstants[i]. */
private final long[] counters; private final long[] counters;
/** /**
* Construct counters for the given enum constants. * Construct counters for the given enum constants.
* @param enumConstants an array of enum constants such that, * @param enumClass the enum class of the counters.
* for all i, enumConstants[i].ordinal() == i.
*/ */
public EnumCounters(final E[] enumConstants) { public EnumCounters(final Class<E> enumClass) {
for(int i = 0; i < enumConstants.length; i++) { final E[] enumConstants = enumClass.getEnumConstants();
Preconditions.checkArgument(enumConstants[i].ordinal() == i); Preconditions.checkNotNull(enumConstants);
} this.enumClass = enumClass;
this.enumConstants = enumConstants;
this.counters = new long[enumConstants.length]; this.counters = new long[enumConstants.length];
} }
@ -69,6 +68,13 @@ public class EnumCounters<E extends Enum<E>> {
counters[e.ordinal()] = value; counters[e.ordinal()] = value;
} }
/** Set this counters to that counters. */
public final void set(final EnumCounters<E> that) {
for(int i = 0; i < counters.length; i++) {
this.counters[i] = that.counters[i];
}
}
/** Add the given value to counter e. */ /** Add the given value to counter e. */
public final void add(final E e, final long value) { public final void add(final E e, final long value) {
counters[e.ordinal()] += value; counters[e.ordinal()] += value;
@ -86,15 +92,33 @@ public class EnumCounters<E extends Enum<E>> {
counters[e.ordinal()] -= value; counters[e.ordinal()] -= value;
} }
/** Subtract that counters from this counters. */ /** Subtract this counters from that counters. */
public final void subtract(final EnumCounters<E> that) { public final void subtract(final EnumCounters<E> that) {
for(int i = 0; i < counters.length; i++) { for(int i = 0; i < counters.length; i++) {
this.counters[i] -= that.counters[i]; this.counters[i] -= that.counters[i];
} }
} }
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
} else if (obj == null || !(obj instanceof EnumCounters)) {
return false;
}
final EnumCounters<?> that = (EnumCounters<?>)obj;
return this.enumClass == that.enumClass
&& Arrays.equals(this.counters, that.counters);
}
@Override
public int hashCode() {
return Arrays.hashCode(counters);
}
@Override @Override
public String toString() { public String toString() {
final E[] enumConstants = enumClass.getEnumConstants();
final StringBuilder b = new StringBuilder(); final StringBuilder b = new StringBuilder();
for(int i = 0; i < counters.length; i++) { for(int i = 0; i < counters.length; i++) {
final String name = enumConstants[i].name(); final String name = enumConstants[i].name();

View File

@ -554,7 +554,7 @@ public abstract class FSImageTestUtil {
* get NameSpace quota. * get NameSpace quota.
*/ */
public static long getNSQuota(FSNamesystem ns) { public static long getNSQuota(FSNamesystem ns) {
return ns.dir.rootDir.getNsQuota(); return ns.dir.rootDir.getQuotaCounts().get(Quota.NAMESPACE);
} }
public static void assertNNFilesMatch(MiniDFSCluster cluster) throws Exception { public static void assertNNFilesMatch(MiniDFSCluster cluster) throws Exception {