⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btreefiler.java

📁 jxta_src_2.41b jxta 2.41b 最新版源码 from www.jxta.org
💻 JAVA
字号:
package net.jxta.impl.xindice.core.filer;

/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xindice" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999-2001, The dbXML
 * Group, L.L.C., http://www.dbxmlgroup.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * $Id: BTreeFiler.java,v 1.9 2005/05/19 22:22:56 hamada Exp $
 */

import net.jxta.impl.xindice.core.DBException;
import net.jxta.impl.xindice.core.FaultCodes;
import net.jxta.impl.xindice.core.data.Key;
import net.jxta.impl.xindice.core.data.Record;
import net.jxta.impl.xindice.core.data.RecordSet;
import net.jxta.impl.xindice.core.data.Value;
import net.jxta.impl.xindice.core.indexer.NameIndexer;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
/**
 * BTreeFiler is a Filer implementation based on the BTree class.
 */

public final class BTreeFiler extends BTree implements Filer {

   protected static final byte RECORD = 20;

   private static final short PAGESIZE = 512;
   // TODO: MAXKEYSIZE might need tuning
   private static final short MAXKEYSIZE = 256;

   private BTreeFilerHeader fileHeader;

   private static final int DBE_CANNOT_READ = (int) (572l);
    
   public BTreeFiler() {
      super();
      fileHeader = (BTreeFilerHeader)getFileHeader();
   }

   public void setLocation(String dir, String file) {
      setFile(new File(dir, file+".tbl"));
   }

   public String getName() {
      return getFile().getName();
   }

   public boolean open() throws DBException {
      if (super.open()) {
         // These are the only properties that can be changed after creation
         fileHeader.setMaxKeySize(MAXKEYSIZE);
         return true;
      } else {
         return false;
      }
   }

   public boolean create() throws DBException {
      fileHeader.setPageSize(PAGESIZE);
      fileHeader.setMaxKeySize(MAXKEYSIZE);
      return super.create();
   }

   public Record readRecord(Key key) throws DBException {
      if (key == null || key.equals("")) {
         return null;
      }

      checkOpened();
      try {
         long pos = findValue(key);
         Record record = readRecord(pos);
         record.setKey(key);
         return record;
      } catch (BTreeNotFoundException b) {
              // do nothing
      } catch (BTreeException b) {
         throw b;
      } catch (IOException e) {
         throw new FilerException(DBE_CANNOT_READ,
                                     "Can't read record '" + key + "': " + e.getMessage(), e);
      }
      return null;
   }

   public Record readRecord(long pos) throws DBException {
      checkOpened();
      try {
         Page startPage = getPage(pos);
         Value v = readValue(startPage);
         BTreeFilerPageHeader sph = (BTreeFilerPageHeader) startPage.getPageHeader();

         HashMap meta = new HashMap(4);
         meta.put(Record.CREATED, new Long(sph.getCreated()));
         meta.put(Record.MODIFIED, new Long(sph.getModified()));
         meta.put(Record.LIFETIME, new Long(sph.getLifetime()));
         meta.put(Record.EXPIRATION, new Long(sph.getExpiration()));

         return new Record(null, v, meta);
      } catch (IOException e) {
            throw new FilerException(DBE_CANNOT_READ,
                                     "Can't read record : " + e.getMessage(), e);
      }
   }

   public long writeRecord(Key key, Value value) 
      throws DBException {

      return writeRecord(key, value, 0, 0);
   }

   public long writeRecord(Key key, Value value, 
                                        long lifetime, long expiration) 
      throws DBException {

      if (key == null || key.equals("")) {
         throw new FilerException(FaultCodes.DBE_CANNOT_CREATE, "Invalid key: '" + key + "'");
      }
      if (value == null) {
         throw new FilerException(FaultCodes.DBE_CANNOT_CREATE, "Invalid null value");
      }
      checkOpened();
      try {
         Page p;
         long pos = 0;
         try {
            pos = findValue(key);
            p = getPage(pos);
         }
         catch ( BTreeNotFoundException b ) {
            p = getFreePage();
            pos = p.getPageNum();
            addValue(key, p.getPageNum());
            fileHeader.incRecordCount();
         }
         BTreeFilerPageHeader ph = (BTreeFilerPageHeader)p.getPageHeader();

         long t = System.currentTimeMillis();
         if ( ph.getStatus() == UNUSED )
            ph.setCreated(t);
         
         ph.setModified(t);
         ph.setLifetime(lifetime);
         ph.setExpiration(expiration);
         ph.setStatus(RECORD);

         writeValue(p, value);
         flush();
         return pos;
        } catch (IOException e) {
            throw new FilerException(FaultCodes.DBE_CANNOT_CREATE,
                                     "Can't write record '" + key + "': " + e.getMessage(), e);
        }
   }

   public long writeRecord(long pos, Value value) throws DBException {

      if (value == null ) {
         throw new FilerException(FaultCodes.DBE_CANNOT_CREATE, "Invalid null value");
      }
      checkOpened();
      try {
         writeValue(pos, value);
         flush();
         return pos;
        } catch (IOException e) {
            throw new FilerException(FaultCodes.DBE_CANNOT_CREATE,
                                     "Can't write record '" + value + "': " + e.getMessage(), e);
        }
   }

