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

📄 hashdirectory.java

📁 Java Crawler with domain knowledge path
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                    }

                    // (finally!) insert new element
                    return dir.put( key, value );
                }
            }
        }
    }


    /**
     * Remove the value which is associated with the given key.  If the
     * key does not exist, this method simply ignores the operation.
     *
     * @param key key whose associated value is to be removed
     * @return object which was associated with the given key, or
     *          <code>null</code> if no association existed with given key.
     */
    Object remove(Object key) throws IOException {
        int hash = hashCode(key);
        long child_recid = _children[hash];
        if (child_recid == 0) {
            // not bucket/page --> not found
            return null;
        } else {
            HashNode node = (HashNode) _recman.fetch( child_recid );
            // System.out.println("HashDirectory.remove() child is : "+node);

            if (node instanceof HashDirectory) {
                // recurse into next directory level
                HashDirectory dir = (HashDirectory)node;
                dir.setPersistenceContext( _recman, child_recid );
                Object existing = dir.remove(key);
                if (existing != null) {
                    if (dir.isEmpty()) {
                        // delete empty directory
                        _recman.delete(child_recid);
                        _children[hash] = 0;
                        _recman.update(_recid, this);
                    }
                }
                return existing;
            } else {
                // node is a bucket
                HashBucket bucket = (HashBucket)node;
                Object existing = bucket.removeElement(key);
                if (existing != null) {
                    if (bucket.getElementCount() >= 1) {
                        _recman.update(child_recid, bucket);
                    } else {
                        // delete bucket, it's empty
                        _recman.delete(child_recid);
                        _children[hash] = 0;
                        _recman.update(_recid, this);
                    }
                }
                return existing;
            }
        }
    }

    /**
     * Calculates the hashcode of a key, based on the current directory
     * depth.
     */
    private int hashCode(Object key) {
        int hashMask = hashMask();
        int hash = key.hashCode();
        hash = hash & hashMask;
        hash = hash >>> ((MAX_DEPTH - _depth) * BIT_SIZE);
        hash = hash % MAX_CHILDREN;
        /*
        System.out.println("HashDirectory.hashCode() is: 0x"
                           +Integer.toHexString(hash)
                           +" for object hashCode() 0x"
                           +Integer.toHexString(key.hashCode()));
        */
        return hash;
    }

    /**
     * Calculates the hashmask of this directory.  The hashmask is the
     * bit mask applied to a hashcode to retain only bits that are
     * relevant to this directory level.
     */
    int hashMask() {
        int bits = MAX_CHILDREN-1;
        int hashMask = bits << ((MAX_DEPTH - _depth) * BIT_SIZE);
        /*
        System.out.println("HashDirectory.hashMask() is: 0x"
                           +Integer.toHexString(hashMask));
        */
        return hashMask;
    }

    /**
     * Returns an enumeration of the keys contained in this
     */
    FastIterator keys()
        throws IOException
    {
        return new HDIterator( true );
    }

    /**
     * Returns an enumeration of the values contained in this
     */
    FastIterator values()
        throws IOException
    {
        return new HDIterator( false );
    }


    /**
     * Implement Externalizable interface
     */
    public void writeExternal(ObjectOutput out)
    throws IOException {
        out.writeByte(_depth);
        out.writeObject(_children);
    }


    /**
     * Implement Externalizable interface
     */
    public synchronized void readExternal(ObjectInput in)
    throws IOException, ClassNotFoundException {
        _depth = in.readByte();
        _children = (long[])in.readObject();
    }


    ////////////////////////////////////////////////////////////////////////
    // INNER CLASS
    ////////////////////////////////////////////////////////////////////////

    /**
     * Utility class to enumerate keys/values in a HTree
     */
    public class HDIterator
        extends FastIterator
    {

        /**
         * True if we're iterating on keys, False if enumerating on values.
         */
        private boolean _iterateKeys;

        /**
         * Stacks of directories & last enumerated child position
         */
        private ArrayList _dirStack;
        private ArrayList _childStack;

        /**
         * Current HashDirectory in the hierarchy
         */
        private HashDirectory _dir;

        /**
         * Current child position
         */
        private int _child;

        /**
         * Current bucket iterator
         */
        private Iterator _iter;


        /**
         * Construct an iterator on this directory.
         *
         * @param iterateKeys True if iteration supplies keys, False
         *                  if iterateKeys supplies values.
         */
        HDIterator( boolean iterateKeys )
            throws IOException
        {
            _dirStack = new ArrayList();
            _childStack = new ArrayList();
            _dir = HashDirectory.this;
            _child = -1;
            _iterateKeys = iterateKeys;

            prepareNext();
        }


        /**
         * Returns the next object.
         */
        public Object next()
        {   
            Object next = null;      
            if( _iter != null && _iter.hasNext() ) {
              next = _iter.next();
            } else {
              try {
                prepareNext();
              } catch ( IOException except ) {
                throw new IterationException( except );
              }
              if ( _iter != null && _iter.hasNext() ) {
                return next();
              }
            }
            return next;         
        }


        /**
         * Prepare internal state so we can answer <code>hasMoreElements</code>
         *
         * Actually, this code prepares an Enumeration on the next
         * Bucket to enumerate.   If no following bucket is found,
         * the next Enumeration is set to <code>null</code>.
         */
        private void prepareNext() throws IOException {
            long child_recid = 0;

            // find next bucket/directory to enumerate
            do {
                _child++;
                if (_child >= MAX_CHILDREN) {

                    if (_dirStack.isEmpty()) {
                        // no more directory in the stack, we're finished
                        return;
                    }

                    // try next page
                    _dir = (HashDirectory) _dirStack.remove( _dirStack.size()-1 );
                    _child = ( (Integer) _childStack.remove( _childStack.size()-1 ) ).intValue();
                    continue;
                }
                child_recid = _dir._children[_child];
            } while (child_recid == 0);

            if (child_recid == 0) {
                throw new Error("child_recid cannot be 0");
            }

            HashNode node = (HashNode) _recman.fetch( child_recid );
            // System.out.println("HDEnumeration.get() child is : "+node);
 
            if ( node instanceof HashDirectory ) {
                // save current position
                _dirStack.add( _dir );
                _childStack.add( new Integer( _child ) );

                _dir = (HashDirectory)node;
                _child = -1;

                // recurse into
                _dir.setPersistenceContext( _recman, child_recid );
                prepareNext();
            } else {
                // node is a bucket
                HashBucket bucket = (HashBucket)node;
                if ( _iterateKeys ) {
                    _iter = bucket.getKeys().iterator();
                } else {
                    _iter = bucket.getValues().iterator();
                }
            }
        }
    }

}

⌨️ 快捷键说明

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