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

📄 dxdiskhashmap.java

📁 用Java写的面相对象的数据库管理系统
💻 JAVA
字号:
// You can redistribute this software and/or modify it under the terms of// the Ozone Library License version 1 published by ozone-db.org.//// The original code and portions created by SMB are// Copyright (C) 1997-2000 by SMB GmbH. All rights reserved.//// $Id: DxDiskHashMap.java,v 1.16 2000/11/10 17:03:17 daniela Exp $package org.ozoneDB.DxLib;import java.io.*;/** * @author <a href="http://www.softwarebuero.de/">SMB</a> * @version $Revision: 1.16 $Date: 2000/11/10 17:03:17 $ */public class DxDiskHashMap extends DxAbstractMap {        final static long serialVersionUID = 2;        public final static String ROOT_TABLE_NAME = ".rootTable";        private String baseFileName;    private long subTableNameCount = System.currentTimeMillis();    private DxDiskSubTable rootTable;    private int itemCount = 0;        // cache related stuff    private int cacheBits = 10;    private int cacheMask;    private DxKeyData[] cache;        // buffer related stuff    protected int maxBufferSize = 10;    protected DxSet buffer = new DxHashSet();        public int bufferAccesses;    public int bufferHits;    public int cacheAccesses;    public int cacheHits;        public int tableBitSize = 8;            public DxDiskHashMap( String _baseFileName, int _maxBufferSize, int _cacheBits, int _tableBitSize ) {        baseFileName = _baseFileName;        maxBufferSize = _maxBufferSize;        tableBitSize = _tableBitSize;                cacheBits = _cacheBits;        cacheMask = ((int)Math.pow( 2, cacheBits ) - 1);        cache = new DxKeyData[(int)Math.pow( 2, cacheBits )];                rootTable = new DxDiskSubTable( this, 0, tableBitSize );        buffer.add( rootTable );    }            public DxDiskHashNodeLeaf newNodeLeaf() {        return new DxDiskHashNodeLeaf( this );    }             public DxDiskHashNodeBranch newNodeBranch() {        return new DxDiskHashNodeBranch();    }             public DxKeyData newKeyData() {        return new DxKeyData();    }             public boolean isDirtyTable( DxDiskSubTable table ) {        // in general we don't know if and when the data objects stored in        // this table has been changed since last write, so we have to assume        // it is always dirty        return true;    }            /**     * Reuse an existing table from disk. To do so a previously created table     * has to be correctly closed. Once a hash map has been re-used it has to     * closed before opening again.     */    public synchronized void re_use() throws Exception {        File f = new File( baseFileName + ROOT_TABLE_NAME );        ObjectInputStream in = new ObjectInputStream( new BufferedInputStream( new FileInputStream( f ) ) );        try {            itemCount = in.readInt();            rootTable.readExternal( in );            rootTable.grandParent = this;        }         finally {            in.close();        }    }             /**     * Close this hash map. Write all changed tables to the disk. Store also     * all information that are needed to re-initialize this object from the     * disk data.     */    public synchronized void close() throws Exception {        writeAllTables();        setReusable( true );    }     public void setReusable( boolean flag ) throws Exception {        File f = new File( baseFileName + ROOT_TABLE_NAME );                if (flag) {            ObjectOutputStream out = new ObjectOutputStream( new BufferedOutputStream( new FileOutputStream( f ) ) );            try {                out.writeInt( itemCount );                rootTable.writeExternal( out );            }             finally {                out.close();            }        }         else {            if (f.exists() && !f.delete()) {                throw new IOException( "Unable to delete file." );            }        }        }     public Object clone() {        throw new RuntimeException( getClass().getName() + ".clone() is not implemented yet." );    }             private final Object cachedElementForKey( Object key, int hashCode ) {        cacheAccesses++;        if (cacheMask == 0) {            return null;        }                 int cacheIndex = hashCode & cacheMask;        DxKeyData entry = cache[cacheIndex];        if (entry != null && (entry.key == key || entry.key.equals( key ))) {            // System.out.print (".");            cacheHits ++;            return entry.data;        } else {            return null;        }     }             private final void addElementToCache( Object obj, Object key, int hashCode ) {        if (cacheMask == 0) {            return;        }                 synchronized (cache) {            int cacheIndex = hashCode & cacheMask;            DxKeyData entry = cache[cacheIndex];            if (entry != null) {                entry.set( key, obj );            } else {                entry = newKeyData();                entry.set( key, obj );                cache[cacheIndex] = entry;            }        }    }             private final void removeElementFromCache( Object key ) {        if (cacheMask == 0) {            return;        }                 synchronized (cache) {            int cacheIndex = key.hashCode() & cacheMask;            cache[cacheIndex] = null;        }    }             public void printStatistics() {        System.out.println( "DxDiskHastable statistics:" );        System.out.println( "    sub-table accesses: " + bufferAccesses + "  hits: " + bufferHits + " loads: "                 + (bufferAccesses - bufferHits) );        System.out.println( "    cache accesses: " + cacheAccesses + "  hits: " + cacheHits );    }             /**     * Eine sub-tabelle will nachladen. Wenn der buffer voll ist,     * muss eine andere verworfen werden. Die "aelteste" table ist     * immer ein blatt, da die zeiten mmer beim rekursiven aufstieg     * gesetzt werden.     */    protected synchronized void readRequest( DxDiskSubTable subTable ) throws Exception {        if (buffer.count() > maxBufferSize) {            //die blatt-sub-tabelle mit der aeltesten zugriffszeit            //suchen            long time = Long.MAX_VALUE;            DxIterator it = buffer.iterator();            DxDiskSubTable table;            DxDiskSubTable bestMatch = null;            while ((table = (DxDiskSubTable)it.next()) != null) {                if (table.accessTime < time) {                    time = table.accessTime;                    bestMatch = table;                }             }             // System.out.println (" - " + time);                        //test ob noch sub-tabels da sind            //            for (int i=0; i<DxDiskSubTable.SIZE; i++) {            //                DxDiskHashNode node = bestMatch.table[i];            //                if (node != null) {            //                    if (node.element == null && node.subTable.table == null) {            //                        System.out.println ("Node is not a leaf!");            //                        break;            //                        }            //                    }            //                }                        //schreiben, leer-machen und aus buffer loeschen            if (isDirtyTable( bestMatch )) {                bestMatch.writeTable();            }            deleteRequest( bestMatch );        }        // subTable.touch();        buffer.add( subTable );    }             /**     * The specified sub-table was deleted from the tree. So we have     * to delete it from the table buffer too.     */    public synchronized void deleteRequest( DxDiskSubTable subTable ) {        subTable.empty();        buffer.remove( subTable );    }             public String newSubTableFileName() {        return baseFileName + "." + String.valueOf( subTableNameCount++ );    }             /**     * Delete all the files used by this hashtable.     */    public void cleanFiles() {        String baseName = new File( baseFileName ).getName();        File path = new File( new File( baseFileName ).getParent() );        String[] fileList = path.list();                for (int i = 0; i < fileList.length; i++) {            if (fileList[i].startsWith( baseName )) {                new File( path, fileList[i] ).delete();            }         }     }     public synchronized void writeAllTables() throws Exception {        DxIterator it = buffer.iterator();        DxDiskSubTable table = null;        while ((table = (DxDiskSubTable)it.next()) != null) {            table.writeTable();        }     }         public synchronized boolean addForKey( Object obj, Object key ) {        try {            if (rootTable.addForKey( obj, key )) {                itemCount++;                addElementToCache( obj, key, key.hashCode() );                return true;            } else {                return false;            }         } catch (Exception e) {            e.printStackTrace();            throw new RuntimeException( e.toString() );        }     }             /**     * Gives the element for the specified key.<p>     *      *      * Note: This method is synchronized because the cache of subtables may     * change.     */    public synchronized Object elementForKey( Object key ) {        try {            int hashCode = key.hashCode();            Object cacheEntry = cachedElementForKey( key, hashCode );            if (cacheEntry != null) {                return cacheEntry;            } else {                Object answer = rootTable.elementForKey( key, hashCode );                addElementToCache( answer, key, hashCode );                return answer;            }         } catch (Exception e) {            e.printStackTrace();            throw new RuntimeException( e.toString() );        }     }             protected synchronized void elementDone( DxDiskHashCompatible obj ) {        rootTable.elementDone( obj );    }             public Object keyForElement( Object obj ) {        throw new RuntimeException( "keyForElement() not implemented." );    }             public synchronized boolean remove( Object obj ) {        throw new RuntimeException( "remove() not implemented." );    }             public synchronized Object removeForKey( Object key ) {        try {            Object obj = rootTable.removeForKey( key );            if (obj != null) {                itemCount--;                removeElementFromCache( key );            }             return obj;        } catch (Exception e) {            e.printStackTrace();            throw new RuntimeException( e.toString() );        }     }             public DxIterator iterator() {        throw new RuntimeException( "iterator() not implemented." );    // return new DxDIterator (this);    }             public int count() {        return itemCount;    }             public boolean isEmpty() {        return itemCount == 0;    }             public boolean containsKey( Object key ) {        return elementForKey( key ) != null;    }             public synchronized void clear() {        throw new RuntimeException( getClass().getName() + ".clear() is not implemented yet." );    }     }

⌨️ 快捷键说明

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