KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > log > UtilizationFileReader


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002-2006
5  * Oracle Corporation. All rights reserved.
6  *
7  * $Id: UtilizationFileReader.java,v 1.6 2006/11/21 02:50:25 linda Exp $
8  */

9
10 package com.sleepycat.je.log;
11
12 import java.io.IOException JavaDoc;
13 import java.nio.ByteBuffer JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19
20 import com.sleepycat.je.DatabaseException;
21 import com.sleepycat.je.cleaner.FileSummary;
22 import com.sleepycat.je.config.EnvironmentParams;
23 import com.sleepycat.je.dbi.EnvironmentImpl;
24 import com.sleepycat.je.log.entry.INLogEntry;
25 import com.sleepycat.je.log.entry.LNLogEntry;
26 import com.sleepycat.je.log.entry.LogEntry;
27 import com.sleepycat.je.log.entry.SingleItemLogEntry;
28 import com.sleepycat.je.tree.INDeleteInfo;
29 import com.sleepycat.je.tree.INDupDeleteInfo;
30 import com.sleepycat.je.tree.LN;
31 import com.sleepycat.je.tree.MapLN;
32 import com.sleepycat.je.txn.TxnCommit;
33 import com.sleepycat.je.txn.TxnEnd;
34 import com.sleepycat.je.utilint.DbLsn;
35
36 /**
37  * Summarizes the utilized and unutilized portion of each log file by examining
38  * each log entry. Does not use the Cleaner UtilizationProfile information in
39  * order to provide a second measure against which to evaluation the
40  * UtilizationProfile accuracy.
41  */

