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