Package com.dbxml.db.common.btree

Source Code of com.dbxml.db.common.btree.BTreeFiler$BTreeFilerPageHeader

package com.dbxml.db.common.btree;

/*
* dbXML - Native XML Database
* Copyright (c) 1999-2006 The dbXML Group, L.L.C.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* $Id: BTreeFiler.java,v 1.8 2008/08/18 17:24:53 bradford Exp $
*/

import com.dbxml.db.core.Collection;
import com.dbxml.db.core.DBException;
import com.dbxml.db.core.FaultCodes;
import com.dbxml.db.core.data.Key;
import com.dbxml.db.core.data.Record;
import com.dbxml.db.core.data.RecordMetaData;
import com.dbxml.db.core.data.RecordSet;
import com.dbxml.db.core.data.Value;
import com.dbxml.db.core.filer.Filer;
import com.dbxml.db.core.filer.FilerException;
import com.dbxml.db.core.transaction.Transaction;
import com.dbxml.util.Configuration;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
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 String PAGESIZE = "pagesize";

   private Collection collection;
   private BTreeFilerHeader fileHeader;

   public BTreeFiler(boolean transactionSupported) {
      super(false);
      setTransactionSupported(transactionSupported);
      fileHeader = (BTreeFilerHeader)getFileHeader();
   }

   public BTreeFiler(File f, boolean transactionSupport) {
      this(transactionSupport);
      setFile(f);
   }

   public BTreeFiler(File f) {
      this(f, true);
   }

   public BTreeFiler() {
      this(true);
   }

   public void setLocation(String location) {
      setFile(new File(collection.getCollectionRoot(), location + ".tbl"));
   }

   public String getName() {
      return "BTreeFiler";
   }

   public boolean create() throws DBException {
      Configuration cfg = getConfig();
      if ( cfg != null )
         fileHeader.setPageSize(cfg.getIntAttribute(PAGESIZE, fileHeader.getPageSize()));
      return super.create();
   }

   public void setCollection(Collection collection) {
      this.collection = collection;
      setLocation(collection.getName());
   }

   private RecordMetaData buildMetaData(Page p) {
      BTreeFilerPageHeader ph = (BTreeFilerPageHeader)p.getPageHeader();
      HashMap meta = new HashMap(2);
      meta.put(RecordMetaData.CREATED, new Long(ph.getCreated()));
      meta.put(RecordMetaData.MODIFIED, new Long(ph.getModified()));
      return new RecordMetaData(meta);
   }

   public RecordMetaData getRecordMetaData(Transaction tx, Key key) throws DBException {
      checkOpened();
      try {
         long pos = findValue(tx, key);
         Page page = getPage(tx, pos);
         return buildMetaData(page);
      }
      catch ( BTreeNotFoundException b ) {
      }
      catch ( BTreeException b ) {
         throw b;
      }
      catch ( Exception e ) {
         e.printStackTrace(System.err);
      }
      return null;
   }

   public Record readRecord(Transaction tx, Key key) throws DBException {
      checkOpened();
      try {
         long pos = findValue(tx, key);
         Page page = getPage(tx, pos);
         Value v = readValue(tx, page);
         RecordMetaData md = buildMetaData(page);
         return new Record(key, v, md);
      }
      catch ( BTreeNotFoundException b ) {
      }
      catch ( BTreeException b ) {
         throw b;
      }
      catch ( Exception e ) {
         e.printStackTrace(System.err);
      }
      return null;
   }

   public boolean writeRecord(Transaction tx, Key key, Value value) throws DBException {
      checkOpened();
      try {
         Page p;
         try {
            long pos = findValue(tx, key);
            p = getPage(tx, pos);
         }
         catch ( BTreeNotFoundException b ) {
            p = getFreePage(tx);
            addValue(tx, 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.setStatus(RECORD);

         writeValue(tx, p, value);
      }
      catch ( DBException d ) {
         throw d;
      }
      catch ( Exception e ) {
         e.printStackTrace(System.err);
      }
      return true;
   }

   public boolean deleteRecord(Transaction tx, Key key) throws DBException {
      checkOpened();
      try {
         long pos = findValue(tx, key);
         Page p = getPage(tx, pos);

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

         fileHeader.decRecordCount();
         return true;
      }
      catch ( BTreeNotFoundException b ) {
      }
      catch ( BTreeException b ) {
         throw b;
      }
      catch ( Exception e ) {
         e.printStackTrace(System.err);
      }
      return false;
   }

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

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


   /**
    * BTreeFilerRecordSet
    */

   private class BTreeFilerRecordSet implements RecordSet, BTreeCallback {
      private Transaction tx;
      private List keys;
      private Iterator iter;

      public BTreeFilerRecordSet(Transaction tx) throws DBException {
         this.tx = tx;
         try {
            keys = new ArrayList((int)fileHeader.getRecordCount());
            query(tx, null, this);
            iter = keys.iterator();
         }
         catch ( IOException e ) {
            throw new FilerException(FaultCodes.GEN_CRITICAL_ERROR, "Error generating RecordSet", e);
         }
      }

      public synchronized void indexInfo(Value value, Value extra) {
         keys.add(new Key(value));
      }

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

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

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

      public synchronized boolean hasMoreRecords() {
         return iter.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;

      public BTreeFilerPageHeader() {
      }

      public BTreeFilerPageHeader(ByteBuffer buf) throws IOException {
         super(buf);
      }

      public synchronized void read(ByteBuffer buf) throws IOException {
         super.read(buf);

         if ( getStatus() == UNUSED )
            return;

         created = buf.getLong();
         modified = buf.getLong();
      }

      public synchronized void write(ByteBuffer buf) throws IOException {
         super.write(buf);
         buf.putLong(created);
         buf.putLong(modified);
      }

      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;
      }
   }
}

TOP

Related Classes of com.dbxml.db.common.btree.BTreeFiler$BTreeFilerPageHeader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.