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

📄 abstractreferencemap.java

📁 iBATIS似乎已远离众说纷纭的OR框架之列
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

    //-----------------------------------------------------------------------
    /**
     * Purges stale mappings from this map before read operations.
     * <p>
     * This implementation calls {@link #purge()} to maintain a consistent state.
     */
    protected void purgeBeforeRead() {
        purge();
    }

    /**
     * Purges stale mappings from this map before write operations.
     * <p>
     * This implementation calls {@link #purge()} to maintain a consistent state.
     */
    protected void purgeBeforeWrite() {
        purge();
    }

    /**
     * Purges stale mappings from this map.
     * <p>
     * Note that this method is not synchronized!  Special
     * care must be taken if, for instance, you want stale
     * mappings to be removed on a periodic basis by some
     * background thread.
     */
    protected void purge() {
        Reference ref = queue.poll();
        while (ref != null) {
            purge(ref);
            ref = queue.poll();
        }
    }

    /**
     * Purges the specified reference.
     * 
     * @param ref  the reference to purge
     */
    protected void purge(Reference ref) {
        // The hashCode of the reference is the hashCode of the
        // mapping key, even if the reference refers to the 
        // mapping value...
        int hash = ref.hashCode();
        int index = hashIndex(hash, data.length);
        HashEntry previous = null;
        HashEntry entry = data[index];
        while (entry != null) {
            if (((ReferenceEntry) entry).purge(ref)) {
                if (previous == null) {
                    data[index] = entry.next;
                } else {
                    previous.next = entry.next;
                }
                this.size--;
                return;
            }
            previous = entry;
            entry = entry.next;
        }

    }

    //-----------------------------------------------------------------------
    /**
     * Gets the entry mapped to the key specified.
     * 
     * @param key  the key
     * @return the entry, null if no match
     */
    protected HashEntry getEntry(Object key) {
        if (key == null) {
            return null;
        } else {
            return super.getEntry(key);
        }
    }

    /**
     * Gets the hash code for a MapEntry.
     * Subclasses can override this, for example to use the identityHashCode.
     * 
     * @param key  the key to get a hash code for, may be null
     * @param value  the value to get a hash code for, may be null
     * @return the hash code, as per the MapEntry specification
     */
    protected int hashEntry(Object key, Object value) {
        return (key == null ? 0 : key.hashCode()) ^
               (value == null ? 0 : value.hashCode()); 
    }
    
    /**
     * Compares two keys, in internal converted form, to see if they are equal.
     * <p>
     * This implementation converts the key from the entry to a real reference
     * before comparison.
     * 
     * @param key1  the first key to compare passed in from outside
     * @param key2  the second key extracted from the entry via <code>entry.key</code>
     * @return true if equal
     */
    protected boolean isEqualKey(Object key1, Object key2) {
        key2 = (keyType > HARD ? ((Reference) key2).get() : key2);
        return (key1 == key2 || key1.equals(key2));
    }
    
    /**
     * Creates a ReferenceEntry instead of a HashEntry.
     * 
     * @param next  the next entry in sequence
     * @param hashCode  the hash code to use
     * @param key  the key to store
     * @param value  the value to store
     * @return the newly created entry
     */
    protected HashEntry createEntry(HashEntry next, int hashCode, Object key, Object value) {
        return new ReferenceEntry(this, next, hashCode, key, value);
    }

    /**
     * Creates an entry set iterator.
     * 
     * @return the entrySet iterator
     */
    protected Iterator createEntrySetIterator() {
        return new ReferenceEntrySetIterator(this);
    }

    /**
     * Creates an key set iterator.
     * 
     * @return the keySet iterator
     */
    protected Iterator createKeySetIterator() {
        return new ReferenceKeySetIterator(this);
    }

    /**
     * Creates an values iterator.
     * 
     * @return the values iterator
     */
    protected Iterator createValuesIterator() {
        return new ReferenceValuesIterator(this);
    }

    //-----------------------------------------------------------------------
    /**
     * EntrySet implementation.
     */
    static class ReferenceEntrySet extends EntrySet {
        
        protected ReferenceEntrySet(AbstractHashedMap parent) {
            super(parent);
        }

        public Object[] toArray() {
            return toArray(new Object[0]);
        }

        public Object[] toArray(Object[] arr) {
            // special implementation to handle disappearing entries
            ArrayList list = new ArrayList();
            Iterator iterator = iterator();
            while (iterator.hasNext()) {
                Entry e = (Entry) iterator.next();
                list.add(new DefaultMapEntry(e.getKey(), e.getValue()));
            }
            return list.toArray(arr);
        }
    }

    //-----------------------------------------------------------------------
    /**
     * KeySet implementation.
     */
    static class ReferenceKeySet extends KeySet {
        
        protected ReferenceKeySet(AbstractHashedMap parent) {
            super(parent);
        }

        public Object[] toArray() {
            return toArray(new Object[0]);
        }

        public Object[] toArray(Object[] arr) {
            // special implementation to handle disappearing keys
            List list = new ArrayList(parent.size());
            for (Iterator it = iterator(); it.hasNext(); ) {
                list.add(it.next());
            }
            return list.toArray(arr);
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Values implementation.
     */
    static class ReferenceValues extends Values {
        
        protected ReferenceValues(AbstractHashedMap parent) {
            super(parent);
        }

        public Object[] toArray() {
            return toArray(new Object[0]);
        }

        public Object[] toArray(Object[] arr) {
            // special implementation to handle disappearing values
            List list = new ArrayList(parent.size());
            for (Iterator it = iterator(); it.hasNext(); ) {
                list.add(it.next());
            }
            return list.toArray(arr);
        }
    }

    //-----------------------------------------------------------------------
    /**
     * A MapEntry implementation for the map.
     * <p>
     * If getKey() or getValue() returns null, it means
     * the mapping is stale and should be removed.
     * 
     * @since Commons Collections 3.1
     */
    protected static class ReferenceEntry extends HashEntry {
        /** The parent map */
        protected final AbstractReferenceMap parent;

        /**
         * Creates a new entry object for the ReferenceMap.
         * 
         * @param parent  the parent map
         * @param next  the next entry in the hash bucket
         * @param hashCode  the hash code of the key
         * @param key  the key
         * @param value  the value
         */
        public ReferenceEntry(AbstractReferenceMap parent, HashEntry next, int hashCode, Object key, Object value) {
            super(next, hashCode, null, null);
            this.parent = parent;
            this.key = toReference(parent.keyType, key, hashCode);
            this.value = toReference(parent.valueType, value, hashCode); // the key hashCode is passed in deliberately
        }

        /**
         * Gets the key from the entry.
         * This method dereferences weak and soft keys and thus may return null.
         * 
         * @return the key, which may be null if it was garbage collected
         */
        public Object getKey() {
            return (parent.keyType > HARD) ? ((Reference) key).get() : key;
        }

        /**
         * Gets the value from the entry.
         * This method dereferences weak and soft value and thus may return null.
         * 
         * @return the value, which may be null if it was garbage collected
         */
        public Object getValue() {
            return (parent.valueType > HARD) ? ((Reference) value).get() : value;
        }

        /**
         * Sets the value of the entry.
         * 
         * @param obj  the object to store
         * @return the previous value
         */
        public Object setValue(Object obj) {
            Object old = getValue();
            if (parent.valueType > HARD) {
                ((Reference)value).clear();
            }
            value = toReference(parent.valueType, obj, hashCode);
            return old;
        }

        /**
         * Compares this map entry to another.
         * <p>
         * This implementation uses <code>isEqualKey</code> and
         * <code>isEqualValue</code> on the main map for comparison.
         * 
         * @param obj  the other map entry to compare to
         * @return true if equal, false if not
         */
        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            }
            if (obj instanceof Map.Entry == false) {
                return false;
            }
            
            Map.Entry entry = (Map.Entry)obj;
            Object entryKey = entry.getKey();  // convert to hard reference
            Object entryValue = entry.getValue();  // convert to hard reference
            if ((entryKey == null) || (entryValue == null)) {
                return false;
            }
            // compare using map methods, aiding identity subclass
            // note that key is direct access and value is via method
            return parent.isEqualKey(entryKey, key) &&
                   parent.isEqualValue(entryValue, getValue());
        }

        /**
         * Gets the hashcode of the entry using temporary hard references.
         * <p>
         * This implementation uses <code>hashEntry</code> on the main map.
         * 
         * @return the hashcode of the entry
         */
        public int hashCode() {
            return parent.hashEntry(getKey(), getValue());
        }

        /**
         * Constructs a reference of the given type to the given referent.

⌨️ 快捷键说明

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