/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002-2006
* Sleepycat Software. All rights reserved.
*
* $Id: DbSpace.java,v 1.17 2006/01/05 03:18:15 mark Exp $
*/
package com.sleepycat.je.util;
import java.io.File;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.DbInternal;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.JEVersion;
import com.sleepycat.je.cleaner.FileSummary;
import com.sleepycat.je.cleaner.UtilizationProfile;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.utilint.CmdUtil;
public class DbSpace {
private static final String USAGE =
"usage: " + CmdUtil.getJavaCommand(DbSpace.class) + "\n" +
" -h <dir> # environment home directory\n" +
" [-q] # quiet, print grand totals only\n" +
" [-u] # sort by utilization\n" +
" [-d] # dump file summary details\n" +
" [-V] # print JE version number";
public static void main(String argv[])
throws DatabaseException {
DbSpace space = new DbSpace();
space.parseArgs(argv);
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setReadOnly(true);
Environment env = new Environment(space.envHome, envConfig);
space.envImpl = DbInternal.envGetEnvironmentImpl(env);
try {
space.print(System.out);
System.exit(0);
} catch (Throwable e) {
e.printStackTrace(System.err);
System.exit(1);
} finally {
try {
env.close();
} catch (Throwable e) {
e.printStackTrace(System.err);
System.exit(1);
}
}
}
private File envHome = null;
private EnvironmentImpl envImpl;
private boolean quiet = false;
private boolean sorted = false;
private boolean details = false;
private DbSpace() {
}
public DbSpace(Environment env,
boolean quiet,
boolean details,
boolean sorted) {
this(DbInternal.envGetEnvironmentImpl(env), quiet, details, sorted);
}
public DbSpace(EnvironmentImpl envImpl,
boolean quiet,
boolean details,
boolean sorted) {
this.envImpl = envImpl;
this.quiet = quiet;
this.details = details;
this.sorted = sorted;
}
private void printUsage(String msg) {
if (msg != null) {
System.err.println(msg);
}
System.err.println(USAGE);
System.exit(-1);
}
private void parseArgs(String argv[]) {
int argc = 0;
int nArgs = argv.length;
if (nArgs == 0) {
printUsage(null);
System.exit(0);
}
while (argc < nArgs) {
String thisArg = argv[argc++];
if (thisArg.equals("-q")) {
quiet = true;
} else if (thisArg.equals("-u")) {
sorted = true;
} else if (thisArg.equals("-d")) {
details = true;
} else if (thisArg.equals("-V")) {
System.out.println(JEVersion.CURRENT_VERSION);
System.exit(0);
} else if (thisArg.equals("-h")) {
if (argc < nArgs) {
envHome = new File(argv[argc++]);
} else {
printUsage("-h requires an argument");
}
}
}
if (envHome == null) {
printUsage("-h is a required argument");
}
}
public void print(PrintStream out)
throws DatabaseException {
UtilizationProfile profile = envImpl.getUtilizationProfile();
SortedMap map = profile.getFileSummaryMap(false);
int fileIndex = 0;
Summary totals = new Summary();
Summary[] summaries = null;
if (!quiet) {
summaries = new Summary[map.size()];
}
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Long fileNum = (Long) entry.getKey();
FileSummary fs = (FileSummary) entry.getValue();
Summary summary = new Summary(fileNum, fs);
if (summaries != null) {
summaries[fileIndex] = summary;
}
if (details) {
out.println
("File 0x" + Long.toHexString(fileNum.longValue()) +
": " + fs);
}
totals.add(summary);
fileIndex += 1;
}
if (details) {
out.println();
}
out.println(Summary.HEADER);
if (summaries != null) {
if (sorted) {
Arrays.sort(summaries);
}
for (int i = 0; i < summaries.length; i += 1) {
summaries[i].print(out);
}
}
totals.print(out);
}
private static class Summary implements Comparable {
static final String HEADER = " File Size (KB) % Used\n" +
"-------- --------- ------";
// 12345678 123456789 123
// 12 12345
// TOTALS:
Long fileNum;
long totalSize;
long obsoleteSize;
Summary() {}
Summary(Long fileNum, FileSummary summary)
throws DatabaseException {
this.fileNum = fileNum;
totalSize = summary.totalSize;
obsoleteSize = summary.getObsoleteSize();
}
public int compareTo(Object other) {
Summary o = (Summary) other;
return utilization() - o.utilization();
}
void add(Summary o) {
totalSize += o.totalSize;
obsoleteSize += o.obsoleteSize;
}
void print(PrintStream out) {
if (fileNum != null) {
pad(out, Long.toHexString(fileNum.longValue()), 8, '0');
} else {
out.print(" TOTALS ");
}
int kb = (int) (totalSize / 1024);
int util = utilization();
out.print(" ");
pad(out, Integer.toString(kb), 9, ' ');
out.print(" ");
pad(out, Integer.toString(util), 3, ' ');
out.println();
}
int utilization() {
return UtilizationProfile.utilization(obsoleteSize, totalSize);
}
private void pad(PrintStream out, String val, int digits,
char padChar) {
int padSize = digits - val.length();
for (int i = 0; i < padSize; i += 1) {
out.print(padChar);
}
out.print(val);
}
}
}