cachinghierarchymanager.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 841 行 · 第 1/2 页

JAVA
841
字号
    /**     * {@inheritDoc}     */    public void nodeRemoved(NodeState state, QName name, int index, NodeId id) {        // Optimization: ignore notifications for nodes that are not in the cache        synchronized (cacheMonitor) {            if (idCache.containsKey(state.getNodeId())) {                try {                    Path path = Path.create(getPath(state.getNodeId()), name, index, true);                    remove(path, id);                } catch (PathNotFoundException e) {                    log.warn("Unable to get path of node " + state.getNodeId()                            + ", event ignored.");                } catch (MalformedPathException e) {                    log.warn("Unable to create path of " + id, e);                } catch (ItemNotFoundException e) {                    log.warn("Unable to get path of " + state.getNodeId(), e);                } catch (RepositoryException e) {                    log.warn("Unable to get path of " + state.getNodeId(), e);                }            }        }    }    //------------------------------------------------------< private methods >    /**     * Return a cached element in the path map, given its id     *     * @param id node id     * @return cached element, <code>null</code> if not found     */    private PathMap.Element get(ItemId id) {        synchronized (cacheMonitor) {            LRUEntry entry = (LRUEntry) idCache.get(id);            if (entry != null) {                entry.touch();                return entry.getElement();            }            return null;        }    }    /**     * Return the nearest cached element in the path map, given a path.     * The returned element is guaranteed to have an associated object that     * is not <code>null</code>.     *     * @param path path     * @return cached element, <code>null</code> if not found     */    private PathMap.Element map(Path path) {        synchronized (cacheMonitor) {            PathMap.Element element = pathCache.map(path, false);            while (element != null) {                LRUEntry entry = (LRUEntry) element.get();                if (entry != null) {                    entry.touch();                    return element;                }                element = element.getParent();            }            return null;        }    }    /**     * Cache an item in the hierarchy given its id and path. Adds a listener     * for this item state to get notified about changes.     *     * @param state node state     * @param path  path to item     */    private void cache(NodeState state, Path path) {        NodeId id = state.getNodeId();        synchronized (cacheMonitor) {            if (idCache.get(id) != null) {                return;            }            if (idCache.size() >= upperLimit) {                /**                 * Remove least recently used item. Scans the LRU list from head to tail                 * and removes the first item that has no children.                 */                LRUEntry entry = head;                while (entry != null) {                    PathMap.Element element = entry.getElement();                    if (element.getChildrenCount() == 0) {                        evict(entry, true);                        return;                    }                    entry = entry.getNext();                }            }            PathMap.Element element = pathCache.put(path);            if (element.get() != null) {                if (!id.equals(((LRUEntry) element.get()).getId())) {                    log.warn("overwriting PathMap.Element");                }            }            LRUEntry entry = new LRUEntry(id, element);            element.set(entry);            idCache.put(id, entry);        }    }    /**     * Return a flag indicating whether a certain element is cached.     *     * @param id item id     * @return <code>true</code> if the item is already cached;     *         <code>false</code> otherwise     */    private boolean isCached(ItemId id) {        synchronized (cacheMonitor) {            return idCache.get(id) != null;        }    }    /**     * Remove item from cache. Removes the associated <code>LRUEntry</code>     * and the <code>PathMap.Element</code> with it. Indexes of same name     * sibling elements are shifted!     *     * @param id item id     */    private void remove(ItemId id) {        synchronized (cacheMonitor) {            LRUEntry entry = (LRUEntry) idCache.get(id);            if (entry != null) {                remove(entry, true);            }        }    }    /**     * Remove item from cache. Index of same name sibling items are shifted!     *     * @param entry               LRU entry     * @param removeFromPathCache whether to remove from path cache     */    private void remove(LRUEntry entry, boolean removeFromPathCache) {        // assert: synchronized (cacheMonitor)        if (removeFromPathCache) {            PathMap.Element element = entry.getElement();            remove(element);            element.remove();        } else {            idCache.remove(entry.getId());            entry.remove();        }    }    /**     * Evict item from cache. Index of same name sibling items are <b>not</b>     * shifted!     *     * @param entry               LRU entry     * @param removeFromPathCache whether to remove from path cache     */    private void evict(LRUEntry entry, boolean removeFromPathCache) {        // assert: synchronized (cacheMonitor)        if (removeFromPathCache) {            PathMap.Element element = entry.getElement();            element.traverse(new PathMap.ElementVisitor() {                public void elementVisited(PathMap.Element element) {                    evict((LRUEntry) element.get(), false);                }            }, false);            element.remove(false);        } else {            idCache.remove(entry.getId());            entry.remove();        }    }    /**     * Evict item from cache. Evicts the associated <code>LRUEntry</code>     * and the <code>PathMap.Element</code> with it. Indexes of same name     * sibling elements are <b>not</b> shifted!     *     * @param id item id     */    private void evict(ItemId id) {        synchronized (cacheMonitor) {            LRUEntry entry = (LRUEntry) idCache.get(id);            if (entry != null) {                evict(entry, true);            }        }    }    /**     * Remove path map element from cache. This will traverse all children     * of this element and remove the objects associated with them.     * Index of same name sibling items are shifted!     *     * @param element path map element     */    private void remove(PathMap.Element element) {        // assert: synchronized (cacheMonitor)        element.traverse(new PathMap.ElementVisitor() {            public void elementVisited(PathMap.Element element) {                remove((LRUEntry) element.get(), false);            }        }, false);    }    /**     * Insert a node into the cache. This will automatically shift     * all indexes of sibling nodes having index greater or equal.     *     * @param path child path     * @param id   node id     *     * @throws PathNotFoundException if the path was not found     */    private void insert(Path path, ItemId id) throws PathNotFoundException {        synchronized (cacheMonitor) {            PathMap.Element element = null;            LRUEntry entry = (LRUEntry) idCache.get(id);            if (entry != null) {                element = entry.getElement();                element.remove();            }            PathMap.Element parent = pathCache.map(path.getAncestor(1), true);            if (parent != null) {                parent.insert(path.getNameElement());            }            if (element != null) {                pathCache.put(path, element);                /* Remember this as a move */                movedIds.add(id);            }        }    }    /**     * Remove an item from the cache in order to shift the indexes     * of items following this item.     *     * @param path child path     * @param id   node id     *     * @throws PathNotFoundException if the path was not found     */    private void remove(Path path, ItemId id) throws PathNotFoundException {        synchronized (cacheMonitor) {            /* If we remembered this as a move, ignore this event */            if (movedIds.remove(id)) {                return;            }            PathMap.Element parent = pathCache.map(path.getAncestor(1), true);            if (parent != null) {                PathMap.Element element = parent.remove(path.getNameElement());                if (element != null) {                    remove(element);                }            }        }    }    /**     * Dump contents of path map and elements included to <code>PrintStream</code> given.     *     * @param ps print stream to dump to     */    public void dump(final PrintStream ps) {        pathCache.traverse(new PathMap.ElementVisitor() {            public void elementVisited(PathMap.Element element) {                StringBuffer line = new StringBuffer();                for (int i = 0; i < element.getDepth(); i++) {                    line.append("--");                }                line.append(element.getName());                int index = element.getIndex();                if (index != 0 && index != 1) {                    line.append('[');                    line.append(index);                    line.append(']');                }                line.append("  ");                line.append(element.get());                ps.println(line.toString());            }        }, true);    }    /**     * Entry in the LRU list     */    private class LRUEntry {        /**         * Previous entry         */        private LRUEntry previous;        /**         * Next entry         */        private LRUEntry next;        /**         * Node id         */        private final NodeId id;        /**         * Element in path map         */        private final PathMap.Element element;        /**         * Create a new instance of this class         *         * @param id node id         * @param element the path map element for this entry         */        public LRUEntry(NodeId id, PathMap.Element element) {            this.id = id;            this.element = element;            append();        }        /**         * Append entry to end of LRU list         */        public void append() {            if (tail == null) {                head = this;                tail = this;            } else {                previous = tail;                tail.next = this;                tail = this;            }        }        /**         * Remove entry from LRU list         */        public void remove() {            if (previous != null) {                previous.next = next;            }            if (next != null) {                next.previous = previous;            }            if (head == this) {                head = next;            }            if (tail == this) {                tail = previous;            }            previous = null;            next = null;        }        /**         * Touch entry. Removes it from its current position in the LRU list         * and moves it to the end.         */        public void touch() {            remove();            append();        }        /**         * Return previous LRU entry         *         * @return previous LRU entry         */        public LRUEntry getPrevious() {            return previous;        }        /**         * Return next LRU entry         *         * @return next LRU entry         */        public LRUEntry getNext() {            return next;        }        /**         * Return node ID         *         * @return node ID         */        public NodeId getId() {            return id;        }        /**         * Return element in path map         *         * @return element in path map         */        public PathMap.Element getElement() {            return element;        }        /**         * {@inheritDoc}         */        public String toString() {            return id.toString();        }    }}

⌨️ 快捷键说明

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