directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r652410 [5/14] - in /directory: apacheds/branches/bigbang/ apacheds/branches/bigbang/apacheds-jdbm/ apacheds/branches/bigbang/apacheds-jdbm/src/ apacheds/branches/bigbang/apacheds-jdbm/src/etc/ apacheds/branches/bigbang/apacheds-jdbm/src/ex...
Date Thu, 01 May 2008 00:06:46 GMT
Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FileHeader.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FileHeader.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FileHeader.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FileHeader.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,156 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: FileHeader.java,v 1.3 2005/06/25 23:12:32 doomdark Exp $
+ */
+
+package jdbm.recman;
+
+/**
+ *  This class represents a file header. It is a 1:1 representation of
+ *  the data that appears in block 0 of a file.
+ */
+class FileHeader implements BlockView {
+    // offsets
+    private static final short O_MAGIC = 0; // short magic
+    private static final short O_LISTS = Magic.SZ_SHORT; // long[2*NLISTS]
+    private static final int O_ROOTS = 
+        O_LISTS + (Magic.NLISTS * 2 * Magic.SZ_LONG);
+
+    // my block
+    private BlockIo block;
+
+    /** The number of "root" rowids available in the file. */
+    static final int NROOTS = 
+        (RecordFile.BLOCK_SIZE - O_ROOTS) / Magic.SZ_LONG;
+
+    /**
+     *  Constructs a FileHeader object from a block.
+     *
+     *  @param block The block that contains the file header
+     *  @param isNew If true, the file header is for a new file.
+     *  @throws IOException if the block is too short to keep the file
+     *          header.
+     */
+    FileHeader(BlockIo block, boolean isNew) {
+        this.block = block;
+        if (isNew)
+            block.writeShort(O_MAGIC, Magic.FILE_HEADER);
+        else if (!magicOk())
+            throw new Error("CRITICAL: file header magic not OK " 
+                            + block.readShort(O_MAGIC));
+    }
+
+    /** Returns true if the magic corresponds with the fileHeader magic.  */
+    private boolean magicOk() {
+        return block.readShort(O_MAGIC) == Magic.FILE_HEADER;
+    }
+
+
+    /** Returns the offset of the "first" block of the indicated list */
+    private short offsetOfFirst(int list) {
+        return (short) (O_LISTS + (2 * Magic.SZ_LONG * list));
+    }
+
+    /** Returns the offset of the "last" block of the indicated list */
+    private short offsetOfLast(int list) {
+        return (short) (offsetOfFirst(list) + Magic.SZ_LONG);
+    }
+
+    /** Returns the offset of the indicated root */
+    private short offsetOfRoot(int root) {
+        return (short) (O_ROOTS + (root * Magic.SZ_LONG));
+    }
+
+    /**
+     *  Returns the first block of the indicated list
+     */
+    long getFirstOf(int list) {
+        return block.readLong(offsetOfFirst(list));
+    }
+    
+    /**
+     *  Sets the first block of the indicated list
+     */
+    void setFirstOf(int list, long value) {
+        block.writeLong(offsetOfFirst(list), value);
+    }
+    
+    /**
+     *  Returns the last block of the indicated list
+     */
+    long getLastOf(int list) {
+        return block.readLong(offsetOfLast(list));
+    }
+    
+    /**
+     *  Sets the last block of the indicated list
+     */
+    void setLastOf(int list, long value) {
+        block.writeLong(offsetOfLast(list), value);
+    }
+
+    /**
+     *  Returns the indicated root rowid. A root rowid is a special rowid
+     *  that needs to be kept between sessions. It could conceivably be
+     *  stored in a special file, but as a large amount of space in the
+     *  block header is wasted anyway, it's more useful to store it where
+     *  it belongs.
+     *
+     *  @see #NROOTS
+     */
+    long getRoot(int root) {
+        return block.readLong(offsetOfRoot(root));
+    }
+
+    /**
+     *  Sets the indicated root rowid.
+     *
+     *  @see #getRoot
+     *  @see #NROOTS
+     */
+    void setRoot(int root, long rowid) {
+        block.writeLong(offsetOfRoot(root), rowid);
+    }
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreeLogicalRowIdPage.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreeLogicalRowIdPage.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreeLogicalRowIdPage.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreeLogicalRowIdPage.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,154 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: FreeLogicalRowIdPage.java,v 1.1 2000/05/06 00:00:31 boisvert Exp $
+ */
+
+package jdbm.recman;
+
+/**
+ *  Class describing a page that holds logical rowids that were freed. Note
+ *  that the methods have *physical* rowids in their signatures - this is
+ *  because logical and physical rowids are internally the same, only their
+ *  external representation (i.e. in the client API) differs.
+ */
+class FreeLogicalRowIdPage extends PageHeader {
+    // offsets
+    private static final short O_COUNT = PageHeader.SIZE; // short count
+    static final short O_FREE = (short)(O_COUNT + Magic.SZ_SHORT);
+    static final short ELEMS_PER_PAGE = (short)
+        ((RecordFile.BLOCK_SIZE - O_FREE) / PhysicalRowId.SIZE);
+
+    // slots we returned.
+    final PhysicalRowId[] slots = new PhysicalRowId[ELEMS_PER_PAGE];
+
+    /**
+     *  Constructs a data page view from the indicated block.
+     */
+    FreeLogicalRowIdPage(BlockIo block) {
+        super(block);
+    }
+
+    /**
+     *  Factory method to create or return a data page for the
+     *  indicated block.
+     */
+    static FreeLogicalRowIdPage getFreeLogicalRowIdPageView(BlockIo block) {
+
+        BlockView view = block.getView();
+        if (view != null && view instanceof FreeLogicalRowIdPage)
+            return (FreeLogicalRowIdPage) view;
+        else
+            return new FreeLogicalRowIdPage(block);
+    }
+
+    /** Returns the number of free rowids */
+    short getCount() {
+        return block.readShort(O_COUNT);
+    }
+
+    /** Sets the number of free rowids */
+    private void setCount(short i) {
+        block.writeShort(O_COUNT, i);
+    }
+
+    /** Frees a slot */
+    void free(int slot) {
+        get(slot).setBlock(0);
+        setCount((short) (getCount() - 1));
+    }
+
+    /** Allocates a slot */
+    PhysicalRowId alloc(int slot) {
+        setCount((short) (getCount() + 1));
+        get(slot).setBlock(-1);
+        return get(slot);
+    }
+
+    /** Returns true if a slot is allocated */
+    boolean isAllocated(int slot) {
+        return get(slot).getBlock() > 0;
+    }
+
+    /** Returns true if a slot is free */
+    boolean isFree(int slot) {
+        return !isAllocated(slot);
+    }
+
+
+    /** Returns the value of the indicated slot */
+    PhysicalRowId get(int slot) {
+        if (slots[slot] == null)
+            slots[slot] = new PhysicalRowId(block, slotToOffset(slot));;
+        return slots[slot];
+    }
+
+    /** Converts slot to offset */
+    private short slotToOffset(int slot) {
+        return (short) (O_FREE +
+                        (slot * PhysicalRowId.SIZE));
+    }
+
+    /**
+     *  Returns first free slot, -1 if no slots are available
+     */
+    int getFirstFree() {
+        for (int i = 0; i < ELEMS_PER_PAGE; i++) {
+            if (isFree(i))
+                return i;
+        }
+        return -1;
+    }
+
+    /**
+     *  Returns first allocated slot, -1 if no slots are available.
+     */
+    int getFirstAllocated() {
+        for (int i = 0; i < ELEMS_PER_PAGE; i++) {
+            if (isAllocated(i))
+                return i;
+        }
+        return -1;
+    }
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreeLogicalRowIdPageManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreeLogicalRowIdPageManager.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreeLogicalRowIdPageManager.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreeLogicalRowIdPageManager.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,143 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: FreeLogicalRowIdPageManager.java,v 1.1 2000/05/06 00:00:31 boisvert Exp $
+ */
+
+package jdbm.recman;
+
+import java.io.IOException;
+
+/**
+ *  This class manages free Logical rowid pages and provides methods
+ *  to free and allocate Logical rowids on a high level.
+ */
+final class FreeLogicalRowIdPageManager {
+    // our record file
+    private RecordFile file;
+    // our page manager
+    private PageManager pageman;
+
+    /**
+     *  Creates a new instance using the indicated record file and
+     *  page manager.
+     */
+    FreeLogicalRowIdPageManager(RecordFile file,
+                                PageManager pageman) throws IOException {
+        this.file = file;
+        this.pageman = pageman;
+    }
+
+    /**
+     *  Returns a free Logical rowid, or
+     *  null if nothing was found.
+     */
+    Location get() throws IOException {
+  
+        // Loop through the free Logical rowid list until we find
+        // the first rowid.
+        Location retval = null;
+        PageCursor curs = new PageCursor(pageman, Magic.FREELOGIDS_PAGE);
+        while (curs.next() != 0) {
+            FreeLogicalRowIdPage fp = FreeLogicalRowIdPage
+                .getFreeLogicalRowIdPageView(file.get(curs.getCurrent()));
+            int slot = fp.getFirstAllocated();
+            if (slot != -1) {
+                // got one!
+                retval =
+                    new Location(fp.get(slot));
+                fp.free(slot);
+                if (fp.getCount() == 0) {
+                    // page became empty - free it
+                    file.release(curs.getCurrent(), false);
+                    pageman.free(Magic.FREELOGIDS_PAGE, curs.getCurrent());
+                }
+                else
+                    file.release(curs.getCurrent(), true);
+                
+                return retval;
+            }
+            else {
+                // no luck, go to next page
+                file.release(curs.getCurrent(), false);
+            }     
+        }
+        return null;
+    }
+
+    /**
+     *  Puts the indicated rowid on the free list
+     */
+    void put(Location rowid)
+    throws IOException {
+        
+        PhysicalRowId free = null;
+        PageCursor curs = new PageCursor(pageman, Magic.FREELOGIDS_PAGE);
+        long freePage = 0;
+        while (curs.next() != 0) {
+            freePage = curs.getCurrent();
+            BlockIo curBlock = file.get(freePage);
+            FreeLogicalRowIdPage fp = FreeLogicalRowIdPage
+                .getFreeLogicalRowIdPageView(curBlock);
+            int slot = fp.getFirstFree();
+            if (slot != -1) {
+                free = fp.alloc(slot);
+                break;
+            }
+            
+            file.release(curBlock);
+        }
+        if (free == null) {
+            // No more space on the free list, add a page.
+            freePage = pageman.allocate(Magic.FREELOGIDS_PAGE);
+            BlockIo curBlock = file.get(freePage);
+            FreeLogicalRowIdPage fp = 
+                FreeLogicalRowIdPage.getFreeLogicalRowIdPageView(curBlock);
+            free = fp.alloc(0);
+        }
+        free.setBlock(rowid.getBlock());
+        free.setOffset(rowid.getOffset());
+        file.release(freePage, true);
+    }
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowId.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowId.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowId.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowId.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,77 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: FreePhysicalRowId.java,v 1.1 2000/05/06 00:00:31 boisvert Exp $
+ */
+
+package jdbm.recman;
+
+/**
+ *  This class extends the physical rowid with a size value to indicated
+ *  the size of a free rowid on the free rowid list.
+ */
+final class FreePhysicalRowId extends PhysicalRowId {
+    // offsets
+    private static final short O_SIZE = PhysicalRowId.SIZE; // int size
+    static final short SIZE = O_SIZE + Magic.SZ_INT;
+
+    /**
+     *  Constructs a physical rowid from the indicated data starting at
+     *  the indicated position.
+     */
+    FreePhysicalRowId(BlockIo block, short pos) {
+  super(block, pos);
+    }
+
+    /** Returns the size */
+    int getSize() {
+  return block.readInt(pos + O_SIZE);
+    }
+
+    /** Sets the size */
+    void setSize(int value) {
+  block.writeInt(pos + O_SIZE, value);
+    }
+
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowIdPage.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowIdPage.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowIdPage.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowIdPage.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,150 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: FreePhysicalRowIdPage.java,v 1.1 2000/05/06 00:00:31 boisvert Exp $
+ */
+
+package jdbm.recman;
+
+/**
+ *  Class describing a page that holds physical rowids that were freed.
+ */
+final class FreePhysicalRowIdPage extends PageHeader {
+    // offsets
+    private static final short O_COUNT = PageHeader.SIZE; // short count
+    static final short O_FREE = O_COUNT + Magic.SZ_SHORT;
+    static final short ELEMS_PER_PAGE = 
+  (RecordFile.BLOCK_SIZE - O_FREE) / FreePhysicalRowId.SIZE;
+    
+    // slots we returned.
+    FreePhysicalRowId[] slots = new FreePhysicalRowId[ELEMS_PER_PAGE];
+
+    /**
+     *  Constructs a data page view from the indicated block.
+     */
+    FreePhysicalRowIdPage(BlockIo block) {
+  super(block);
+    }
+
+    /**
+     *  Factory method to create or return a data page for the
+     *  indicated block.
+     */
+    static FreePhysicalRowIdPage getFreePhysicalRowIdPageView(BlockIo block) {
+  BlockView view = block.getView();
+  if (view != null && view instanceof FreePhysicalRowIdPage)
+      return (FreePhysicalRowIdPage) view;
+  else
+      return new FreePhysicalRowIdPage(block);
+    }
+
+    /** Returns the number of free rowids */
+    short getCount() {
+  return block.readShort(O_COUNT);
+    }
+
+    /** Sets the number of free rowids */
+    private void setCount(short i) {
+  block.writeShort(O_COUNT, i);
+    }
+
+    /** Frees a slot */
+    void free(int slot) {
+  get(slot).setSize(0);
+  setCount((short) (getCount() - 1));
+    }
+
+    /** Allocates a slot */
+    FreePhysicalRowId alloc(int slot) {
+  setCount((short) (getCount() + 1));
+  return get(slot);
+    }
+
+    /** Returns true if a slot is allocated */
+    boolean isAllocated(int slot) {
+  return get(slot).getSize() != 0;
+    }
+
+    /** Returns true if a slot is free */
+    boolean isFree(int slot) {
+  return !isAllocated(slot);
+    }
+    
+    
+    /** Returns the value of the indicated slot */
+    FreePhysicalRowId get(int slot) {
+  if (slots[slot] == null) 
+      slots[slot] = new FreePhysicalRowId(block, slotToOffset(slot));;
+  return slots[slot];
+    }
+
+    /** Converts slot to offset */
+    short slotToOffset(int slot) {
+  return (short) (O_FREE +
+      (slot * FreePhysicalRowId.SIZE));
+    }
+    
+    /** 
+     *  Returns first free slot, -1 if no slots are available
+     */
+    int getFirstFree() {
+  for (int i = 0; i < ELEMS_PER_PAGE; i++) {
+      if (isFree(i))
+    return i;
+  }
+  return -1;
+    }
+
+    /** 
+     *  Returns first slot with available size >= indicated size,  
+     *  or -1 if no slots are available.
+     **/
+    int getFirstLargerThan(int size) {
+  for (int i = 0; i < ELEMS_PER_PAGE; i++) {
+      if (isAllocated(i) && get(i).getSize() >= size)
+    return i;
+  }
+  return -1;
+    }
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowIdPageManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowIdPageManager.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowIdPageManager.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/FreePhysicalRowIdPageManager.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,152 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot.
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: FreePhysicalRowIdPageManager.java,v 1.2 2001/11/17 16:14:25 boisvert Exp $
+ */
+
+package jdbm.recman;
+
+import java.io.IOException;
+
+/**
+ *  This class manages free physical rowid pages and provides methods
+ *  to free and allocate physical rowids on a high level.
+ */
+final class FreePhysicalRowIdPageManager
+{
+    // our record file
+    protected RecordFile _file;
+
+    // our page manager
+    protected PageManager _pageman;
+
+    /**
+     *  Creates a new instance using the indicated record file and
+     *  page manager.
+     */
+    FreePhysicalRowIdPageManager( RecordFile file, PageManager pageman )
+        throws IOException
+    {
+        _file = file;
+        _pageman = pageman;
+    }
+
+
+    /**
+     *  Returns a free physical rowid of the indicated size, or
+     *  null if nothing was found.
+     */
+    Location get( int size )
+        throws IOException
+    {
+        // Loop through the free physical rowid list until we find
+        // a rowid that's large enough.
+        Location retval = null;
+        PageCursor curs = new PageCursor( _pageman, Magic.FREEPHYSIDS_PAGE );
+
+        while (curs.next() != 0) {
+            FreePhysicalRowIdPage fp = FreePhysicalRowIdPage
+                .getFreePhysicalRowIdPageView( _file.get( curs.getCurrent() ) );
+            int slot = fp.getFirstLargerThan( size );
+            if ( slot != -1 ) {
+                // got one!
+                retval = new Location( fp.get( slot ) );
+
+                int slotsize = fp.get( slot ).getSize();
+                fp.free( slot );
+                if ( fp.getCount() == 0 ) {
+                    // page became empty - free it
+                    _file.release( curs.getCurrent(), false );
+                    _pageman.free( Magic.FREEPHYSIDS_PAGE, curs.getCurrent() );
+                } else {
+                    _file.release( curs.getCurrent(), true );
+                }
+
+                return retval;
+            } else {
+                // no luck, go to next page
+                _file.release( curs.getCurrent(), false );
+            }
+
+        }
+        return null;
+    }
+
+    /**
+     *  Puts the indicated rowid on the free list
+     */
+    void put(Location rowid, int size)
+  throws IOException {
+
+  FreePhysicalRowId free = null;
+  PageCursor curs = new PageCursor(_pageman, Magic.FREEPHYSIDS_PAGE);
+  long freePage = 0;
+  while (curs.next() != 0) {
+      freePage = curs.getCurrent();
+      BlockIo curBlock = _file.get(freePage);
+      FreePhysicalRowIdPage fp = FreePhysicalRowIdPage
+    .getFreePhysicalRowIdPageView(curBlock);
+      int slot = fp.getFirstFree();
+      if (slot != -1) {
+    free = fp.alloc(slot);
+    break;
+      }
+
+      _file.release(curBlock);
+  }
+  if (free == null) {
+      // No more space on the free list, add a page.
+      freePage = _pageman.allocate(Magic.FREEPHYSIDS_PAGE);
+      BlockIo curBlock = _file.get(freePage);
+      FreePhysicalRowIdPage fp =
+    FreePhysicalRowIdPage.getFreePhysicalRowIdPageView(curBlock);
+      free = fp.alloc(0);
+  }
+
+  free.setBlock(rowid.getBlock());
+  free.setOffset(rowid.getOffset());
+  free.setSize(size);
+  _file.release(freePage, true);
+    }
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Location.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Location.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Location.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Location.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,121 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: Location.java,v 1.2 2003/11/01 14:17:21 dranatunga Exp $
+ */
+
+package jdbm.recman;
+
+/**
+ * This class represents a location within a file. Both physical and
+ * logical rowids are based on locations internally - this version is
+ * used when there is no file block to back the location's data.
+ */
+final class Location {
+    private long block;
+    private short offset;
+
+    /**
+     * Creates a location from a (block, offset) tuple.
+     */
+    Location(long block, short offset) {
+        this.block = block;
+        this.offset = offset;
+    }
+
+    /**
+     * Creates a location from a combined block/offset long, as
+     * used in the external representation of logical rowids.
+     * 
+     * @see #toLong()
+     */
+    Location(long blockOffset) {
+        this.offset = (short) (blockOffset & 0xffff);
+        this.block = blockOffset >> 16;
+    }
+
+    /**
+     * Creates a location based on the data of the physical rowid.
+     */
+    Location(PhysicalRowId src) {
+        block = src.getBlock();
+        offset = src.getOffset();
+    }
+
+    /**
+     * Returns the file block of the location
+     */
+    long getBlock() {
+        return block;
+    }
+
+    /**
+     * Returns the offset within the block of the location
+     */
+    short getOffset() {
+        return offset;
+    }
+
+    /**
+     * Returns the external representation of a location when used
+     * as a logical rowid, which combines the block and the offset
+     * in a single long.
+     */
+    long toLong() {
+        return (block << 16) + (long) offset;
+    }
+
+    // overrides of java.lang.Object
+
+    public boolean equals(Object o) {
+        if (o == null || !(o instanceof Location))
+            return false;
+        Location ol = (Location) o;
+        return ol.block == block && ol.offset == offset;
+    }
+
+    public String toString() {
+        return "PL(" + block + ":" + offset + ")";
+    }
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/LogicalRowIdManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/LogicalRowIdManager.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/LogicalRowIdManager.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/LogicalRowIdManager.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,145 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot.
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: LogicalRowIdManager.java,v 1.3 2005/06/25 23:12:32 doomdark Exp $
+ */
+
+package jdbm.recman;
+
+import java.io.IOException;
+
+/**
+ *  This class manages the linked lists of logical rowid pages.
+ */
+final class LogicalRowIdManager {
+    // our record file and associated page manager
+    private RecordFile file;
+    private PageManager pageman;
+    private FreeLogicalRowIdPageManager freeman;
+
+    /**
+     *  Creates a log rowid manager using the indicated record file and
+     *  page manager
+     */
+    LogicalRowIdManager(RecordFile file, PageManager pageman)
+  throws IOException {
+  this.file = file;
+  this.pageman = pageman;
+  this.freeman = new FreeLogicalRowIdPageManager(file, pageman);
+
+    }
+
+    /**
+     *  Creates a new logical rowid pointing to the indicated physical
+     *  id
+     */
+    Location insert(Location loc)
+    throws IOException {
+  // check whether there's a free rowid to reuse
+  Location retval = freeman.get();
+  if (retval == null) {
+      // no. This means that we bootstrap things by allocating
+      // a new translation page and freeing all the rowids on it.
+      long firstPage = pageman.allocate(Magic.TRANSLATION_PAGE);
+      short curOffset = TranslationPage.O_TRANS;
+      for (int i = 0; i < TranslationPage.ELEMS_PER_PAGE; i++) {
+    freeman.put(new Location(firstPage, curOffset));
+    curOffset += PhysicalRowId.SIZE;
+      }
+      retval = freeman.get();
+      if (retval == null) {
+    throw new Error("couldn't obtain free translation");
+      }
+  }
+  // write the translation.
+  update(retval, loc);
+  return retval;
+    }
+
+    /**
+     *  Releases the indicated logical rowid.
+     */
+    void delete(Location rowid)
+  throws IOException {
+
+  freeman.put(rowid);
+    }
+
+    /**
+     *  Updates the mapping
+     *
+     *  @param rowid The logical rowid
+     *  @param loc The physical rowid
+     */
+    void update(Location rowid, Location loc)
+    throws IOException {
+
+        TranslationPage xlatPage = TranslationPage.getTranslationPageView(
+                                       file.get(rowid.getBlock()));
+        PhysicalRowId physid = xlatPage.get(rowid.getOffset());
+        physid.setBlock(loc.getBlock());
+        physid.setOffset(loc.getOffset());
+        file.release(rowid.getBlock(), true);
+    }
+
+    /**
+     *  Returns a mapping
+     *
+     *  @param rowid The logical rowid
+     *  @return The physical rowid
+     */
+    Location fetch(Location rowid)
+    throws IOException {
+
+        TranslationPage xlatPage = TranslationPage.getTranslationPageView(
+                                       file.get(rowid.getBlock()));
+        try {
+            Location retval = new Location(xlatPage.get(rowid.getOffset()));
+            return retval;
+        } finally {
+            file.release(rowid.getBlock(), false);
+        }
+    }
+
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Magic.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Magic.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Magic.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Magic.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,87 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: Magic.java,v 1.1 2000/05/06 00:00:31 boisvert Exp $
+ */
+
+package jdbm.recman;
+
+/**
+ *  This interface contains magic cookies.
+ */
+public interface Magic {
+    /** Magic cookie at start of file */
+    public short FILE_HEADER = 0x1350;
+
+    /** Magic for blocks. They're offset by the block type magic codes. */
+    public short BLOCK = 0x1351;
+
+    /** Magics for blocks in certain lists. Offset by baseBlockMagic */
+    short FREE_PAGE = 0;
+    short USED_PAGE = 1;
+    short TRANSLATION_PAGE = 2;
+    short FREELOGIDS_PAGE = 3;
+    short FREEPHYSIDS_PAGE = 4;
+
+    /** Number of lists in a file */
+    public short NLISTS = 5;
+
+    /**
+     *  Maximum number of blocks in a file, leaving room for a 16 bit
+     *  offset encoded within a long.
+     */
+    long MAX_BLOCKS = 0x7FFFFFFFFFFFL;
+
+    /** Magic for transaction file */
+    short LOGFILE_HEADER = 0x1360;
+
+    /** Size of an externalized byte */
+    public short SZ_BYTE = 1;
+    /** Size of an externalized short */
+    public short SZ_SHORT = 2;
+    /** Size of an externalized int */
+    public short SZ_INT = 4;
+    /** Size of an externalized long */
+    public short SZ_LONG = 8;
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageCursor.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageCursor.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageCursor.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,103 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: PageCursor.java,v 1.1 2000/05/06 00:00:31 boisvert Exp $
+ */
+
+package jdbm.recman;
+
+import java.io.IOException;
+
+/**
+ *  This class provides a cursor that can follow lists of pages
+ *  bi-directionally.
+ */
+final class PageCursor {
+    PageManager pageman;
+    long current;
+    short type;
+    
+    /**
+     *  Constructs a page cursor that starts at the indicated block.
+     */
+    PageCursor(PageManager pageman, long current) {
+        this.pageman = pageman;
+        this.current = current;
+    }
+    
+    /**
+     *  Constructs a page cursor that starts at the first block
+     *  of the indicated list.
+     */
+    PageCursor(PageManager pageman, short type) throws IOException {
+        this.pageman = pageman;
+        this.type = type;
+    }
+    
+    /**
+     *  Returns the current value of the cursor.
+     */
+    long getCurrent() throws IOException {
+        return current;
+    }
+    
+    /**
+     *  Returns the next value of the cursor
+     */
+    long next() throws IOException {
+        if (current == 0)
+            current = pageman.getFirst(type);
+        else
+            current = pageman.getNext(current);
+        return current;
+    } 
+    
+    /**
+     *  Returns the previous value of the cursor
+     */
+    long prev() throws IOException {
+        current = pageman.getPrev(current);
+        return current;
+    }
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageHeader.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageHeader.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageHeader.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageHeader.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,156 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: PageHeader.java,v 1.2 2003/09/21 15:47:01 boisvert Exp $
+ */
+
+package jdbm.recman;
+
+/**
+ *  This class represents a page header. It is the common superclass for
+ *  all different page views.
+ */
+public class PageHeader implements BlockView {
+    // offsets
+    private static final short O_MAGIC = 0; // short magic
+    private static final short O_NEXT = Magic.SZ_SHORT;  // long next
+    private static final short O_PREV = O_NEXT + Magic.SZ_LONG; // long prev
+    protected static final short SIZE = O_PREV + Magic.SZ_LONG;
+
+    // my block
+    protected BlockIo block;
+
+    /**
+     *  Constructs a PageHeader object from a block
+     *
+     *  @param block The block that contains the file header
+     *  @throws IOException if the block is too short to keep the file
+     *          header.
+     */
+    protected PageHeader(BlockIo block) {
+        initialize(block);
+        if (!magicOk())
+            throw new Error("CRITICAL: page header magic for block "
+                            + block.getBlockId() + " not OK "
+                            + getMagic());
+    }
+    
+    /**
+     *  Constructs a new PageHeader of the indicated type. Used for newly
+     *  created pages.
+     */
+    PageHeader(BlockIo block, short type) {
+        initialize(block);
+        setType(type);
+    }
+    
+    /**
+     *  Factory method to create or return a page header for the
+     *  indicated block.
+     */
+    static PageHeader getView(BlockIo block) {
+        BlockView view = block.getView();
+        if (view != null && view instanceof PageHeader)
+            return (PageHeader) view;
+        else
+            return new PageHeader(block);
+    }
+    
+    private void initialize(BlockIo block) {
+        this.block = block;
+        block.setView(this);
+    }
+    
+    /**
+     *  Returns true if the magic corresponds with the fileHeader magic.
+     */
+    private boolean magicOk() {
+        int magic = getMagic();
+        return magic >= Magic.BLOCK
+            && magic <= (Magic.BLOCK + Magic.FREEPHYSIDS_PAGE);
+    }
+    
+    /**
+     *  For paranoia mode
+     */
+    protected void paranoiaMagicOk() {
+        if (!magicOk())
+            throw new Error("CRITICAL: page header magic not OK "
+                            + getMagic());
+    }
+    
+    /** Returns the magic code */
+    short getMagic() {
+        return block.readShort(O_MAGIC);
+    }
+
+    /** Returns the next block. */
+    long getNext() {
+        paranoiaMagicOk();
+        return block.readLong(O_NEXT);
+    }
+    
+    /** Sets the next block. */
+    void setNext(long next) {
+        paranoiaMagicOk();
+        block.writeLong(O_NEXT, next);
+    }
+    
+    /** Returns the previous block. */
+    long getPrev() {
+        paranoiaMagicOk();
+        return block.readLong(O_PREV);
+    }
+    
+    /** Sets the previous block. */
+    void setPrev(long prev) {
+        paranoiaMagicOk();
+        block.writeLong(O_PREV, prev);
+    }
+    
+    /** Sets the type of the page header */
+    void setType(short type) {
+        block.writeShort(O_MAGIC, (short) (Magic.BLOCK + type));
+    }
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageManager.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageManager.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PageManager.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,272 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: PageManager.java,v 1.3 2005/06/25 23:12:32 doomdark Exp $
+ */
+
+package jdbm.recman;
+
+import java.io.*;
+
+/**
+ *  This class manages the linked lists of pages that make up a file.
+ */
+final class PageManager {
+    // our record file
+    private RecordFile file;
+    // header data
+    private FileHeader header;
+    private BlockIo headerBuf;
+    
+    /**
+     *  Creates a new page manager using the indicated record file.
+     */
+    PageManager(RecordFile file) throws IOException {
+        this.file = file;
+        
+        // check the file header. If the magic is 0, we assume a new
+        // file. Note that we hold on to the file header node.
+        headerBuf = file.get(0);
+        if (headerBuf.readShort(0) == 0)
+            header = new FileHeader(headerBuf, true);
+        else
+            header = new FileHeader(headerBuf, false);
+    }
+    
+    /**
+     *  Allocates a page of the indicated type. Returns recid of the
+     *  page.
+     */
+    long allocate(short type) throws IOException {
+        
+        if (type == Magic.FREE_PAGE)
+            throw new Error("allocate of free page?");
+        
+        // do we have something on the free list?
+        long retval = header.getFirstOf(Magic.FREE_PAGE);
+        boolean isNew = false;
+        if (retval != 0) {
+            // yes. Point to it and make the next of that page the
+            // new first free page.
+            header.setFirstOf(Magic.FREE_PAGE, getNext(retval));
+        }
+        else {
+            // nope. make a new record
+            retval = header.getLastOf(Magic.FREE_PAGE);
+            if (retval == 0)
+                // very new file - allocate record #1
+                retval = 1;
+            header.setLastOf(Magic.FREE_PAGE, retval + 1);
+            isNew = true;
+        }
+        
+        // Cool. We have a record, add it to the correct list
+        BlockIo buf = file.get(retval);
+        PageHeader pageHdr = isNew ? new PageHeader(buf, type) 
+            : PageHeader.getView(buf);
+        long oldLast = header.getLastOf(type);
+        
+        // Clean data.
+        System.arraycopy(RecordFile.cleanData, 0, 
+                         buf.getData(), 0, 
+                         RecordFile.BLOCK_SIZE);
+        pageHdr.setType(type);
+        pageHdr.setPrev(oldLast);
+        pageHdr.setNext(0);
+        
+        
+        if (oldLast == 0)
+            // This was the first one of this type
+            header.setFirstOf(type, retval);
+        header.setLastOf(type, retval);
+        file.release(retval, true);
+        
+        // If there's a previous, fix up its pointer
+        if (oldLast != 0) {
+            buf = file.get(oldLast);
+            pageHdr = PageHeader.getView(buf);
+            pageHdr.setNext(retval);
+            file.release(oldLast, true);
+        }
+        
+        // remove the view, we have modified the type.
+        buf.setView(null);
+        
+        return retval;
+    }
+    
+    /**
+     *  Frees a page of the indicated type.
+     */
+    void free(short type, long recid) throws IOException {
+        if (type == Magic.FREE_PAGE)
+            throw new Error("free free page?");
+        if (recid == 0)
+            throw new Error("free header page?");
+        
+        // get the page and read next and previous pointers
+        BlockIo buf = file.get(recid);
+        PageHeader pageHdr = PageHeader.getView(buf);
+        long prev = pageHdr.getPrev();
+        long next = pageHdr.getNext();
+        
+        // put the page at the front of the free list.
+        pageHdr.setType(Magic.FREE_PAGE);
+        pageHdr.setNext(header.getFirstOf(Magic.FREE_PAGE));
+        pageHdr.setPrev(0);
+        
+        header.setFirstOf(Magic.FREE_PAGE, recid);
+        file.release(recid, true);
+        
+        // remove the page from its old list
+        if (prev != 0) {
+            buf = file.get(prev);
+            pageHdr = PageHeader.getView(buf);
+            pageHdr.setNext(next);
+            file.release(prev, true);
+        }
+        else {
+            header.setFirstOf(type, next);
+        }
+        if (next != 0) {
+            buf = file.get(next);
+            pageHdr = PageHeader.getView(buf);
+            pageHdr.setPrev(prev);
+            file.release(next, true);
+        }
+        else {
+            header.setLastOf(type, prev);
+        }
+        
+    }
+    
+    
+    /**
+     *  Returns the page following the indicated block
+     */
+    long getNext(long block) throws IOException {
+        try {
+            return PageHeader.getView(file.get(block)).getNext();
+        } finally {
+            file.release(block, false);
+        }
+    }
+    
+    /**
+     *  Returns the page before the indicated block
+     */
+    long getPrev(long block) throws IOException {
+        try {
+            return PageHeader.getView(file.get(block)).getPrev();
+        } finally {
+            file.release(block, false);
+        }
+    }
+    
+    /**
+     *  Returns the first page on the indicated list.
+     */
+    long getFirst(short type) throws IOException {
+        return header.getFirstOf(type);
+    }
+
+    /**
+     *  Returns the last page on the indicated list.
+     */
+    long getLast(short type) throws IOException {
+        return header.getLastOf(type);
+    }
+    
+    
+    /**
+     *  Commit all pending (in-memory) data by flushing the page manager.
+     *  This forces a flush of all outstanding blocks (this it's an implicit
+     *  {@link RecordFile#commit} as well).
+     */
+    void commit() throws IOException {
+        // write the header out
+        file.release(headerBuf);
+        file.commit();
+
+        // and obtain it again
+        headerBuf = file.get(0);
+        header = new FileHeader(headerBuf, false);
+    }
+
+    /**
+     *  Flushes the page manager. This forces a flush of all outstanding
+     *  blocks (this it's an implicit {@link RecordFile#commit} as well).
+     */
+    void rollback() throws IOException {
+        // release header
+        file.discard(headerBuf);
+        file.rollback();
+        // and obtain it again
+        headerBuf = file.get(0);
+        if (headerBuf.readShort(0) == 0)
+            header = new FileHeader(headerBuf, true);
+        else
+            header = new FileHeader(headerBuf, false);
+    }
+    
+    /**
+     *  Closes the page manager. This flushes the page manager and releases
+     *  the lock on the header.
+     */
+    void close() throws IOException {   
+        file.release(headerBuf);
+        file.commit();
+        headerBuf = null;
+        header = null;
+        file = null;
+    }
+    
+    /**
+     *  Returns the file header.
+     */
+    FileHeader getFileHeader() {
+        return header;
+    }
+    
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PhysicalRowId.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PhysicalRowId.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PhysicalRowId.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PhysicalRowId.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,95 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot. 
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: PhysicalRowId.java,v 1.1 2000/05/06 00:00:31 boisvert Exp $
+ */
+
+package jdbm.recman;
+
+/**
+ *  A physical rowid is nothing else than a pointer to a physical location
+ *  in a file - a (block, offset) tuple.
+ *  <P>
+ *  <B>Note</B>: The fact that the offset is modelled as a short limits 
+ *  the block size to 32k.
+ */
+class PhysicalRowId {
+    // offsets
+    private static final short O_BLOCK = 0; // long block
+    private static final short O_OFFSET = Magic.SZ_LONG; // short offset
+    static final int SIZE = O_OFFSET + Magic.SZ_SHORT;
+    
+    // my block and the position within the block
+    BlockIo block;
+    short pos;
+
+    /**
+     *  Constructs a physical rowid from the indicated data starting at
+     *  the indicated position.
+     */
+    PhysicalRowId(BlockIo block, short pos) {
+        this.block = block;
+        this.pos = pos;
+    }
+    
+    /** Returns the block number */
+    long getBlock() {
+        return block.readLong(pos + O_BLOCK);
+    }
+    
+    /** Sets the block number */
+    void setBlock(long value) {
+        block.writeLong(pos + O_BLOCK, value);
+    }
+    
+    /** Returns the offset */
+    short getOffset() {
+        return block.readShort(pos + O_OFFSET);
+    }
+    
+    /** Sets the offset */
+    void setOffset(short value) {
+        block.writeShort(pos + O_OFFSET, value);
+    }
+}

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PhysicalRowIdManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PhysicalRowIdManager.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PhysicalRowIdManager.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/PhysicalRowIdManager.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,338 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot.
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: PhysicalRowIdManager.java,v 1.3 2003/03/21 03:00:09 boisvert Exp $
+ */
+
+package jdbm.recman;
+
+import java.io.IOException;
+
+/**
+ *  This class manages physical row ids, and their data.
+ */
+final class PhysicalRowIdManager
+{
+
+    // The file we're talking to and the associated page manager.
+    private RecordFile file;
+    private PageManager pageman;
+    private FreePhysicalRowIdPageManager freeman;
+
+    /**
+     *  Creates a new rowid manager using the indicated record file.
+     *  and page manager.
+     */
+    PhysicalRowIdManager( RecordFile file, PageManager pageManager )
+        throws IOException
+    {
+        this.file = file;
+        this.pageman = pageManager;
+        this.freeman = new FreePhysicalRowIdPageManager(file, pageman);
+    }
+
+    /**
+     *  Inserts a new record. Returns the new physical rowid.
+     */
+    Location insert( byte[] data, int start, int length )
+        throws IOException
+    {
+        Location retval = alloc( length );
+        write( retval, data, start, length );
+        return retval;
+    }
+
+    /**
+     *  Updates an existing record. Returns the possibly changed
+     *  physical rowid.
+     */
+    Location update( Location rowid, byte[] data, int start, int length )
+        throws IOException
+    {
+        // fetch the record header
+        BlockIo block = file.get( rowid.getBlock() );
+        RecordHeader head = new RecordHeader( block, rowid.getOffset() );
+        if ( length > head.getAvailableSize() ) {
+            // not enough space - we need to copy to a new rowid.
+            file.release( block );
+            free( rowid );
+            rowid = alloc( length );
+        } else {
+            file.release( block );
+        }
+
+        // 'nuff space, write it in and return the rowid.
+        write( rowid, data, start, length );
+        return rowid;
+    }
+
+    /**
+     *  Deletes a record.
+     */
+    void delete( Location rowid )
+        throws IOException
+    {
+        free( rowid );
+    }
+
+    /**
+     *  Retrieves a record.
+     */
+    byte[] fetch( Location rowid )
+        throws IOException 
+    {
+        // fetch the record header
+        PageCursor curs = new PageCursor( pageman, rowid.getBlock() );
+        BlockIo block = file.get( curs.getCurrent() );
+        RecordHeader head = new RecordHeader( block, rowid.getOffset() );
+
+        // allocate a return buffer
+        byte[] retval = new byte[ head.getCurrentSize() ];
+        if ( retval.length == 0 ) {
+            file.release( curs.getCurrent(), false );
+            return retval;
+        }
+
+        // copy bytes in
+        int offsetInBuffer = 0;
+        int leftToRead = retval.length;
+        short dataOffset = (short) (rowid.getOffset() + RecordHeader.SIZE);
+        while ( leftToRead > 0 ) {
+            // copy current page's data to return buffer
+            int toCopy = RecordFile.BLOCK_SIZE - dataOffset;
+            if ( leftToRead < toCopy ) {
+                toCopy = leftToRead;
+            }
+            System.arraycopy( block.getData(), dataOffset,
+                              retval, offsetInBuffer,
+                              toCopy );
+
+            // Go to the next block
+            leftToRead -= toCopy;
+            offsetInBuffer += toCopy;
+
+            file.release( block );
+
+            if ( leftToRead > 0 ) {
+                block = file.get( curs.next() );
+                dataOffset = DataPage.O_DATA;
+            }
+
+        }
+
+        return retval;
+    }
+
+    /**
+     *  Allocate a new rowid with the indicated size.
+     */
+    private Location alloc( int size )
+        throws IOException
+    {
+        Location retval = freeman.get( size );
+        if ( retval == null ) {
+            retval = allocNew( size, pageman.getLast( Magic.USED_PAGE ) );
+        }
+        return retval;
+    }
+
+    /**
+     *  Allocates a new rowid. The second parameter is there to
+     *  allow for a recursive call - it indicates where the search
+     *  should start.
+     */
+    private Location allocNew( int size, long start )
+        throws IOException
+    {
+        BlockIo curBlock;
+        DataPage curPage;
+        if ( start == 0 ) {
+            // we need to create a new page.
+            start = pageman.allocate( Magic.USED_PAGE );
+            curBlock = file.get( start );
+            curPage = DataPage.getDataPageView( curBlock );
+            curPage.setFirst( DataPage.O_DATA );
+            RecordHeader hdr = new RecordHeader( curBlock, DataPage.O_DATA );
+            hdr.setAvailableSize( 0 );
+            hdr.setCurrentSize( 0 );
+        } else {
+            curBlock = file.get( start );
+            curPage = DataPage.getDataPageView( curBlock );
+        }
+
+        // follow the rowids on this page to get to the last one. We don't
+        // fall off, because this is the last page, remember?
+        short pos = curPage.getFirst();
+        if ( pos == 0 ) {
+            // page is exactly filled by the last block of a record
+            file.release( curBlock );
+            return allocNew( size, 0 );
+        }
+
+        RecordHeader hdr = new RecordHeader( curBlock, pos );
+        while ( hdr.getAvailableSize() != 0 && pos < RecordFile.BLOCK_SIZE ) {
+            pos += hdr.getAvailableSize() + RecordHeader.SIZE;
+            if ( pos == RecordFile.BLOCK_SIZE ) {
+                // Again, a filled page.
+                file.release( curBlock );
+                return allocNew( size, 0 );
+            }
+
+            hdr = new RecordHeader( curBlock, pos );
+        }
+
+        if ( pos == RecordHeader.SIZE ) {
+            // the last record exactly filled the page. Restart forcing
+            // a new page.
+            file.release( curBlock );
+        }
+
+        // we have the position, now tack on extra pages until we've got
+        // enough space.
+        Location retval = new Location( start, pos );
+        int freeHere = RecordFile.BLOCK_SIZE - pos - RecordHeader.SIZE;
+        if ( freeHere < size ) {
+            // check whether the last page would have only a small bit left.
+            // if yes, increase the allocation. A small bit is a record
+            // header plus 16 bytes.
+            int lastSize = (size - freeHere) % DataPage.DATA_PER_PAGE;
+            if (( DataPage.DATA_PER_PAGE - lastSize ) < (RecordHeader.SIZE + 16) ) {
+                size += (DataPage.DATA_PER_PAGE - lastSize);
+            }
+
+            // write out the header now so we don't have to come back.
+            hdr.setAvailableSize( size );
+            file.release( start, true );
+
+            int neededLeft = size - freeHere;
+            // Refactor these two blocks!
+            while ( neededLeft >= DataPage.DATA_PER_PAGE ) {
+                start = pageman.allocate( Magic.USED_PAGE );
+                curBlock = file.get( start );
+                curPage = DataPage.getDataPageView( curBlock );
+                curPage.setFirst( (short) 0 ); // no rowids, just data
+                file.release( start, true );
+                neededLeft -= DataPage.DATA_PER_PAGE;
+            }
+            if ( neededLeft > 0 ) {
+                // done with whole chunks, allocate last fragment.
+                start = pageman.allocate( Magic.USED_PAGE );
+                curBlock = file.get( start );
+                curPage = DataPage.getDataPageView( curBlock );
+                curPage.setFirst( (short) (DataPage.O_DATA + neededLeft) );
+                file.release( start, true );
+            }
+        } else {
+            // just update the current page. If there's less than 16 bytes
+            // left, we increase the allocation (16 bytes is an arbitrary
+            // number).
+            if ( freeHere - size <= (16 + RecordHeader.SIZE) ) {
+                size = freeHere;
+            }
+            hdr.setAvailableSize( size );
+            file.release( start, true );
+        }
+        return retval;
+
+    }
+
+
+    private void free( Location id )
+        throws IOException
+    {
+        // get the rowid, and write a zero current size into it.
+        BlockIo curBlock = file.get( id.getBlock() );
+        DataPage curPage = DataPage.getDataPageView( curBlock );
+        RecordHeader hdr = new RecordHeader( curBlock, id.getOffset() );
+        hdr.setCurrentSize( 0 );
+        file.release( id.getBlock(), true );
+
+        // write the rowid to the free list
+        freeman.put( id, hdr.getAvailableSize() );
+    }
+
+    /**
+     *  Writes out data to a rowid. Assumes that any resizing has been
+     *  done.
+     */
+    private void write(Location rowid, byte[] data, int start, int length )
+        throws IOException
+    {
+        PageCursor curs = new PageCursor( pageman, rowid.getBlock() );
+        BlockIo block = file.get( curs.getCurrent() );
+        RecordHeader hdr = new RecordHeader( block, rowid.getOffset() );
+        hdr.setCurrentSize( length );
+        if ( length == 0 ) {
+            file.release( curs.getCurrent(), true );
+            return;
+        }
+
+        // copy bytes in
+        int offsetInBuffer = start;
+        int leftToWrite = length;
+        short dataOffset = (short) (rowid.getOffset() + RecordHeader.SIZE);
+        while ( leftToWrite > 0 ) {
+            // copy current page's data to return buffer
+            int toCopy = RecordFile.BLOCK_SIZE - dataOffset;
+
+            if ( leftToWrite < toCopy ) {
+                toCopy = leftToWrite;
+            }
+            System.arraycopy( data, offsetInBuffer, block.getData(), 
+                              dataOffset, toCopy );
+
+            // Go to the next block
+            leftToWrite -= toCopy;
+            offsetInBuffer += toCopy;
+
+            file.release( curs.getCurrent(), true );
+
+            if ( leftToWrite > 0 ) {
+                block = file.get( curs.next() );
+                dataOffset = DataPage.O_DATA;
+            }
+        }
+    }
+}
+

Added: directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Provider.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Provider.java?rev=652410&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Provider.java (added)
+++ directory/apacheds/branches/bigbang/apacheds-jdbm/src/main/java/jdbm/recman/Provider.java Wed Apr 30 17:06:41 2008
@@ -0,0 +1,116 @@
+/**
+ * JDBM LICENSE v1.00
+ *
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 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 name "JDBM" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of Cees de Groot.  For written permission,
+ *    please contact cg@cdegroot.com.
+ *
+ * 4. Products derived from this Software may not be called "JDBM"
+ *    nor may "JDBM" appear in their names without prior written
+ *    permission of Cees de Groot.
+ *
+ * 5. Due credit should be given to the JDBM Project
+ *    (http://jdbm.sourceforge.net/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
+ * ``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
+ * CEES DE GROOT OR ANY 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.
+ *
+ * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
+ * Copyright 2000-2001 (C) Alex Boisvert. All Rights Reserved.
+ * Contributions are Copyright (C) 2000 by their associated contributors.
+ *
+ * $Id: Provider.java,v 1.3 2005/06/25 23:12:32 doomdark Exp $
+ */
+
+package jdbm.recman;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import jdbm.RecordManager;
+import jdbm.RecordManagerOptions;
+import jdbm.RecordManagerProvider;
+
+import jdbm.helper.MRU;
+
+/**
+ * Provider of the default RecordManager implementation.
+ *
+ * @author <a href="mailto:boisvert@intalio.com">Alex Boisvert</a>
+ * @version $Id: Provider.java,v 1.3 2005/06/25 23:12:32 doomdark Exp $
+ */
+public final class Provider
+    implements RecordManagerProvider
+{
+
+    /**
+     * Create a default implementation record manager.
+     *
+     * @param name Name of the record file.
+     * @param options Record manager options.
+     * @throws IOException if an I/O related exception occurs while creating
+     *                    or opening the record manager.
+     * @throws UnsupportedOperationException if some options are not supported by the
+     *                                      implementation.
+     * @throws IllegalArgumentException if some options are invalid.
+     */
+    public RecordManager createRecordManager( String name,
+                                              Properties options )
+        throws IOException
+    {
+        RecordManager  recman;
+        String         value;
+        int            cacheSize;
+
+        recman = new BaseRecordManager( name );
+
+        value = options.getProperty( RecordManagerOptions.DISABLE_TRANSACTIONS, "false" );
+        if ( value.equalsIgnoreCase( "TRUE" ) ) {
+            ( (BaseRecordManager) recman ).disableTransactions();
+        }
+
+        value = options.getProperty( RecordManagerOptions.CACHE_SIZE, "1000" );
+        cacheSize = Integer.parseInt( value );
+
+        value = options.getProperty( RecordManagerOptions.CACHE_TYPE,
+                                     RecordManagerOptions.NORMAL_CACHE );
+        if ( value.equalsIgnoreCase( RecordManagerOptions.NORMAL_CACHE ) ) {
+            MRU cache = new MRU( cacheSize );
+            recman = new CacheRecordManager( recman, cache );
+        } else if ( value.equalsIgnoreCase( RecordManagerOptions.SOFT_REF_CACHE ) ) {
+            throw new IllegalArgumentException( "Soft reference cache not implemented" );
+        } else if ( value.equalsIgnoreCase( RecordManagerOptions.WEAK_REF_CACHE ) ) {
+            throw new IllegalArgumentException( "Weak reference cache not implemented" );
+        } else {
+            throw new IllegalArgumentException( "Invalid cache type: " + value );
+        }
+
+        return recman;
+    }
+
+
+}



Mime
View raw message