   public boolean deleteRecord(Key key) throws DBException {
      if ( key == null || key.equals("") ) {
         return false;
      }
     checkOpened();
      try {
         long pos = findValue(key);
         Page p = getPage(pos);

         removeValue(key);
         unlinkPages(p.getPageNum());

         fileHeader.decRecordCount();

         flush();

         return true;
      } catch (BTreeNotFoundException b) {
          // not found move on
      } catch (IOException e) {
            throw new FilerException(FaultCodes.DBE_CANNOT_DROP,
                                     "Can't delete record '" + key + "': " + e.getMessage(), e);
      }
      return false;
   }

   public long getRecordCount() throws DBException {
      checkOpened();
      return fileHeader.getRecordCount();
   }

   public RecordSet getRecordSet() throws DBException {
      checkOpened();
      return new BTreeFilerRecordSet();
   }

   public void flush() throws DBException {
      super.flush();
   }

   /**
    * BTreeFilerRecordSet
    */

   private class BTreeFilerRecordSet implements RecordSet, BTreeCallback {
      private List keys = new ArrayList();
      private Iterator it;

      public BTreeFilerRecordSet() throws DBException {
         try {
            query(null, this);
            it = keys.iterator();
         } catch (IOException e) {
            throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, 
                                     "Error generating RecordSet", e);
         }
      }

      public synchronized boolean indexInfo(Value value, long pointer) {
         keys.add(new Key(value));
         return true;
      }

      public synchronized Key getNextKey() {
         return (Key) it.next();
      }

      public synchronized Record getNextRecord() throws DBException {
         return readRecord((Key) it.next());
      }

      public synchronized Value getNextValue() throws DBException {
         return getNextRecord().getValue();
      }

      public synchronized boolean hasMoreRecords() {
         return it.hasNext();
      }
   }

   ////////////////////////////////////////////////////////////////////

   public FileHeader createFileHeader() {
      return new BTreeFilerHeader();
   }

   public FileHeader createFileHeader(boolean read) throws IOException {
      return new BTreeFilerHeader(read);
   }

   public FileHeader createFileHeader(long pageCount) {
      return new BTreeFilerHeader(pageCount);
   }

   public FileHeader createFileHeader(long pageCount, int pageSize) {
      return new BTreeFilerHeader(pageCount, pageSize);
   }

   public PageHeader createPageHeader() {
      return new BTreeFilerPageHeader();
   }

   /**
    * BTreeFilerHeader
    */

   private final class BTreeFilerHeader extends BTreeFileHeader {
      private long totalBytes = 0;

      public BTreeFilerHeader() {
      }

      public BTreeFilerHeader(long pageCount) {
         super(pageCount);
      }

      public BTreeFilerHeader(long pageCount, int pageSize) {
         super(pageCount, pageSize);
      }

      public BTreeFilerHeader(boolean read) throws IOException {
         super(read);
      }

      public synchronized void read(RandomAccessFile raf) throws IOException {
         super.read(raf);
         totalBytes = raf.readLong();
      }

      public synchronized void write(RandomAccessFile raf) throws IOException {
         super.write(raf);
         raf.writeLong(totalBytes);
      }

      /** The total number of bytes in use by the file */
      public synchronized void setTotalBytes(long totalBytes) {
         this.totalBytes = totalBytes;
         setDirty();
      }

      /** The total number of bytes in use by the file */
      public synchronized long getTotalBytes() {
         return totalBytes;
      }
   }

   /**
    * BTreeFilerPageHeader
    */

   private final class BTreeFilerPageHeader extends BTreePageHeader {
      private long created = 0;
      private long modified = 0;
      private long lifetime = 0;
      private long expiration = 0;

      public BTreeFilerPageHeader() {
      }

      public BTreeFilerPageHeader(DataInputStream dis) throws IOException {
         super(dis);
      }

      public synchronized void read(DataInputStream dis) throws IOException {
         super.read(dis);

         if (getStatus() == UNUSED) {
             return;
         }

         created = dis.readLong();
         modified = dis.readLong();
         lifetime = dis.readLong();
         expiration = dis.readLong();
      }

      public synchronized void write(DataOutputStream dos) throws IOException {
         super.write(dos);
         dos.writeLong(created);
         dos.writeLong(modified);
         dos.writeLong(lifetime);
         dos.writeLong(expiration);
      }

      public synchronized void setRecordLen(int recordLen) {
         fileHeader.setTotalBytes((fileHeader.totalBytes - getRecordLen()) + recordLen);
         super.setRecordLen(recordLen);
      }

      /** UNIX-time when this record was created */
      public synchronized void setCreated(long created) {
         this.created = created;
         setDirty();
      }

      /** UNIX-time when this record was created */
      public synchronized long getCreated() {
         return created;
      }

      /** UNIX-time when this record was last modified */
      public synchronized void setModified(long modified) {
         this.modified = modified;
         setDirty();
      }

      /** UNIX-time when this record was last modified */
      public synchronized long getModified() {
         return modified;
      }

      /** JXTA-lifetime this record's lifetime */
      public synchronized void setLifetime(long lifetime) {
         this.lifetime = lifetime;
         setDirty();
      }

      /** JXTA-lifetime this record's lifetime */
      public synchronized long getLifetime() {
         return lifetime;
      }

      /** JXTA-expiration this record's expiration */
      public synchronized void setExpiration(long expiration) {
         this.expiration = expiration;
         setDirty();
      }

      /** JXTA-expiration this record's expiration */
      public synchronized long getExpiration() {
         return expiration;
      }
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -