1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.hadoop.hdfs.protocol; 19 20 import java.io.PrintStream; 21 import java.text.SimpleDateFormat; 22 import java.util.Comparator; 23 import java.util.Date; 24 25 import org.apache.hadoop.fs.Path; 26 import org.apache.hadoop.fs.permission.FsPermission; 27 import org.apache.hadoop.hdfs.DFSUtil; 28 import org.apache.hadoop.hdfs.server.blockmanagement.BlockStoragePolicySuite; 29 30 /** 31 * Metadata about a snapshottable directory 32 */ 33 public class SnapshottableDirectoryStatus { 34 /** Compare the statuses by full paths. */ 35 public static final Comparator<SnapshottableDirectoryStatus> COMPARATOR 36 = new Comparator<SnapshottableDirectoryStatus>() { 37 @Override 38 public int compare(SnapshottableDirectoryStatus left, 39 SnapshottableDirectoryStatus right) { 40 int d = DFSUtil.compareBytes(left.parentFullPath, right.parentFullPath); 41 return d != 0? d 42 : DFSUtil.compareBytes(left.dirStatus.getLocalNameInBytes(), 43 right.dirStatus.getLocalNameInBytes()); 44 } 45 }; 46 47 /** Basic information of the snapshottable directory */ 48 private final HdfsFileStatus dirStatus; 49 50 /** Number of snapshots that have been taken*/ 51 private final int snapshotNumber; 52 53 /** Number of snapshots allowed. */ 54 private final int snapshotQuota; 55 56 /** Full path of the parent. */ 57 private final byte[] parentFullPath; 58 SnapshottableDirectoryStatus(long modification_time, long access_time, FsPermission permission, String owner, String group, byte[] localName, long inodeId, int childrenNum, int snapshotNumber, int snapshotQuota, byte[] parentFullPath)59 public SnapshottableDirectoryStatus(long modification_time, long access_time, 60 FsPermission permission, String owner, String group, byte[] localName, 61 long inodeId, int childrenNum, 62 int snapshotNumber, int snapshotQuota, byte[] parentFullPath) { 63 this.dirStatus = new HdfsFileStatus(0, true, 0, 0, modification_time, 64 access_time, permission, owner, group, null, localName, inodeId, 65 childrenNum, null, BlockStoragePolicySuite.ID_UNSPECIFIED); 66 this.snapshotNumber = snapshotNumber; 67 this.snapshotQuota = snapshotQuota; 68 this.parentFullPath = parentFullPath; 69 } 70 71 /** 72 * @return Number of snapshots that have been taken for the directory 73 */ getSnapshotNumber()74 public int getSnapshotNumber() { 75 return snapshotNumber; 76 } 77 78 /** 79 * @return Number of snapshots allowed for the directory 80 */ getSnapshotQuota()81 public int getSnapshotQuota() { 82 return snapshotQuota; 83 } 84 85 /** 86 * @return Full path of the parent 87 */ getParentFullPath()88 public byte[] getParentFullPath() { 89 return parentFullPath; 90 } 91 92 /** 93 * @return The basic information of the directory 94 */ getDirStatus()95 public HdfsFileStatus getDirStatus() { 96 return dirStatus; 97 } 98 99 /** 100 * @return Full path of the file 101 */ getFullPath()102 public Path getFullPath() { 103 String parentFullPathStr = 104 (parentFullPath == null || parentFullPath.length == 0) ? 105 null : DFSUtil.bytes2String(parentFullPath); 106 if (parentFullPathStr == null 107 && dirStatus.getLocalNameInBytes().length == 0) { 108 // root 109 return new Path("/"); 110 } else { 111 return parentFullPathStr == null ? new Path(dirStatus.getLocalName()) 112 : new Path(parentFullPathStr, dirStatus.getLocalName()); 113 } 114 } 115 116 /** 117 * Print a list of {@link SnapshottableDirectoryStatus} out to a given stream. 118 * @param stats The list of {@link SnapshottableDirectoryStatus} 119 * @param out The given stream for printing. 120 */ print(SnapshottableDirectoryStatus[] stats, PrintStream out)121 public static void print(SnapshottableDirectoryStatus[] stats, 122 PrintStream out) { 123 if (stats == null || stats.length == 0) { 124 out.println(); 125 return; 126 } 127 int maxRepl = 0, maxLen = 0, maxOwner = 0, maxGroup = 0; 128 int maxSnapshotNum = 0, maxSnapshotQuota = 0; 129 for (SnapshottableDirectoryStatus status : stats) { 130 maxRepl = maxLength(maxRepl, status.dirStatus.getReplication()); 131 maxLen = maxLength(maxLen, status.dirStatus.getLen()); 132 maxOwner = maxLength(maxOwner, status.dirStatus.getOwner()); 133 maxGroup = maxLength(maxGroup, status.dirStatus.getGroup()); 134 maxSnapshotNum = maxLength(maxSnapshotNum, status.snapshotNumber); 135 maxSnapshotQuota = maxLength(maxSnapshotQuota, status.snapshotQuota); 136 } 137 138 StringBuilder fmt = new StringBuilder(); 139 fmt.append("%s%s "); // permission string 140 fmt.append("%" + maxRepl + "s "); 141 fmt.append((maxOwner > 0) ? "%-" + maxOwner + "s " : "%s"); 142 fmt.append((maxGroup > 0) ? "%-" + maxGroup + "s " : "%s"); 143 fmt.append("%" + maxLen + "s "); 144 fmt.append("%s "); // mod time 145 fmt.append("%" + maxSnapshotNum + "s "); 146 fmt.append("%" + maxSnapshotQuota + "s "); 147 fmt.append("%s"); // path 148 149 String lineFormat = fmt.toString(); 150 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 151 152 for (SnapshottableDirectoryStatus status : stats) { 153 String line = String.format(lineFormat, "d", 154 status.dirStatus.getPermission(), 155 status.dirStatus.getReplication(), 156 status.dirStatus.getOwner(), 157 status.dirStatus.getGroup(), 158 String.valueOf(status.dirStatus.getLen()), 159 dateFormat.format(new Date(status.dirStatus.getModificationTime())), 160 status.snapshotNumber, status.snapshotQuota, 161 status.getFullPath().toString() 162 ); 163 out.println(line); 164 } 165 } 166 maxLength(int n, Object value)167 private static int maxLength(int n, Object value) { 168 return Math.max(n, String.valueOf(value).length()); 169 } 170 171 public static class Bean { 172 private final String path; 173 private final int snapshotNumber; 174 private final int snapshotQuota; 175 private final long modificationTime; 176 private final short permission; 177 private final String owner; 178 private final String group; 179 Bean(String path, int snapshotNumber, int snapshotQuota, long modificationTime, short permission, String owner, String group)180 public Bean(String path, int snapshotNumber, int snapshotQuota, 181 long modificationTime, short permission, String owner, String group) { 182 this.path = path; 183 this.snapshotNumber = snapshotNumber; 184 this.snapshotQuota = snapshotQuota; 185 this.modificationTime = modificationTime; 186 this.permission = permission; 187 this.owner = owner; 188 this.group = group; 189 } 190 getPath()191 public String getPath() { 192 return path; 193 } 194 getSnapshotNumber()195 public int getSnapshotNumber() { 196 return snapshotNumber; 197 } 198 getSnapshotQuota()199 public int getSnapshotQuota() { 200 return snapshotQuota; 201 } 202 getModificationTime()203 public long getModificationTime() { 204 return modificationTime; 205 } 206 getPermission()207 public short getPermission() { 208 return permission; 209 } 210 getOwner()211 public String getOwner() { 212 return owner; 213 } 214 getGroup()215 public String getGroup() { 216 return group; 217 } 218 } 219 } 220