001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.hadoop.hdfs.protocol; 019 020 import java.io.PrintStream; 021 import java.text.SimpleDateFormat; 022 import java.util.Comparator; 023 import java.util.Date; 024 025 import org.apache.hadoop.fs.Path; 026 import org.apache.hadoop.fs.permission.FsPermission; 027 import org.apache.hadoop.hdfs.DFSUtil; 028 029 /** 030 * Metadata about a snapshottable directory 031 */ 032 public class SnapshottableDirectoryStatus { 033 /** Compare the statuses by full paths. */ 034 public static final Comparator<SnapshottableDirectoryStatus> COMPARATOR 035 = new Comparator<SnapshottableDirectoryStatus>() { 036 @Override 037 public int compare(SnapshottableDirectoryStatus left, 038 SnapshottableDirectoryStatus right) { 039 int d = DFSUtil.compareBytes(left.parentFullPath, right.parentFullPath); 040 return d != 0? d 041 : DFSUtil.compareBytes(left.dirStatus.getLocalNameInBytes(), 042 right.dirStatus.getLocalNameInBytes()); 043 } 044 }; 045 046 /** Basic information of the snapshottable directory */ 047 private HdfsFileStatus dirStatus; 048 049 /** Number of snapshots that have been taken*/ 050 private int snapshotNumber; 051 052 /** Number of snapshots allowed. */ 053 private int snapshotQuota; 054 055 /** Full path of the parent. */ 056 private byte[] parentFullPath; 057 058 public SnapshottableDirectoryStatus(long modification_time, long access_time, 059 FsPermission permission, String owner, String group, byte[] localName, 060 long inodeId, int childrenNum, 061 int snapshotNumber, int snapshotQuota, byte[] parentFullPath) { 062 this.dirStatus = new HdfsFileStatus(0, true, 0, 0, modification_time, 063 access_time, permission, owner, group, null, localName, inodeId, 064 childrenNum); 065 this.snapshotNumber = snapshotNumber; 066 this.snapshotQuota = snapshotQuota; 067 this.parentFullPath = parentFullPath; 068 } 069 070 /** 071 * @return Number of snapshots that have been taken for the directory 072 */ 073 public int getSnapshotNumber() { 074 return snapshotNumber; 075 } 076 077 /** 078 * @return Number of snapshots allowed for the directory 079 */ 080 public int getSnapshotQuota() { 081 return snapshotQuota; 082 } 083 084 /** 085 * @return Full path of the parent 086 */ 087 public byte[] getParentFullPath() { 088 return parentFullPath; 089 } 090 091 /** 092 * @return The basic information of the directory 093 */ 094 public HdfsFileStatus getDirStatus() { 095 return dirStatus; 096 } 097 098 /** 099 * @return Full path of the file 100 */ 101 public Path getFullPath() { 102 String parentFullPathStr = 103 (parentFullPath == null || parentFullPath.length == 0) ? 104 null : DFSUtil.bytes2String(parentFullPath); 105 if (parentFullPathStr == null 106 && dirStatus.getLocalNameInBytes().length == 0) { 107 // root 108 return new Path("/"); 109 } else { 110 return parentFullPathStr == null ? new Path(dirStatus.getLocalName()) 111 : new Path(parentFullPathStr, dirStatus.getLocalName()); 112 } 113 } 114 115 /** 116 * Print a list of {@link SnapshottableDirectoryStatus} out to a given stream. 117 * @param stats The list of {@link SnapshottableDirectoryStatus} 118 * @param out The given stream for printing. 119 */ 120 public static void print(SnapshottableDirectoryStatus[] stats, 121 PrintStream out) { 122 if (stats == null || stats.length == 0) { 123 out.println(); 124 return; 125 } 126 int maxRepl = 0, maxLen = 0, maxOwner = 0, maxGroup = 0; 127 int maxSnapshotNum = 0, maxSnapshotQuota = 0; 128 for (SnapshottableDirectoryStatus status : stats) { 129 maxRepl = maxLength(maxRepl, status.dirStatus.getReplication()); 130 maxLen = maxLength(maxLen, status.dirStatus.getLen()); 131 maxOwner = maxLength(maxOwner, status.dirStatus.getOwner()); 132 maxGroup = maxLength(maxGroup, status.dirStatus.getGroup()); 133 maxSnapshotNum = maxLength(maxSnapshotNum, status.snapshotNumber); 134 maxSnapshotQuota = maxLength(maxSnapshotQuota, status.snapshotQuota); 135 } 136 137 StringBuilder fmt = new StringBuilder(); 138 fmt.append("%s%s "); // permission string 139 fmt.append("%" + maxRepl + "s "); 140 fmt.append((maxOwner > 0) ? "%-" + maxOwner + "s " : "%s"); 141 fmt.append((maxGroup > 0) ? "%-" + maxGroup + "s " : "%s"); 142 fmt.append("%" + maxLen + "s "); 143 fmt.append("%s "); // mod time 144 fmt.append("%" + maxSnapshotNum + "s "); 145 fmt.append("%" + maxSnapshotQuota + "s "); 146 fmt.append("%s"); // path 147 148 String lineFormat = fmt.toString(); 149 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 150 151 for (SnapshottableDirectoryStatus status : stats) { 152 String line = String.format(lineFormat, "d", 153 status.dirStatus.getPermission(), 154 status.dirStatus.getReplication(), 155 status.dirStatus.getOwner(), 156 status.dirStatus.getGroup(), 157 String.valueOf(status.dirStatus.getLen()), 158 dateFormat.format(new Date(status.dirStatus.getModificationTime())), 159 status.snapshotNumber, status.snapshotQuota, 160 status.getFullPath().toString() 161 ); 162 out.println(line); 163 } 164 } 165 166 private static int maxLength(int n, Object value) { 167 return Math.max(n, String.valueOf(value).length()); 168 } 169 }