Source Code Cross Referenced for FileSummaryLN.java in  » JMX » je » com » sleepycat » je » tree » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » JMX » je » com.sleepycat.je.tree 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*-
002:         * See the file LICENSE for redistribution information.
003:         *
004:         * Copyright (c) 2002,2008 Oracle.  All rights reserved.
005:         *
006:         * $Id: FileSummaryLN.java,v 1.22.2.5 2008/01/07 15:14:16 cwl Exp $
007:         */
008:
009:        package com.sleepycat.je.tree;
010:
011:        import java.io.UnsupportedEncodingException;
012:        import java.nio.ByteBuffer;
013:
014:        import com.sleepycat.je.DatabaseException;
015:        import com.sleepycat.je.cleaner.FileSummary;
016:        import com.sleepycat.je.cleaner.PackedOffsets;
017:        import com.sleepycat.je.cleaner.TrackedFileSummary;
018:        import com.sleepycat.je.dbi.DatabaseImpl;
019:        import com.sleepycat.je.dbi.MemoryBudget;
020:        import com.sleepycat.je.log.LogEntryType;
021:        import com.sleepycat.je.log.LogException;
022:        import com.sleepycat.je.log.LogUtils;
023:
024:        /**
025:         * A FileSummaryLN represents a Leaf Node in the UtilizationProfile database.
026:         *
027:         * <p>The contents of the FileSummaryLN are not fixed until the moment at which
028:         * the LN is added to the log.  A base summary object contains the summary last
029:         * added to the log.  A tracked summary object contains live summary info being
030:         * updated in real time.  The tracked summary is added to the base summary just
031:         * before logging it, and then the tracked summary is reset.  This ensures that
032:         * the logged summary will accurately reflect the totals calculated at the
033:         * point in the log where the LN is added.</p>
034:         *
035:         * <p>This is all done in the writeToLog method, which operates under the log
036:         * write latch.  All utilization tracking must be done under the log write
037:         * latch.</p>
038:         *
039:         * <p>In record version 1, obsolete offset tracking was added and multiple
040:         * records are stored for a single file rather than a single record.  Each
041:         * record contains the offsets that were tracked since the last record was
042:         * written.
043:         *
044:         * <p>The key is 8 bytes: 4 bytes for the file number followed by 4 bytes for
045:         * the sequence number.  The lowest valued key for a given file contains the
046:         * most recent summary information, while to get a complete list of obsolete
047:         * offsets all records for the file must be read.  A range search using just
048:         * the first 4 bytes can be used to find the most recent record -- this is
049:         * possible because the sequence number values are decreasing over time for a
050:         * given file.  Here are example keys for three summary records in file 1:</p>
051:         *
052:         * <pre>
053:         * (file=1, sequence=Integer.MAX_VALUE - 300)
054:         * (file=1, sequence=Integer.MAX_VALUE - 200)
055:         * (file=1, sequence=Integer.MAX_VALUE - 100)
056:         * </pre>
057:         *
058:         * <p>The sequence number is the number of obsolete entries counted so far,
059:         * subtracted from Integer.MAX_VALUE to cause the latest written record to have
060:         * the lowest key.</p>
061:         *
062:         * <h3>Log version information</h3>
063:         * <p>Version 0: Keys are old format strings. No obsolete detail is
064:         * present.</p>
065:         * <p>Version 1: Keys are two 4 byte integers: {file, sequence}.  Obsolete
066:         * detail is present.  Some offsets may be invalid if RMW was used.</p>
067:         * <p>Version 2: The RMW problem with invalid offsets was corrected.  There is
068:         * no data format change; all versions of JE 2.0.x can read version 1.</p>
069:         *
070:         * @see com.sleepycat.je.cleaner.UtilizationProfile
071:         */
072:        public final class FileSummaryLN extends LN {
073:
074:            private static final String BEGIN_TAG = "<fileSummaryLN>";
075:            private static final String END_TAG = "</fileSummaryLN>";
076:
077:            private FileSummary baseSummary;
078:            private TrackedFileSummary trackedSummary;
079:            private PackedOffsets obsoleteOffsets;
080:            private boolean needOffsets;
081:            private byte logVersion;
082:
083:            /**
084:             * Creates a new LN with a given base summary.
085:             */
086:            public FileSummaryLN(FileSummary baseSummary) {
087:                super (new byte[0]);
088:                assert baseSummary != null;
089:                this .baseSummary = baseSummary;
090:                obsoleteOffsets = new PackedOffsets();
091:                logVersion = -1;
092:            }
093:
094:            /**
095:             * Creates an empty LN to be filled in from the log.
096:             */
097:            public FileSummaryLN() throws DatabaseException {
098:                baseSummary = new FileSummary();
099:                obsoleteOffsets = new PackedOffsets();
100:            }
101:
102:            /**
103:             * Sets the live summary object that will be added to the base summary at
104:             * the time the LN is logged.
105:             */
106:            public void setTrackedSummary(TrackedFileSummary trackedSummary) {
107:                this .trackedSummary = trackedSummary;
108:                needOffsets = true;
109:            }
110:
111:            /**
112:             * Returns the tracked summary, or null if setTrackedSummary was not
113:             * called.
114:             */
115:            public TrackedFileSummary getTrackedSummary() {
116:                return trackedSummary;
117:            }
118:
119:            /**
120:             * Returns the base summary for the file that is stored in the LN.
121:             */
122:            public FileSummary getBaseSummary() {
123:                return baseSummary;
124:            }
125:
126:            /**
127:             * Returns the obsolete offsets for the file.
128:             */
129:            public PackedOffsets getObsoleteOffsets() {
130:                return obsoleteOffsets;
131:            }
132:
133:            /**
134:             * Returns true if the given key for this LN is a String file number key.
135:             * For the old version of the LN there will be a single record per file.
136:             *
137:             * If this is a version 0 log entry, the key is a string.  However, such an
138:             * LN may be migrated by the cleaner, in which case the version will be 1
139:             * or greater [#13061].  In the latter case, we can distinguish a string
140:             * key by:
141:             *
142:             * 1) If the key is not 8 bytes long, it has to be a string key.
143:             *
144:             * 2) If the key is 8 bytes long, but bytes[4] is ascii "0" to "9", then it
145:             * must be a string key.  bytes[4] to bytes[7] are a sequence number that
146:             * is the number of log entries counted.  For this number to be greater
147:             * than 0x30000000, the binary value of 4 digits starting with ascii "0",
148:             * over 400 million log entries would have to occur in a single file; this
149:             * should never happen.
150:             *
151:             * Note that having to rely on method (2) is unlikely.  A string key will
152:             * only be 8 bytes if the file number reach 8 decimal digits (10,000,000 to
153:             * 99,999,999).  This is a very large file number and unlikely to have
154:             * occurred using JE 1.7.1 or earlier.
155:             *
156:             * In summary, the only time the algorithm here could fail is if there were
157:             * more than 400 million log entries per file, and more than 10 million
158:             * were written with JE 1.7.1 or earlier.
159:             */
160:            public boolean hasStringKey(byte[] bytes) {
161:
162:                if (logVersion == 0 || bytes.length != 8) {
163:                    return true;
164:                } else {
165:                    return (bytes[4] >= '0' && bytes[4] <= '9');
166:                }
167:            }
168:
169:            /**
170:             * Convert a FileSummaryLN key from a byte array to a long.  The file
171:             * number is the first 4 bytes of the key.
172:             */
173:            public long getFileNumber(byte[] bytes) {
174:
175:                if (hasStringKey(bytes)) {
176:                    try {
177:                        return Long.valueOf(new String(bytes, "UTF-8"))
178:                                .longValue();
179:                    } catch (UnsupportedEncodingException shouldNeverHappen) {
180:                        assert false : shouldNeverHappen;
181:                        return 0;
182:                    }
183:                } else {
184:                    ByteBuffer buf = ByteBuffer.wrap(bytes);
185:                    return LogUtils.readIntMSB(buf) & 0xFFFFFFFFL;
186:                }
187:            }
188:
189:            /**
190:             * Returns the first 4 bytes of the key for the given file number.  This
191:             * can be used to do a range search to find the first LN for the file.
192:             */
193:            public static byte[] makePartialKey(long fileNum) {
194:
195:                byte[] bytes = new byte[4];
196:                ByteBuffer buf = ByteBuffer.wrap(bytes);
197:
198:                LogUtils.writeIntMSB(buf, (int) fileNum);
199:
200:                return bytes;
201:            }
202:
203:            /**
204:             * Returns the full two-part key for a given file number and unique
205:             * sequence.  This can be used to insert a new LN.
206:             *
207:             * @param sequence is a unique identifier for the LN for the given file,
208:             * and must be greater than the last sequence.
209:             */
210:            public static byte[] makeFullKey(long fileNum, int sequence) {
211:
212:                assert sequence >= 0;
213:
214:                byte[] bytes = new byte[8];
215:                ByteBuffer buf = ByteBuffer.wrap(bytes);
216:
217:                /*
218:                 * The sequence is subtracted from MAX_VALUE so that increasing values
219:                 * will be sorted first.  This allows a simple range search to find the
220:                 * most recent value.
221:                 */
222:                LogUtils.writeIntMSB(buf, (int) fileNum);
223:                LogUtils.writeIntMSB(buf, Integer.MAX_VALUE - sequence);
224:
225:                return bytes;
226:            }
227:
228:            /**
229:             * Initialize a node that has been faulted in from the log.  If this FSLN
230:             * contains version 1 offsets that can be incorrect when RMW was used, and
231:             * if je.cleaner.rmwFix is enabled, discard the offsets.  [#13158]
232:             */
233:            public void postFetchInit(DatabaseImpl db, long sourceLsn)
234:                    throws DatabaseException {
235:
236:                super .postFetchInit(db, sourceLsn);
237:
238:                if (logVersion == 1
239:                        && db.getDbEnvironment().getUtilizationProfile()
240:                                .isRMWFixEnabled()) {
241:                    obsoleteOffsets = new PackedOffsets();
242:                }
243:            }
244:
245:            /*
246:             * Dumping
247:             */
248:
249:            public String toString() {
250:                return dumpString(0, true);
251:            }
252:
253:            public String beginTag() {
254:                return BEGIN_TAG;
255:            }
256:
257:            public String endTag() {
258:                return END_TAG;
259:            }
260:
261:            public String dumpString(int nSpaces, boolean dumpTags) {
262:                StringBuffer sb = new StringBuffer();
263:                sb.append(super .dumpString(nSpaces, dumpTags));
264:                sb.append('\n');
265:                if (!isDeleted()) {
266:                    sb.append(baseSummary.toString());
267:                    sb.append(obsoleteOffsets.toString());
268:                }
269:                return sb.toString();
270:            }
271:
272:            /**
273:             * Dump additional fields. Done this way so the additional info can
274:             * be within the XML tags defining the dumped log entry.
275:             */
276:            protected void dumpLogAdditional(StringBuffer sb, boolean verbose) {
277:                if (!isDeleted()) {
278:                    baseSummary.dumpLog(sb, true);
279:                    if (verbose) {
280:                        obsoleteOffsets.dumpLog(sb, true);
281:                    }
282:                }
283:            }
284:
285:            /*
286:             * Logging
287:             */
288:
289:            /**
290:             * Log type for transactional entries.
291:             */
292:            protected LogEntryType getTransactionalLogType() {
293:                assert false : "Txnl access to UP db not allowed";
294:                return LogEntryType.LOG_FILESUMMARYLN;
295:            }
296:
297:            /**
298:             * @see Node#getLogType
299:             */
300:            public LogEntryType getLogType() {
301:                return LogEntryType.LOG_FILESUMMARYLN;
302:            }
303:
304:            /**
305:             * @see LN#getLogSize
306:             */
307:            public int getLogSize() {
308:                int size = super .getLogSize();
309:                if (!isDeleted()) {
310:                    size += baseSummary.getLogSize();
311:                    getOffsets();
312:                    size += obsoleteOffsets.getLogSize();
313:                }
314:                return size;
315:            }
316:
317:            /**
318:             * @see LN#writeToLog
319:             */
320:            public void writeToLog(ByteBuffer logBuffer) {
321:
322:                /*
323:                 * Add the tracked (live) summary to the base summary before writing it
324:                 * to the log, and reset the tracked summary.  Do this even when
325:                 * deleting the LN, so that the tracked summary is cleared.
326:                 */
327:                if (trackedSummary != null) {
328:
329:                    baseSummary.add(trackedSummary);
330:
331:                    if (!isDeleted()) {
332:                        getOffsets();
333:                    }
334:
335:                    /* Reset the totals to zero and clear the tracked offsets. */
336:                    trackedSummary.reset();
337:                }
338:
339:                super .writeToLog(logBuffer);
340:
341:                if (!isDeleted()) {
342:                    baseSummary.writeToLog(logBuffer);
343:                    obsoleteOffsets.writeToLog(logBuffer);
344:                }
345:            }
346:
347:            /**
348:             * @see LN#readFromLog
349:             */
350:            public void readFromLog(ByteBuffer itemBuffer, byte entryTypeVersion)
351:                    throws LogException {
352:
353:                super .readFromLog(itemBuffer, entryTypeVersion);
354:
355:                logVersion = entryTypeVersion;
356:
357:                if (!isDeleted()) {
358:                    baseSummary.readFromLog(itemBuffer, entryTypeVersion);
359:                    if (entryTypeVersion > 0) {
360:                        obsoleteOffsets.readFromLog(itemBuffer,
361:                                entryTypeVersion);
362:                    }
363:                }
364:            }
365:
366:            /**
367:             * If tracked offsets may be present, get them so they are ready to be
368:             * written to the log.
369:             */
370:            private void getOffsets() {
371:                if (needOffsets) {
372:                    long[] offsets = trackedSummary.getObsoleteOffsets();
373:                    if (offsets != null) {
374:                        obsoleteOffsets.pack(offsets);
375:                    }
376:                    needOffsets = false;
377:                }
378:            }
379:
380:            /**
381:             * Overrides this method to indicate that getLogSize and writeToLog can
382:             * change the memory size of the LN.  The size returned by ObsoleteOffsets
383:             * getExtraMemorySize can change when getOffsets is called by getLogSize or
384:             * writeToLog, when the trackedSummary field is non-null.
385:             */
386:            boolean canMemorySizeChangeDuringLogging() {
387:                return true;
388:            }
389:
390:            /**
391:             * Overrides this method to add space occupied by this object's fields.
392:             */
393:            public long getMemorySizeIncludedByParent() {
394:                return super .getMemorySizeIncludedByParent()
395:                        + (MemoryBudget.FILESUMMARYLN_OVERHEAD - MemoryBudget.LN_OVERHEAD)
396:                        + obsoleteOffsets.getExtraMemorySize();
397:            }
398:
399:            /**
400:             * Clear out the obsoleteOffsets to save memory when the LN is deleted.
401:             */
402:            void makeDeleted() {
403:                super .makeDeleted();
404:                obsoleteOffsets = new PackedOffsets();
405:            }
406:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.