📄 dxdisksubtable.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: DxDiskSubTable.java,v 1.16 2000/11/10 17:03:17 daniela Exp $package org.ozoneDB.DxLib;import java.io.*;import java.util.zip.*;public final class DxDiskSubTable implements Externalizable { final static long serialVersionUID = 2; public static int timeCount = (int)System.currentTimeMillis(); private int size; private int bitSize; private int maxDepth; protected String fileName; protected int depth; protected int hashMask; protected DxDiskHashMap grandParent; protected DxDiskHashNode[] table; protected long accessTime = timeCount++; protected boolean dirty; protected int subTableCount = 0; /** * All the items (including subTables) in the local list. */ protected int itemCount = 0; public DxDiskSubTable() { } public DxDiskSubTable( DxDiskHashMap _grandParent, int _depth, int _bitSize ) { bitSize = Math.min( _bitSize, 32 - _depth * _bitSize ); size = (int)Math.pow( 2, bitSize ); depth = _depth; maxDepth = (32 / _bitSize - (32 % bitSize > 0 ? 0 : 1)); // System.out.println ("DxDiskSubTable: bitSize=" + bitSize + ", size=" + size + ", depth:" + depth + ", maxDepth:" + maxDepth); int bitNum = (maxDepth - depth) * bitSize; int bitMask = (int)Math.pow( 2, bitNum ); hashMask = 0; for (int i = 0; i < bitSize; i++) { hashMask = hashMask | bitMask; bitMask *= 2; } // hashMask = ((int)0xff) << ((maxDepth - depth) * bitSize); // System.out.println ("DxDiskSubTable: hashMask: " + hashMask); // System.out.print ("DxDiskSubTable: hashMask: "); // for (int i=31; i>=0; i--) // System.out.print ((hashMask & (int)Math.pow(2, i)) > 0 ? "1" : "0"); // System.out.println (""); table = new DxDiskHashNode[size]; grandParent = _grandParent; fileName = grandParent.newSubTableFileName(); } public String filename() { return fileName; } public DxDiskHashNode[] table() { return table; } public void empty() { table = null; } public int count() { return itemCount; } public void deleteFile() { // System.out.println ("deleteFile()..."); File file = new File( fileName ); if (file.exists()) { file.delete(); } } public int hashKey( int key ) { // return (key & hashMask) >> (depth * bitSize); return (key & hashMask) >> (maxDepth - depth) * bitSize; } protected void fetchTable() throws Exception { grandParent.bufferAccesses++; if (table == null) { grandParent.readRequest( this ); readTable(); } else { grandParent.bufferHits++; } } protected synchronized void touch() { accessTime = timeCount++; } public boolean isLeaf() { return subTableCount == 0; } public boolean isDirty() { return dirty; } public synchronized boolean addForKey( Object obj, Object key ) throws Exception { fetchTable(); boolean answer = true; int localKey = hashKey( key.hashCode() ); DxDiskHashNode node = table[localKey]; if (node != null) { //node ist ein blatt if (node instanceof DxDiskHashNodeLeaf) { DxDiskHashNodeLeaf oldNode = (DxDiskHashNodeLeaf)node; if (depth < maxDepth) { DxDiskHashNodeBranch newNode = grandParent.newNodeBranch(); newNode.subTable = new DxDiskSubTable( grandParent, depth + 1, grandParent.tableBitSize ); //im alten node kann nur ein element stehen newNode.subTable.addForKey( oldNode.element.data, oldNode.element.key ); answer = newNode.subTable.addForKey( obj, key ); if (answer) { grandParent.readRequest( newNode.subTable ); table[localKey] = newNode; subTableCount++; } else { table[localKey] = oldNode; } } else { //maximale tiefe ist erreicht answer = oldNode.addForKey( obj, key ); } } else { //node ist ein branch ((DxDiskHashNodeBranch)node).subTable.addForKey( obj, key ); } } else { //node existiert noch nicht DxDiskHashNodeLeaf newNode = grandParent.newNodeLeaf(); newNode.addForKey( obj, key ); table[localKey] = newNode; itemCount++; } //muss ganz unten stehen, damit abraeumen korrekt ist touch(); dirty = true; return answer; } public final Object elementForKey( Object key, int hashCode ) throws Exception { fetchTable(); int localKey = hashKey( hashCode ); Object answer = null; DxDiskHashNode node = table[localKey]; if (node != null) { if (node instanceof DxDiskHashNodeLeaf) { answer = ((DxDiskHashNodeLeaf)node).elementForKey( key, hashCode ); } else { answer = ((DxDiskHashNodeBranch)node).subTable.elementForKey( key, hashCode ); } } //muss ganz unten stehen, damit anraeumen korrekt ist touch(); return answer; } protected synchronized void elementDone( DxDiskHashCompatible obj ) { } public synchronized Object removeForKey( Object key ) throws Exception { fetchTable(); Object answer = null; int localKey = hashKey( key.hashCode() ); DxDiskHashNode node = table[localKey]; if (node != null) { if (node instanceof DxDiskHashNodeLeaf) { answer = ((DxDiskHashNodeLeaf)node).removeForKey( key ); if (((DxDiskHashNodeLeaf)node).element == null) { table[localKey] = null; itemCount--; } } else { DxDiskHashNodeBranch oldNode = (DxDiskHashNodeBranch)node; answer = oldNode.subTable.removeForKey( key ); if (oldNode.subTable.itemCount == 0) { grandParent.deleteRequest( oldNode.subTable ); oldNode.subTable.deleteFile(); table[localKey] = null; itemCount--; subTableCount--; } } } // System.out.println ("remove: key: " + key + " - depth: " + depth + " - count: " + itemCount); //muss ganz unten stehen, damit anraeumen korrekt ist touch(); dirty = true; return answer; } /** * Schreibt nur die representation in einem HashNode aber * nicht die tabelle selber. */ public void writeExternal( ObjectOutput out ) throws IOException { out.writeUTF( fileName ); out.writeInt( bitSize ); out.writeInt( size ); out.writeInt( maxDepth ); out.writeInt( depth ); out.writeInt( hashMask ); out.writeInt( subTableCount ); out.writeInt( itemCount ); } public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException { fileName = in.readUTF(); bitSize = in.readInt(); size = in.readInt(); maxDepth = in.readInt(); depth = in.readInt(); hashMask = in.readInt(); subTableCount = in.readInt(); itemCount = in.readInt(); // force tabel to be read on next access if (itemCount > 0) { table = null; } accessTime = 0; dirty = false; } /** * Schreibt den inhalt der ganzen tabelle aber nicht die * sub-tabellen. Der name wird aus dem baseFileName und */ public void writeTable() throws IOException { // System.out.println ("schreiben: " + fileName); // ObjectOutputStream out = new ObjectOutputStream (new BufferedOutputStream (new FileOutputStream (fileName), 4*1024)); OutputStream out = new FileOutputStream( fileName ); out = new GZIPOutputStream( out ); out = new BufferedOutputStream( out, 4096 ); ObjectOutputStream oout = new ObjectOutputStream( out ); try { synchronized (table) { oout.writeInt( itemCount ); for (int i = 0; i < size; i++) { if (table[i] != null) { oout.writeShort( i ); oout.writeByte( table[i] instanceof DxDiskHashNodeLeaf ? 1 : 2 ); table[i].writeExternal( oout ); } } } dirty = false; } finally { oout.close(); } } public synchronized void readTable() throws IOException, ClassNotFoundException { // System.out.println ("lesen: " + fileName); table = new DxDiskHashNode[size]; // ObjectInputStream in = new ObjectInputStream (new BufferedInputStream (new FileInputStream (fileName), 4*1024)); InputStream in = new FileInputStream( fileName ); in = new GZIPInputStream( in ); in = new BufferedInputStream( in, 4096 ); ObjectInputStream oin = new ObjectInputStream( in ); try { int count = oin.readInt(); for (int i = 0; i < count; i++) { short index = oin.readShort(); byte nodeType = oin.readByte(); if (nodeType == 1) { table[index] = grandParent.newNodeLeaf(); } else { table[index] = grandParent.newNodeBranch(); } table[index].readExternal( oin ); if (nodeType == 2) { ((DxDiskHashNodeBranch)table[index]).subTable.grandParent = grandParent; } } touch(); dirty = false; } finally { oin.close(); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -