kstaken     2003/02/05 20:49:44

  Modified:    java/src/org/apache/xindice/core/filer Paged.java
  Log:
  Adding documentation and a little code cleanup.
  
  Revision  Changes    Path
  1.13      +100 -25   
xml-xindice/java/src/org/apache/xindice/core/filer/Paged.java
  
  Index: Paged.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xindice/java/src/org/apache/xindice/core/filer/Paged.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- Paged.java        26 Nov 2002 01:50:16 -0000      1.12
  +++ Paged.java        6 Feb 2003 04:49:43 -0000       1.13
  @@ -86,20 +86,37 @@
    */
   
   public abstract class Paged {
  +   // The maximum number of pages that will be held in the dirty cache.
      private static final int MAX_DIRTY_SIZE = 128;
  +
  +   // The maximum number of open random access files we can have
      private static final int MAX_DESCRIPTORS = 16;
   
      protected static final byte UNUSED = 0;
      protected static final byte OVERFLOW = 126;
      protected static final byte DELETED = 127;
   
  +   protected static final int NO_PAGE = -1;
  +
  +   // Cache of recently read pages.
      private Map pages = new WeakHashMap();
  +
  +   // Cache of modified pages waiting to be written out.
      private Map dirty = new HashMap();
   
  -   private File file;
  +   // Random access file cache.
      private Stack descriptors = new Stack();
  +
  +   // The number of random access file objects that exist. Either in the 
cache
  +   // or in use.
      private int descCount = 0;
  +
  +   // Whether the file is opened or not.
      private boolean opened = false;
  +
  +   // The underlying file where the Paged object stores its pages.
  +   private File file;
  +
      private FileHeader fileHeader;
   
      public Paged() {
  @@ -130,13 +147,18 @@
      }
   
      protected synchronized final RandomAccessFile getDescriptor() throws 
IOException {
  -      if ( !descriptors.empty() )
  +      // If there are descriptors in the cache return one.
  +      if ( !descriptors.empty() ) {
            return (RandomAccessFile)descriptors.pop();
  +      }
  +      // Otherwise we need to get one some other way.
         else {
  +         // First try to create a new one if there's room
            if ( descCount < MAX_DESCRIPTORS ) {
               descCount++;
               return new RandomAccessFile(file, "rw");
            }
  +         // Otherwise we have to wait for one to be released by another 
thread.
            else {
               while ( true ) {
                  try {
  @@ -151,6 +173,9 @@
         }
      }
   
  +   /**
  +    * Puts a RandomAccessFile/descriptor into the descriptor cache.
  +    */
      protected synchronized final void putDescriptor(RandomAccessFile raf) {
         if ( raf != null ) {
            descriptors.push(raf);
  @@ -168,20 +193,29 @@
      protected final Page getPage(Long lp) throws IOException {
         Page p;
         synchronized ( this ) {
  -         p = (Page)dirty.get(lp); // Check if it's in the dirty stash
  -         if ( p == null )
  -            p = (Page)pages.get(lp);   // Check if it's in the volatile cache
  +         // Check if it's in the dirty cache
  +         p = (Page)dirty.get(lp);
  +
  +         // if not check if it's already loaded in the page cache
  +         if ( p == null ) {
  +            p = (Page)pages.get(lp);
  +         }
  +
  +         // if still not found we need to create it and add it to the page 
cache.
            if ( p == null ) {
               p = new Page(lp.longValue());
               pages.put(lp, p);
            }
         }
  +
  +      // Load the page from disk if necessary
         synchronized ( p ) {
  -         if ( !p.isLoaded() ) {
  +         if ( ! p.isLoaded() ) {
               p.read();
               p.setLoaded(true);
            }
         }
  +
         return p;
      }
   
  @@ -210,15 +244,23 @@
         Page p = page;
         PageHeader ph = null;
         long nextPage;
  +
  +      // Loop until we've read all the pages into memory.
         while ( true ) {
            ph = p.getPageHeader();
  +
  +         // Add the contents of the page onto the stream
            p.streamTo(bos);
  +
  +         // Continue following the list of pages until we get to the end.
            nextPage = ph.getNextPage();
  -         if ( nextPage != -1 )
  +         if ( nextPage != NO_PAGE )
               p = getPage(nextPage);
            else
               break;
         }
  +
  +      // Return a Value with the collected contents of all pages.
         return new Value(bos.toByteArray());
      }
   
  @@ -249,34 +291,46 @@
   
         InputStream is = value.getInputStream();
   
  +      // Write as much as we can onto the primary page.
         PageHeader hdr = page.getPageHeader();
         hdr.setRecordLen(value.getLength());
         page.streamFrom(is);
   
  -      // Write out the rest of the value
  +      // Write out the rest of the value onto any needed overflow pages
         while ( is.available() > 0 ) {
            Page lpage = page;
            PageHeader lhdr = hdr;
   
  +         // Find an overflow page to use
            long np = lhdr.getNextPage();
  -         if ( np != -1 )
  +         if ( np != NO_PAGE ) {
  +            // Use an existing page.
               page = getPage(np);
  +         }
            else {
  +            // Create a new overflow page
               page = getFreePage();
               lhdr.setNextPage(page.getPageNum());
            }
   
  +         // Mark the page as an overflow page.
            hdr = page.getPageHeader();
            hdr.setStatus(OVERFLOW);
  +
  +         // Write some more of the value to the overflow page.
            page.streamFrom(is);
   
            lpage.write();
         }
   
  +      // Cleanup any unused overflow pages. i.e. the value is smaller then 
the
  +      // last time it was written.
         long np = hdr.getNextPage();
  -      if ( np != -1 )
  +      if ( np != NO_PAGE ) {
            unlinkPages(np);
  -      hdr.setNextPage(-1);
  +      }
  +
  +      hdr.setNextPage(NO_PAGE);
         page.write();
      }
   
  @@ -299,31 +353,48 @@
       * @throws IOException if an Exception occurs
       */
      protected final void unlinkPages(Page page) throws IOException {
  -      // If the page is in primary space, just reset it's
  -      // status.  If it's in overflow, add it to the unused list.
  +      // Handle the page if it's in primary space by setting its status to
  +      // DELETED and freeing any overflow pages linked to it.
         if ( page.pageNum < fileHeader.pageCount ) {
            long nextPage = page.header.nextPage;
            page.header.setStatus(DELETED);
  -         page.header.setNextPage(-1);
  +         page.header.setNextPage(NO_PAGE);
            page.write();
  -         page = nextPage != -1 ? getPage(nextPage)
  -            : null;
  +
  +         // See if there are any chained pages from the page that was just 
removed
  +         if ( nextPage == NO_PAGE ) {
  +            page = null;
  +         }
  +         else {
  +            page = getPage(nextPage);
  +         }
         }
   
  +      // Add any overflow pages to the list of free pages.
         if ( page != null ) {
  -         // Walk the chain and add it to the unused list
  +         // Get the first page in the chain.
            long firstPage = page.pageNum;
  -         while ( page.header.nextPage != -1 )
  +
  +         // Find the last page in the chain.
  +         while ( page.header.nextPage != NO_PAGE ) {
               page = getPage(page.header.nextPage);
  +         }
            long lastPage = page.pageNum;
   
  -         if ( fileHeader.lastFreePage != -1 ) {
  +         // If there are already some free pages, add the start of the chain
  +         // to the list of free pages.
  +         if ( fileHeader.lastFreePage != NO_PAGE ) {
               Page p = getPage(fileHeader.lastFreePage);
               p.header.setNextPage(firstPage);
               p.write();
            }
  -         if ( fileHeader.firstFreePage == -1 )
  +
  +         // Otherwise set the chain as the list of free pages.
  +         if ( fileHeader.firstFreePage == NO_PAGE ) {
               fileHeader.setFirstFreePage(firstPage);
  +         }
  +
  +         // Add a reference to the end of the chain.
            fileHeader.setLastFreePage(lastPage);
         }
      }
  @@ -349,12 +420,12 @@
      protected final Page getFreePage() throws IOException {
         Page p = null;
         long pageNum = fileHeader.firstFreePage;
  -      if ( pageNum != -1 ) {
  +      if ( pageNum != NO_PAGE ) {
            // Steal a deleted page
            p = getPage(pageNum);
            fileHeader.setFirstFreePage(p.getPageHeader().nextPage);
  -         if ( fileHeader.firstFreePage == -1 )
  -            fileHeader.setLastFreePage(-1);
  +         if ( fileHeader.firstFreePage == NO_PAGE )
  +            fileHeader.setLastFreePage(NO_PAGE);
         }
         else {
            // Grow the file
  @@ -364,7 +435,7 @@
         }
   
         // Initialize The Page Header (Cleanly)
  -      p.header.setNextPage(-1);
  +      p.header.setNextPage(NO_PAGE);
         p.header.setStatus(UNUSED);
         return p;
      }
  @@ -1099,7 +1170,11 @@
   
         public synchronized void setKey(Key key) {
            header.setKey(key);
  +         // Insert the key into the data array.
            key.copyTo(data, keyPos);
  +
  +         // Set the start of data to skip over the key.
  +         dataPos = keyPos + header.keyLen;
         }
   
         public synchronized Key getKey() {
  
  
  

Reply via email to