Source Code Cross Referenced for CachedPage.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » store » raw » data » 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 » Database DBMS » db derby 10.2 » org.apache.derby.impl.store.raw.data 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Derby - Class org.apache.derby.impl.store.raw.data.CachedPage
004:
005:           Licensed to the Apache Software Foundation (ASF) under one or more
006:           contributor license agreements.  See the NOTICE file distributed with
007:           this work for additional information regarding copyright ownership.
008:           The ASF licenses this file to you under the Apache License, Version 2.0
009:           (the "License"); you may not use this file except in compliance with
010:           the License.  You may obtain a copy of the License at
011:
012:              http://www.apache.org/licenses/LICENSE-2.0
013:
014:           Unless required by applicable law or agreed to in writing, software
015:           distributed under the License is distributed on an "AS IS" BASIS,
016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017:           See the License for the specific language governing permissions and
018:           limitations under the License.
019:
020:         */
021:
022:        package org.apache.derby.impl.store.raw.data;
023:
024:        import org.apache.derby.iapi.reference.SQLState;
025:
026:        import org.apache.derby.impl.store.raw.data.BasePage;
027:
028:        import org.apache.derby.iapi.store.raw.log.LogInstant;
029:        import org.apache.derby.iapi.store.raw.ContainerHandle;
030:        import org.apache.derby.iapi.store.raw.PageKey;
031:
032:        import org.apache.derby.iapi.services.cache.Cacheable;
033:        import org.apache.derby.iapi.services.cache.CacheManager;
034:        import org.apache.derby.iapi.services.context.ContextService;
035:
036:        import org.apache.derby.iapi.services.monitor.Monitor;
037:
038:        import org.apache.derby.iapi.services.sanity.SanityManager;
039:
040:        import org.apache.derby.iapi.services.io.FormatIdUtil;
041:        import org.apache.derby.iapi.services.io.StoredFormatIds;
042:
043:        import org.apache.derby.iapi.error.StandardException;
044:        import org.apache.derby.iapi.error.ExceptionSeverity;
045:        import java.io.IOException;
046:
047:        /**
048:         A base page that is cached.
049:
050:         Since there are multiple page formats, use this abstract class to implement
051:         cacheable interface.
052:
053:         */
054:
055:        public abstract class CachedPage extends BasePage implements  Cacheable {
056:            protected boolean alreadyReadPage; // true when page read by another 
057:            // class
058:
059:            protected byte[] pageData; // the actual page data - this is
060:            // the 'buffer' in the buffer cache
061:
062:            // The isDirty flag indicates if the pageData or pageHeader has been
063:            // modified.  The preDirty flag indicates that the pageData or the
064:            // pageHeader is about to be modified.  The reason for these 2 flags
065:            // instead of just one is to accomodate checkpoint.  After a clean
066:            // (latched) page sends a log record to the log stream but before that page
067:            // is dirtied by the log operation, a checkpoint could be taken.  If so,
068:            // then the redoLWM will be after the log record but, without preDirty, the
069:            // cache cleaning will not have waited for the change.  So the preDirty bit
070:            // is to stop the cache cleaning from skipping over this (latched) page
071:            // even though it has not really been modified yet.  
072:
073:            protected boolean isDirty; // must be set to true whenever the
074:            // pageData array is touched 
075:            // directly or indirectly.
076:
077:            protected boolean preDirty; // set to true if the page is clean
078:            // and the pageData array is about 
079:            // to be touched directly or 
080:            // indirectly.
081:
082:            protected int initialRowCount; // keep a running count of rows for
083:            // estimated row count.
084:
085:            private long containerRowCount; // the number of rows in the
086:            // container when this page is read
087:            // from disk 
088:
089:            /*
090:             ** These fields are immutable and can be used by the subclasses directly.
091:             */
092:
093:            /**
094:            	The page cache I live in.
095:
096:            	<BR> MT - Immutable
097:             */
098:            protected CacheManager pageCache;
099:
100:            /**
101:            	The container cache my container lives in.
102:
103:            	<BR> MT - Immutable
104:             */
105:            protected CacheManager containerCache;
106:
107:            /**
108:            	My factory class.
109:
110:            	<BR> MT - Immutable - 
111:             */
112:            protected BaseDataFileFactory dataFactory; // my factory class.
113:
114:            protected static final int PAGE_FORMAT_ID_SIZE = 4;
115:
116:            /*
117:             * the page need to be written and synced to disk 
118:             */
119:            public static final int WRITE_SYNC = 1;
120:
121:            /*
122:             * the page need to be write to disk but not synced
123:             */
124:            public static final int WRITE_NO_SYNC = 2;
125:
126:            public CachedPage() {
127:                super ();
128:            }
129:
130:            public final void setFactory(BaseDataFileFactory factory) {
131:                dataFactory = factory;
132:                pageCache = factory.getPageCache();
133:                containerCache = factory.getContainerCache();
134:            }
135:
136:            /**
137:                Initialize a CachedPage.
138:                <p>
139:            	Initialize the object, ie. perform work normally perfomed in 
140:                constructor.  Called by setIdentity() and createIdentity().
141:             */
142:            protected void initialize() {
143:                super .initialize();
144:                isDirty = false;
145:                preDirty = false;
146:                initialRowCount = 0;
147:                containerRowCount = 0;
148:            }
149:
150:            /*
151:             ** Methods of Cacheable
152:             */
153:
154:            /**
155:             * Find the container and then read the page from that container.
156:             * <p>
157:             * This is the way new pages enter the page cache.
158:             * <p>
159:             *
160:             * @return always true, higher levels have already checked the page number 
161:             *         is valid for an open.
162:             *
163:             * @exception StandardException Standard Cloudscape policy.
164:             *
165:             * @see Cacheable#setIdentity
166:             **/
167:            public Cacheable setIdentity(Object key) throws StandardException {
168:                if (SanityManager.DEBUG) {
169:                    SanityManager.ASSERT(key instanceof  PageKey);
170:                }
171:
172:                initialize();
173:
174:                PageKey newIdentity = (PageKey) key;
175:
176:                FileContainer myContainer = (FileContainer) containerCache
177:                        .find(newIdentity.getContainerId());
178:
179:                setContainerRowCount(myContainer.getEstimatedRowCount(0));
180:
181:                try {
182:                    if (!alreadyReadPage) {
183:                        // Fill in the pageData array by reading bytes from disk.
184:                        readPage(myContainer, newIdentity);
185:                    } else {
186:                        // pageData array already filled
187:                        alreadyReadPage = false;
188:                    }
189:
190:                    // if the formatID on disk is not the same as this page instance's
191:                    // format id, instantiate the real page object
192:                    int fmtId = getTypeFormatId();
193:
194:                    int onPageFormatId = FormatIdUtil
195:                            .readFormatIdInteger(pageData);
196:                    if (fmtId != onPageFormatId) {
197:                        return changeInstanceTo(onPageFormatId, newIdentity)
198:                                .setIdentity(key);
199:                    }
200:
201:                    // this is the correct page instance
202:                    initFromData(myContainer, newIdentity);
203:                } finally {
204:                    containerCache.release(myContainer);
205:                    myContainer = null;
206:                }
207:
208:                fillInIdentity(newIdentity);
209:
210:                initialRowCount = 0;
211:
212:                return this ;
213:            }
214:
215:            /**
216:             * Find the container and then create the page in that container.
217:             * <p>
218:             * This is the process of creating a new page in a container, in that
219:             * case no need to read the page from disk - just need to initialize it
220:             * in the cache.
221:             * <p>
222:             *
223:             * @return new page, higher levels have already checked the page number is 
224:             *         valid for an open.
225:             *
226:             * @param key               Which page is this?
227:             * @param createParameter   details needed to create page like size, 
228:             *                          format id, ...
229:             *
230:             * @exception  StandardException  Standard exception policy.
231:             *
232:             * @see Cacheable#createIdentity
233:             **/
234:            public Cacheable createIdentity(Object key, Object createParameter)
235:                    throws StandardException {
236:
237:                if (SanityManager.DEBUG) {
238:                    SanityManager.ASSERT(key instanceof  PageKey);
239:                }
240:
241:                initialize();
242:
243:                PageKey newIdentity = (PageKey) key;
244:
245:                int[] createArgs = (int[]) createParameter;
246:
247:                if (createArgs[0] == -1) {
248:                    throw StandardException.newException(
249:                            SQLState.DATA_UNKNOWN_PAGE_FORMAT, newIdentity);
250:                }
251:
252:                // createArgs[0] contains the integer form of the formatId 
253:                // if it is not the same as this instance's formatId, instantiate the
254:                // real page object
255:                if (createArgs[0] != getTypeFormatId()) {
256:                    return (changeInstanceTo(createArgs[0], newIdentity)
257:                            .createIdentity(key, createParameter));
258:                }
259:
260:                // this is the correct page instance
261:                initializeHeaders(5);
262:                createPage(newIdentity, createArgs);
263:
264:                fillInIdentity(newIdentity);
265:
266:                initialRowCount = 0;
267:
268:                /*
269:                 * if we need to grow the container and the page has not been
270:                 * preallocated, writing page before the log is written so that we
271:                 * know if there is an IO error - like running out of disk space - then
272:                 * we don't write out the log record, because if we do, it may fail
273:                 * after the log goes to disk and then the database may not be
274:                 * recoverable. 
275:                 *
276:                 * WRITE_SYNC is used when we create the page without first
277:                 *	preallocating it 
278:                 * WRITE_NO_SYNC is used when we are preallocating the page - there
279:                 *	will be a SYNC call after all the pages are preallocated
280:                 * 0 means creating a page that has already been preallocated.
281:                 */
282:                if ((createArgs[1] & WRITE_SYNC) != 0
283:                        || (createArgs[1] & WRITE_NO_SYNC) != 0)
284:                    writePage(newIdentity, (createArgs[1] & WRITE_SYNC) != 0);
285:
286:                if (SanityManager.DEBUG) {
287:                    if (SanityManager.DEBUG_ON(FileContainer.SPACE_TRACE)) {
288:                        String syncFlag = ((createArgs[1] & WRITE_SYNC) != 0) ? "Write_Sync"
289:                                : (((createArgs[1] & WRITE_NO_SYNC) != 0) ? "Write_NO_Sync"
290:                                        : "No_write");
291:
292:                        SanityManager.DEBUG(FileContainer.SPACE_TRACE,
293:                                "creating new page " + newIdentity + " with "
294:                                        + syncFlag);
295:                    }
296:                }
297:
298:                return this ;
299:            }
300:
301:            /**
302:             * Convert this page to requested type, as defined by input format id.
303:             * <p>
304:             * The current cache entry is a different format id than the requested
305:             * type, change it.  This object is instantiated to the wrong subtype of 
306:             * cachedPage, this routine will create an object with the correct subtype,
307:             * and transfer all pertinent information from this to the new correct 
308:             * object.
309:             * <p>
310:             *
311:             * @return The new object created with the input fid and transfered info.
312:             *
313:             * @param fid          The format id of the new page.
314:             * @param newIdentity  The key of the new page.
315:             *
316:             * @exception  StandardException  Standard exception policy.
317:             **/
318:            private CachedPage changeInstanceTo(int fid, PageKey newIdentity)
319:                    throws StandardException {
320:                CachedPage realPage;
321:                try {
322:                    realPage = (CachedPage) Monitor
323:                            .newInstanceFromIdentifier(fid);
324:
325:                } catch (StandardException se) {
326:                    if (se.getSeverity() > ExceptionSeverity.STATEMENT_SEVERITY) {
327:                        throw se;
328:                    } else {
329:                        throw StandardException.newException(
330:                                SQLState.DATA_UNKNOWN_PAGE_FORMAT, se,
331:                                newIdentity);
332:                    }
333:                }
334:
335:                realPage.setFactory(dataFactory);
336:
337:                // avoid creating the data buffer if possible, transfer it to the new 
338:                // page if this is the first time the page buffer is used, then 
339:                // createPage will create the page array with the correct page size
340:                if (this .pageData != null) {
341:                    realPage.alreadyReadPage = true;
342:                    realPage.usePageBuffer(this .pageData);
343:                }
344:
345:                // RESOLVE (12/15/06) - the following code is commented out, but
346:                // not sure why.
347:
348:                // this page should not be used any more, null out all its content and
349:                // wait for GC to clean it up  
350:
351:                //destroyPage();// let this subtype have a chance to get rid of stuff
352:                //this.pageData = null;	// this instance no longer own the data array
353:                //this.pageCache = null;
354:                //this.dataFactory = null;
355:                //this.containerCache = null;
356:
357:                return realPage;
358:            }
359:
360:            /**
361:             * Is the page dirty?
362:             * <p>
363:             * The isDirty flag indicates if the pageData or pageHeader has been
364:             * modified.  The preDirty flag indicates that the pageData or the
365:             * pageHeader is about to be modified.  The reason for these 2 flags
366:             * instead of just one is to accomodate checkpoint.  After a clean
367:             * (latched) page sends a log record to the log stream but before that page
368:             * is dirtied by the log operation, a checkpoint could be taken.  If so,
369:             * then the redoLWM will be after the log record but, without preDirty, the
370:             * cache cleaning will not have waited for the change.  So the preDirty bit
371:             * is to stop the cache cleaning from skipping over this (latched) page
372:             * even though it has not really been modified yet.  
373:             *
374:             * @return true if the page is dirty.
375:             *
376:             * @see Cacheable#isDirty
377:             **/
378:            public boolean isDirty() {
379:                synchronized (this ) {
380:                    return isDirty || preDirty;
381:                }
382:            }
383:
384:            /**
385:             * Has the page or its header been modified.
386:             * <p>
387:             * See comment on class header on meaning of isDirty and preDirty bits.
388:             * <p>
389:             *
390:             * @return true if changes have actually been made to the page in memory.
391:             **/
392:            public boolean isActuallyDirty() {
393:                synchronized (this ) {
394:                    return isDirty;
395:                }
396:            }
397:
398:            /**
399:             * Set state to indicate the page or its header is about to be modified.
400:             * <p>
401:             * See comment on class header on meaning of isDirty and preDirty bits.
402:             **/
403:            public void preDirty() {
404:                synchronized (this ) {
405:                    if (!isDirty)
406:                        preDirty = true;
407:                }
408:            }
409:
410:            /**
411:             * Set state to indicate the page or its header has been modified.
412:             * <p>
413:             * See comment on class header on meaning of isDirty and preDirty bits.
414:             * <p>
415:             **/
416:            protected void setDirty() {
417:                synchronized (this ) {
418:                    isDirty = true;
419:                    preDirty = false;
420:                }
421:            }
422:
423:            /**
424:             * exclusive latch on page is being released.
425:             * <p>
426:             * The only work done in CachedPage is to update the row count on the
427:             * container if it is too out of sync.
428:             **/
429:            protected void releaseExclusive() {
430:                // look at dirty bit without latching, the updating of the row
431:                // count is just an optimization so does not need the latch.
432:                //
433:                // if this page actually has > 1/8 rows of the entire container, then
434:                // consider updating the row count if it is different.
435:                //
436:                // No need to special case allocation pages because it has recordCount 
437:                // of zero, thus the if clause will never be true for an allocation 
438:                // page.
439:                if (isDirty && !isOverflowPage()
440:                        && (containerRowCount / 8) < recordCount()) {
441:                    int currentRowCount = internalNonDeletedRecordCount();
442:                    int delta = currentRowCount - initialRowCount;
443:                    int posDelta = delta > 0 ? delta : (-delta);
444:
445:                    if ((containerRowCount / 8) < posDelta) {
446:                        // This pages delta row count represents a significant change
447:                        // with respect to current container row count so update 
448:                        // container row count
449:                        FileContainer myContainer = null;
450:
451:                        try {
452:                            myContainer = (FileContainer) containerCache
453:                                    .find(identity.getContainerId());
454:
455:                            if (myContainer != null) {
456:                                myContainer.updateEstimatedRowCount(delta);
457:                                setContainerRowCount(myContainer
458:                                        .getEstimatedRowCount(0));
459:
460:                                initialRowCount = currentRowCount;
461:
462:                                // since I have the container, might as well update the
463:                                // unfilled information
464:                                myContainer.trackUnfilledPage(identity
465:                                        .getPageNumber(), unfilled());
466:                            }
467:                        } catch (StandardException se) {
468:                            // do nothing, not sure what could fail but this update
469:                            // is just an optimization so no need to throw error.
470:                        } finally {
471:                            if (myContainer != null)
472:                                containerCache.release(myContainer);
473:                        }
474:                    }
475:                }
476:
477:                super .releaseExclusive();
478:            }
479:
480:            /**
481:             * Write the page to disk.
482:             * <p>
483:             * MP - In a simple world we would just not allow clean until it held the
484:             *      latch on the page.  But in order to fit into the cache system, we 
485:             *      don't have enough state around to just make clean() latch the page 
486:             *      while doing the I/O - but we still need someway to insure that no
487:             *      changes happen to the page while the I/O is taking place.  
488:             *      Also someday it would be fine to allow reads of this page
489:             *      while the I/O was taking place.  
490:             *
491:             *
492:             * @exception  StandardException  Error writing the page.
493:             *
494:             * @see Cacheable#clean
495:             **/
496:            public void clean(boolean remove) throws StandardException {
497:
498:                // must wait for the page to be unlatched
499:                synchronized (this ) {
500:                    if (!isDirty())
501:                        return;
502:
503:                    // is someone else cleaning it
504:                    while (inClean) {
505:                        try {
506:                            wait();
507:                        } catch (InterruptedException ie) {
508:                            throw StandardException.interrupt(ie);
509:                        }
510:                    }
511:
512:                    // page is not "inClean" by other thread at this point.
513:
514:                    if (!isDirty())
515:                        return;
516:
517:                    inClean = true;
518:
519:                    // If page is in LATCHED state (as opposed to UNLATCH or PRELATCH)
520:                    // wait for the page to move to UNLATCHED state.  See Comments in
521:                    // Generic/BasePage.java describing the interaction of inClean,
522:                    // (owner != null), and preLatch.
523:                    while ((owner != null) && !preLatch) {
524:                        try {
525:                            wait();
526:                        } catch (InterruptedException ie) {
527:                            inClean = false;
528:                            throw StandardException.interrupt(ie);
529:                        }
530:                    }
531:
532:                    // The page is now effectively latched by the cleaner.
533:                    // We only want to clean the page if the page is actually dirtied,
534:                    // not when it is just pre-dirtied.
535:                    if (!isActuallyDirty()) {
536:                        // the person who latched it gives up the
537:                        // latch without really dirtying the page
538:                        preDirty = false;
539:                        inClean = false;
540:                        notifyAll();
541:                        return;
542:                    }
543:                }
544:
545:                try {
546:                    writePage(getPageId(), false);
547:                } catch (StandardException se) {
548:                    // If we get an error while trying to write a page, current
549:                    // recovery system requires that entire DB is shutdown.  Then
550:                    // when system is rebooted we will run redo recovery which 
551:                    // if it does not encounter disk errors will guarantee to recover
552:                    // to a transaction consistent state.  If this write is a 
553:                    // persistent device problem, redo recovery will likely fail
554:                    // attempting to the same I/O.  Mark corrupt will stop all further
555:                    // writes of data and log by the system.
556:                    throw dataFactory.markCorrupt(se);
557:                } finally {
558:                    // if there is something wrong in writing out the page, 
559:                    // do not leave it inClean state or it will block the next cleaner 
560:                    // forever
561:
562:                    synchronized (this ) {
563:                        inClean = false;
564:                        notifyAll();
565:                    }
566:                }
567:            }
568:
569:            public void clearIdentity() {
570:                alreadyReadPage = false;
571:                super .clearIdentity();
572:            }
573:
574:            /**
575:             * read the page from disk into this CachedPage object.
576:             * <p>
577:             * A page is read in from disk into the pageData array of this object,
578:             * and then put in the cache.
579:             * <p>
580:             *
581:             * @param myContainer the container to read the page from.
582:             * @param newIdentity indentity (ie. page number) of the page to read
583:             *
584:             * @exception  StandardException  Standard exception policy.
585:             **/
586:            private void readPage(FileContainer myContainer, PageKey newIdentity)
587:                    throws StandardException {
588:                int pagesize = myContainer.getPageSize();
589:
590:                // we will reuse the existing page array if it is same size, the
591:                // cache does support caching various sized pages.
592:                setPageArray(pagesize);
593:
594:                for (int io_retry_count = 0;;) {
595:                    try {
596:                        myContainer.readPage(newIdentity.getPageNumber(),
597:                                pageData);
598:                        break;
599:                    } catch (IOException ioe) {
600:                        io_retry_count++;
601:
602:                        // Retrying read I/O's has been found to be successful sometimes
603:                        // in completing the read without having to fail the calling
604:                        // query, and in some cases avoiding complete db shutdown.
605:                        // Some situations are:
606:                        //     spurious interrupts being sent to thread by clients.
607:                        //     unreliable hardware like a network mounted file system.
608:                        //
609:                        // The only option other than retrying is to fail the I/O 
610:                        // immediately and throwing an error, thus performance cost
611:                        // not really a consideration.
612:                        //
613:                        // The retry max of 4 is arbitrary, but has been enough that
614:                        // not many read I/O errors have been reported.
615:                        if (io_retry_count > 4) {
616:                            // page cannot be physically read
617:
618:                            StandardException se = StandardException
619:                                    .newException(
620:                                            SQLState.FILE_READ_PAGE_EXCEPTION,
621:                                            ioe, newIdentity, new Integer(
622:                                                    pagesize));
623:
624:                            if (dataFactory.getLogFactory().inRFR()) {
625:                                //if in rollforward recovery, it is possible that this 
626:                                //page actually does not exist on the disk yet because
627:                                //the log record we are proccessing now is actually 
628:                                //creating the page, we will recreate the page if we 
629:                                //are in rollforward recovery, so just throw the 
630:                                //exception.
631:                                throw se;
632:                            } else {
633:                                if (SanityManager.DEBUG) {
634:                                    // by shutting down system in debug mode, maybe
635:                                    // we can catch root cause of the interrupt.
636:                                    throw dataFactory.markCorrupt(se);
637:                                } else {
638:                                    // No need to shut down runtime database on read
639:                                    // error in delivered system, throwing exception 
640:                                    // should be enough.  Thrown exception has nested
641:                                    // IO exception which is root cause of error.
642:                                    throw se;
643:                                }
644:                            }
645:                        }
646:                    }
647:                }
648:            }
649:
650:            /**
651:             * write the page from this CachedPage object to disk.
652:             * <p>
653:             *
654:             * @param identity indentity (ie. page number) of the page to read
655:             * @param syncMe      does the write of this single page have to be sync'd?
656:             *
657:             * @exception  StandardException  Standard exception policy.
658:             **/
659:            private void writePage(PageKey identity, boolean syncMe)
660:                    throws StandardException {
661:
662:                // make subclass write the page format
663:                writeFormatId(identity);
664:
665:                // let subclass have a chance to write any cached data to page data 
666:                // array
667:                writePage(identity);
668:
669:                // force WAL - and check to see if database is corrupt or is frozen.
670:                // last log Instant may be null if the page is being forced
671:                // to disk on a createPage (which violates the WAL protocol actually).
672:                // See FileContainer.newPage
673:                LogInstant flushLogTo = getLastLogInstant();
674:                dataFactory.flush(flushLogTo);
675:
676:                if (flushLogTo != null) {
677:                    clearLastLogInstant();
678:                }
679:
680:                // find the container and file access object
681:                FileContainer myContainer = (FileContainer) containerCache
682:                        .find(identity.getContainerId());
683:
684:                if (myContainer != null) {
685:                    try {
686:                        myContainer.writePage(identity.getPageNumber(),
687:                                pageData, syncMe);
688:
689:                        //
690:                        // Do some in memory unlogged bookkeeping tasks while we have
691:                        // the container. 
692:                        //
693:
694:                        if (!isOverflowPage() && isDirty()) {
695:
696:                            // let the container knows whether this page is a not 
697:                            // filled, non-overflow page
698:                            myContainer.trackUnfilledPage(identity
699:                                    .getPageNumber(), unfilled());
700:
701:                            // if this is not an overflow page, see if the page's row
702:                            // count has changed since it come into the cache.
703:                            //
704:                            // if the page is not invalid, row count is 0.  Otherwise,
705:                            // count non-deleted records on page.
706:                            //
707:                            // Cannot call nonDeletedRecordCount because the page is
708:                            // unlatched now even though nobody is changing it
709:                            int currentRowCount = internalNonDeletedRecordCount();
710:
711:                            if (currentRowCount != initialRowCount) {
712:                                myContainer
713:                                        .updateEstimatedRowCount(currentRowCount
714:                                                - initialRowCount);
715:
716:                                setContainerRowCount(myContainer
717:                                        .getEstimatedRowCount(0));
718:
719:                                initialRowCount = currentRowCount;
720:                            }
721:                        }
722:
723:                    } catch (IOException ioe) {
724:                        // page cannot be written
725:                        throw StandardException.newException(
726:                                SQLState.FILE_WRITE_PAGE_EXCEPTION, ioe,
727:                                identity,
728:                                new Integer(myContainer.getPageSize()));
729:                    } finally {
730:                        containerCache.release(myContainer);
731:                        myContainer = null;
732:                    }
733:                } else {
734:                    StandardException nested = StandardException.newException(
735:                            SQLState.DATA_CONTAINER_VANISHED, identity
736:                                    .getContainerId());
737:                    throw dataFactory.markCorrupt(StandardException
738:                            .newException(SQLState.FILE_WRITE_PAGE_EXCEPTION,
739:                                    nested, identity, new Integer(myContainer
740:                                            .getPageSize())));
741:                }
742:
743:                synchronized (this ) {
744:                    // change page state to not dirty after the successful write
745:                    isDirty = false;
746:                    preDirty = false;
747:                }
748:            }
749:
750:            public void setContainerRowCount(long rowCount) {
751:                containerRowCount = rowCount;
752:            }
753:
754:            /*
755:             ** if the page size is different from the page buffer, then make a
756:             ** new page buffer and make subclass use the new page buffer
757:             */
758:
759:            protected void setPageArray(int pageSize) throws StandardException {
760:                if ((pageData == null) || (pageData.length != pageSize)) {
761:                    pageData = new byte[pageSize];
762:
763:                    if (pageData == null || pageData.length != pageSize) {
764:                        throw StandardException.newException(
765:                                SQLState.DATA_OBJECT_ALLOCATION_FAILED, "PAGE");
766:                    }
767:
768:                    usePageBuffer(pageData);
769:                }
770:            }
771:
772:            /**
773:             * Returns the page data array used to write on disk version.
774:             *
775:             * <p>
776:             * returns the page data array, that is actually written to the disk,
777:             * when the page is cleaned from the page cache.  Takes care of flushing
778:             * in-memory information to the array (like page header and format id info).
779:             * <p>
780:             *
781:             * @return The array of bytes that is the on disk version of page.
782:             *
783:             * @exception  StandardException  Standard exception policy.
784:             **/
785:            protected byte[] getPageArray() throws StandardException {
786:                // make subclass write the page format
787:                writeFormatId(identity);
788:
789:                // let subclass have a chance to write any cached
790:                // data to page data array
791:                writePage(identity);
792:
793:                return pageData;
794:            }
795:
796:            /* methods for subclass of cached page */
797:
798:            // use a new pageData buffer, initialize in memory structure that depend on
799:            // the pageData's size.  The actual disk data may not have not been read in
800:            // yet so don't look at the content of the buffer
801:            protected abstract void usePageBuffer(byte[] buffer);
802:
803:            // initialize in memory structure using the read in buffer in pageData
804:            protected abstract void initFromData(FileContainer container,
805:                    PageKey id) throws StandardException;
806:
807:            // create the page
808:            protected abstract void createPage(PageKey id, int[] args)
809:                    throws StandardException;
810:
811:            // page is about to be written, write everything to pageData array
812:            protected abstract void writePage(PageKey id)
813:                    throws StandardException;
814:
815:            // write out the formatId to the pageData
816:            protected abstract void writeFormatId(PageKey identity)
817:                    throws StandardException;
818:        }
ww___w__._j__av_a___2__s_.__c_om___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.