42 public class UtilizationFileReader extends FileReader {
43
44     private static final boolean DEBUG = true;
45
46     private Map JavaDoc summaries; // Long file -> FileSummary
47
private Map JavaDoc activeNodes; // Long node ID -> NodeInfo
48
private Map JavaDoc txns; // Long txn ID -> List of pairs, where each pair
49
// is [ExtendedFileSummary, LNLogEntry]
50
private List JavaDoc twoEntryList; // holds one [ExtendedFileSummary, LNLogEntry]
51

52     private UtilizationFileReader(EnvironmentImpl env, int readBufferSize)
53     throws IOException JavaDoc, DatabaseException {
54
55         super(env,
56               readBufferSize,
57               true, // read forward
58
DbLsn.NULL_LSN, // start LSN
59
null, // single file number
60
DbLsn.NULL_LSN, // end of file LSN
61
DbLsn.NULL_LSN); // finish LSN
62

63         summaries = new HashMap JavaDoc();
64         activeNodes = new HashMap JavaDoc();
65         txns = new HashMap JavaDoc();
66
67         twoEntryList = new ArrayList JavaDoc();
68         twoEntryList.add(null);
69         twoEntryList.add(null);
70     }
71
72     protected boolean isTargetEntry(byte logEntryTypeNumber,
73                                     byte logEntryTypeVersion) {
74         /* UtilizationTracker does not count the file header. */
75         return logEntryTypeNumber != LogEntryType.LOG_FILE_HEADER.getTypeNum();
76     }
77
78     protected boolean processEntry(ByteBuffer JavaDoc entryBuffer)
79         throws DatabaseException {
80
81         LogEntryType lastEntryType = LogEntryType.findType
82             (currentEntryTypeNum, currentEntryTypeVersion);
83     LogEntry entry = lastEntryType.getNewLogEntry();
84         entry.readEntry(entryBuffer, currentEntrySize,
85                         currentEntryTypeVersion, true);
86
87         Long JavaDoc fileNum = new Long JavaDoc(readBufferFileNum);
88         ExtendedFileSummary summary =
89             (ExtendedFileSummary) summaries.get(fileNum);
90         if (summary == null) {
91             summary = new ExtendedFileSummary();
92             summaries.put(fileNum, summary);
93         }
94
95         int size = getLastEntrySize();
96
97         summary.totalCount += 1;
98         summary.totalSize += size;
99         
100         if (entry instanceof LNLogEntry) {
101             LNLogEntry lnEntry = (LNLogEntry) entry;
102             if (DEBUG) {
103                 int otherSize = getLNEntrySize(lnEntry);
104                 if (size != otherSize) {
105                     System.out.println
106                         ("LogReader.getLastEntrySize=" + size +
107                          " LNLogEntry.getLogSize=" + otherSize +
108                          " " + lnEntry);
109                 }
110                 if (!lnEntry.getLN().isDeleted()) {
111                     otherSize = lnEntry.getLN().getTotalLastLoggedSize
112                         (lnEntry.getKey());
113                     if (size != otherSize) {
114                         System.out.println
115                             ("LogReader.getLastEntrySize=" + size +
116                              " LN.getTotalLastLoggedSize=" + otherSize +
117                              " " + lnEntry);
118                     }
119                 }
120             }
121             if (lnEntry.isTransactional()) {
122                 Long JavaDoc txnId = new Long JavaDoc(lnEntry.getTransactionId());
123                 List JavaDoc txnEntries = (List JavaDoc) txns.get(txnId);
124                 if (txnEntries == null) {
125                     txnEntries = new ArrayList JavaDoc();
126                     txns.put(txnId, txnEntries);
127                 }
128                 txnEntries.add(summary);
129                 txnEntries.add(lnEntry);
130             } else {
131                 twoEntryList.set(0, summary);
132                 twoEntryList.set(1, lnEntry);
133                 applyTxn(twoEntryList, true);
134             }
135         } else if (entry instanceof INLogEntry) {
136             INLogEntry inEntry = (INLogEntry) entry;
137             Long JavaDoc nodeId = new Long JavaDoc(inEntry.getNodeId());
138             summary.totalINCount += 1;
139             summary.totalINSize += size;
140             countObsoleteNode(nodeId);
141             putActiveNode(nodeId, size, summary,
142                           inEntry.getDbId().getId(),
143                           false);
144         } else if (entry instanceof SingleItemLogEntry) {
145             Object JavaDoc item = ((SingleItemLogEntry) entry).getMainItem();
146             long deletedNodeId = -1;
147             if (item instanceof INDeleteInfo) {
148                 deletedNodeId = ((INDeleteInfo) item).getDeletedNodeId();
149             } else if (item instanceof INDupDeleteInfo) {
150                 deletedNodeId = ((INDupDeleteInfo) item).getDeletedNodeId();
151             }
152             if (deletedNodeId != -1) {
153                 Long JavaDoc nodeId = new Long JavaDoc(deletedNodeId);
154                 countObsoleteNode(nodeId);
155                 activeNodes.remove(nodeId);
156             }
157             if (item instanceof TxnEnd) {
158                 Long JavaDoc txnId = new Long JavaDoc(((TxnEnd) item).getTransactionId());
159                 List JavaDoc txnEntries = (List JavaDoc) txns.remove(txnId);
160                 if (txnEntries != null) {
161                     applyTxn(txnEntries, item instanceof TxnCommit);
162                 }
163             }
164         }
165         
166         return true;
167     }
168
169     private void applyTxn(List JavaDoc entries, boolean commit) {
170         for (int i = 0; i < entries.size(); i += 2) {
171             ExtendedFileSummary summary = (ExtendedFileSummary) entries.get(i);
172             LNLogEntry lnEntry = (LNLogEntry) entries.get(i + 1);
173             LN ln = lnEntry.getLN();
174             int size = getLNEntrySize(lnEntry);
175
176             summary.totalLNCount += 1;
177             summary.totalLNSize += size;
178
179             if (!commit || ln.isDeleted()) {
180                 summary.obsoleteLNCount += 1;
181                 summary.recalcObsoleteLNSize += size;
182             }
183
184             if (commit) {
185                 Long JavaDoc nodeId = new Long JavaDoc(lnEntry.getNodeId());
186                 countObsoleteNode(nodeId);
187                 if (ln.isDeleted()) {
188                     activeNodes.remove(nodeId);
189                 } else {
190                     putActiveNode(nodeId, size, summary,
191                                   lnEntry.getDbId().getId(),
192                                   true);
193                 }
194             }
195
196             /* Process Database truncate or remove. */
197             if (commit && ln.isDeleted() && ln instanceof MapLN) {
198                 int dbId = ((MapLN) ln).getDatabase().getId().getId();
199                 Iterator JavaDoc iter = activeNodes.entrySet().iterator();
200                 while (iter.hasNext()) {
201                     Map.Entry JavaDoc iEntry = (Map.Entry JavaDoc) iter.next();
202                     NodeInfo info = (NodeInfo) iEntry.getValue();
203                     if (info.dbId == dbId) {
204                         Long JavaDoc nodeId = (Long JavaDoc) iEntry.getKey();
205                         countObsoleteNode(nodeId);
206                         iter.remove();
207                     }
208                 }
209             }
210         }
211     }
212
213     private void finishProcessing() {
214
215         /* Apply uncomitted transactions. */
216         Iterator JavaDoc txnIter = txns.values().iterator();
217         while (txnIter.hasNext()) {
218             List JavaDoc txnEntries = (List JavaDoc) txnIter.next();
219             applyTxn(txnEntries, false);
220         }
221     }
222
223     private void putActiveNode(Long JavaDoc nodeId,
224                                int size,
225                                ExtendedFileSummary summary,
226                                int dbId,
227                                boolean isLN) {
228         NodeInfo info = (NodeInfo) activeNodes.get(nodeId);
229         if (info == null) {
230             info = new NodeInfo();
231             activeNodes.put(nodeId, info);
232         }
233         info.size = size;
234         info.summary = summary;
235         info.dbId = dbId;
236         info.isLN = isLN;
237     }
238
239     private void countObsoleteNode(Long JavaDoc nodeId) {
240         NodeInfo info = (NodeInfo) activeNodes.get(nodeId);
241         if (info != null) {
242             ExtendedFileSummary summary = info.summary;
243             if (info.isLN) {
244                 summary.obsoleteLNCount += 1;
245                 summary.recalcObsoleteLNSize += info.size;
246             } else {
247                 summary.obsoleteINCount += 1;
248                 summary.recalcObsoleteINSize += info.size;
249             }
250         }
251     }
252
253     /**
254      * Get the log entry size of an LNLogEntry.
255      */

256     private int getLNEntrySize(LNLogEntry lnEntry) {
257         return lnEntry.getLogSize() + LogManager.HEADER_BYTES;
258     }
259     
260     /**
261      * Creates a UtilizationReader, reads the log, and returns the resulting
262      * Map of Long file number to FileSummary.
263      */

264     public static Map JavaDoc calcFileSummaryMap(EnvironmentImpl env)
265     throws IOException JavaDoc, DatabaseException {
266
267         int readBufferSize = env.getConfigManager().getInt
268             (EnvironmentParams.LOG_ITERATOR_READ_SIZE);
269
270         UtilizationFileReader reader =
271             new UtilizationFileReader(env, readBufferSize);
272         while (reader.readNextEntry()) {
273             /* All the work is done in processEntry. */
274         }
275
276         reader.finishProcessing();
277
278         return reader.summaries;
279     }
280
281     private static class ExtendedFileSummary extends FileSummary {
282         private int recalcObsoleteINSize;
283         private int recalcObsoleteLNSize;
284
285         /**
286          * Overrides the LN size calculation to return the recalculated number
287          * of obsolete LN bytes.
288          */

289         public int getObsoleteLNSize() {
290             return recalcObsoleteLNSize;
291         }
292
293         /**
294          * Overrides the IN size calculation to return the recalculated number
295          * of obsolete IN bytes.
296          */

297         public int getObsoleteINSize() {
298             return recalcObsoleteINSize;
299         }
300
301         /**
302          * Overrides to add the extended data fields.
303          */

304         public String JavaDoc toString() {
305             StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
306             buf.append(super.toString());
307             buf.append("<extended-info recalcObosleteINSize=\"");
308             buf.append(recalcObsoleteINSize);
309             buf.append("\" recalcObosletedLNSize=\"");
310             buf.append(recalcObsoleteLNSize);
311             buf.append("\"/>");
312             return buf.toString();
313         }
314     }
315
316     private static class NodeInfo {
317         ExtendedFileSummary summary;
318         int size;
319         int dbId;
320         boolean isLN;
321     }
322 }
323
Popular Tags