001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.objectserver.persistence.sleepycat;
005:
006: import com.sleepycat.je.Cursor;
007: import com.sleepycat.je.CursorConfig;
008: import com.sleepycat.je.Database;
009: import com.sleepycat.je.DatabaseConfig;
010: import com.sleepycat.je.DatabaseEntry;
011: import com.sleepycat.je.DatabaseException;
012: import com.sleepycat.je.Environment;
013: import com.sleepycat.je.EnvironmentConfig;
014: import com.sleepycat.je.LockMode;
015: import com.sleepycat.je.OperationStatus;
016:
017: import java.io.File;
018: import java.util.Iterator;
019: import java.util.List;
020:
021: public class SleepycatDBUsage {
022:
023: private static final int LEFT = 1;
024: private static final int RIGHT = 2;
025: private static final int CENTER = 3;
026:
027: private EnvironmentConfig enc;
028: private Environment env;
029: private long grandTotal;
030: private long totalCount;
031: private DatabaseConfig dbc;
032: private boolean header = true;
033: private long keyTotal;
034: private long valuesTotal;
035:
036: public SleepycatDBUsage(File dir) throws Exception {
037: enc = new EnvironmentConfig();
038: enc.setReadOnly(true);
039: env = new Environment(dir, enc);
040: dbc = new DatabaseConfig();
041: dbc.setReadOnly(true);
042: }
043:
044: public void report() throws DatabaseException {
045: List dbs = env.getDatabaseNames();
046: log("Databases in the enviroment : " + dbs);
047:
048: log("\nReport on individual databases :\n================================\n");
049: for (Iterator i = dbs.iterator(); i.hasNext();) {
050: String dbNAme = (String) i.next();
051: Database db = env.openDatabase(null, dbNAme, dbc);
052: DBStats stats = calculate(db);
053: db.close();
054: report(stats);
055: }
056: reportGrandTotals();
057: }
058:
059: private void reportGrandTotals() {
060: log("\n");
061: log(" TOTAL : ", String.valueOf(totalCount), "", "", "",
062: String.valueOf(keyTotal), "", "", "", String
063: .valueOf(valuesTotal), String
064: .valueOf(grandTotal));
065: }
066:
067: private DBStats calculate(Database db) throws DatabaseException {
068: CursorConfig config = new CursorConfig();
069: Cursor c = db.openCursor(null, config);
070: DBStats stats = new DBStats(db.getDatabaseName());
071: DatabaseEntry key = new DatabaseEntry();
072: DatabaseEntry value = new DatabaseEntry();
073: while (OperationStatus.SUCCESS.equals(c.getNext(key, value,
074: LockMode.DEFAULT))) {
075: stats.record(key.getData().length, value.getData().length);
076: }
077: c.close();
078: return stats;
079: }
080:
081: private void report(DBStats stats) {
082: if (header) {
083: log("DBName", "# Records", "Keys(Bytes)", "Values(Bytes)",
084: "Total(Bytes)");
085: log("", "", "min", "max", "avg", "total", "min", "max",
086: "avg", "total", "");
087: log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
088: header = false;
089: }
090: log(stats.getDatabaseName(), stats.getRecordCount(), stats
091: .getKeyMin(), stats.getKeyMax(), stats.getKeyAvg(),
092: stats.getTotalKeySize(), stats.getValueMin(), stats
093: .getValueMax(), stats.getValueAvg(), stats
094: .getTotalValueSize(), stats.getTotalSize());
095: this .keyTotal += stats.getTotalKeySize();
096: this .valuesTotal += stats.getTotalValueSize();
097: this .grandTotal += stats.getTotalSize();
098: this .totalCount += stats.getRecordCount();
099: }
100:
101: private void log(String databaseName, long recordCount,
102: long keyMin, long keyMax, long keyAvg, long totalKeySize,
103: long valueMin, long valueMax, long valueAvg,
104: long totalValueSize, long totalSize) {
105: log(databaseName, String.valueOf(recordCount), String
106: .valueOf(keyMin), String.valueOf(keyMax), String
107: .valueOf(keyAvg), String.valueOf(totalKeySize), String
108: .valueOf(valueMin), String.valueOf(valueMax), String
109: .valueOf(valueAvg), String.valueOf(totalValueSize),
110: String.valueOf(totalSize));
111: }
112:
113: private static void log(String nameHeader, String countHeader,
114: String keyHeader, String valueHeader, String sizeHeader) {
115: log(format(nameHeader, 20, LEFT)
116: + format(countHeader, 10, RIGHT)
117: + format(keyHeader, 30, CENTER)
118: + format(valueHeader, 30, CENTER)
119: + format(sizeHeader, 15, RIGHT));
120: }
121:
122: private void log(String databaseName, String count, String kmin,
123: String kmax, String kavg, String kTot, String vmin,
124: String vmax, String vavg, String vTot, String totalSize) {
125: log(format(databaseName, 20, LEFT) + format(count, 10, RIGHT)
126: + format(kmin, 5, RIGHT) + format(kmax, 10, RIGHT)
127: + format(kavg, 5, RIGHT) + format(kTot, 10, RIGHT)
128: + format(vmin, 5, RIGHT) + format(vmax, 10, RIGHT)
129: + format(vavg, 5, RIGHT) + format(vTot, 10, RIGHT)
130: + format(totalSize, 15, RIGHT));
131: }
132:
133: private static String format(String s, int size, int justification) {
134: if (s == null || s.length() >= size) {
135: return s;
136: }
137: int diff = size - s.length();
138: if (justification == LEFT) {
139: return s + createSpaces(diff);
140: } else if (justification == RIGHT) {
141: return createSpaces(diff) + s;
142: } else {
143: return createSpaces(diff / 2) + s
144: + createSpaces(diff - (diff / 2));
145: }
146: }
147:
148: private static String createSpaces(int i) {
149: StringBuffer sb = new StringBuffer();
150: while (i-- > 0) {
151: sb.append(' ');
152: }
153: return sb.toString();
154: }
155:
156: public static void main(String[] args) {
157: if (args == null || args.length < 1) {
158: usage();
159: System.exit(1);
160: }
161:
162: try {
163: File dir = new File(args[0]);
164: validateDir(dir);
165: SleepycatDBUsage reporter = new SleepycatDBUsage(dir);
166: reporter.report();
167: } catch (Exception e) {
168: e.printStackTrace();
169: System.exit(2);
170: }
171: }
172:
173: private static void validateDir(File dir) {
174: if (!dir.exists() || !dir.isDirectory()) {
175: throw new RuntimeException("Not a valid directory : " + dir);
176: }
177: }
178:
179: private static void usage() {
180: log("Usage: SleepycatDBUsage <environment home directory>");
181: }
182:
183: private static void log(String message) {
184: System.out.println(message);
185: }
186:
187: private static final class DBStats {
188:
189: private long count;
190: private long keySize;
191: private long valueSize;
192: private long minKey;
193: private long maxKey;
194: private long minValue;
195: private long maxValue;
196: private final String databaseName;
197:
198: public DBStats(String databaseName) {
199: this .databaseName = databaseName;
200: }
201:
202: public long getValueAvg() {
203: return (count == 0 ? 0 : valueSize / count);
204: }
205:
206: public long getValueMax() {
207: return maxValue;
208: }
209:
210: public long getValueMin() {
211: return minValue;
212: }
213:
214: public long getKeyAvg() {
215: return (count == 0 ? 0 : keySize / count);
216: }
217:
218: public long getKeyMax() {
219: return maxKey;
220: }
221:
222: public long getKeyMin() {
223: return minKey;
224: }
225:
226: public long getTotalValueSize() {
227: return valueSize;
228: }
229:
230: public long getTotalKeySize() {
231: return keySize;
232: }
233:
234: public long getTotalSize() {
235: return keySize + valueSize;
236: }
237:
238: public String getValueStats() {
239: return valueSize + "(" + minValue + "/" + maxValue + "/"
240: + getValueAvg() + ")";
241: }
242:
243: public String getKeyStats() {
244: return keySize + "(" + minKey + "/" + maxKey + "/"
245: + getKeyAvg() + ")";
246: }
247:
248: public long getRecordCount() {
249: return count;
250: }
251:
252: public String getDatabaseName() {
253: return databaseName;
254: }
255:
256: public void record(int kSize, int vSize) {
257: count++;
258: keySize += kSize;
259: valueSize += vSize;
260: if (minKey == 0 || minKey > kSize) {
261: minKey = kSize;
262: }
263: if (maxKey < kSize) {
264: maxKey = kSize;
265: }
266: if (minValue == 0 || minValue > vSize) {
267: minValue = vSize;
268: }
269: if (maxValue < vSize) {
270: maxValue = vSize;
271: }
272: }
273:
274: }
275:
276: }
|