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;
import de.ovgu.cide.jakutil.*;
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" + "-------- --------- ------";
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);
}
}
}