001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.memory;
018    
019    /**
020     * Maintains a simple linked list of CacheEntry objects. It is thread safe.
021     * 
022     * 
023     */
024    public class CacheEntryList {
025    
026        // Points at the tail of the CacheEntry list
027        public final CacheEntry tail = new CacheEntry(null, null);
028    
029        public CacheEntryList() {
030            tail.next = tail;
031            tail.previous = tail;
032        }
033    
034        public void add(CacheEntry ce) {
035            addEntryBefore(tail, ce);
036        }
037    
038        private void addEntryBefore(CacheEntry position, CacheEntry ce) {
039            assert ce.key != null && ce.next == null && ce.owner == null;
040    
041            synchronized (tail) {
042                ce.owner = this;
043                ce.next = position;
044                ce.previous = position.previous;
045                ce.previous.next = ce;
046                ce.next.previous = ce;
047            }
048        }
049    
050        public void clear() {
051            synchronized (tail) {
052                tail.next = tail;
053                tail.previous = tail;
054            }
055        }
056    
057        public CacheEvictor createFIFOCacheEvictor() {
058            return new CacheEvictor() {
059                public CacheEntry evictCacheEntry() {
060                    CacheEntry rc;
061                    synchronized (tail) {
062                        rc = tail.next;
063                    }
064                    return rc.remove() ? rc : null;
065                }
066            };
067        }
068    
069        public CacheEvictor createLIFOCacheEvictor() {
070            return new CacheEvictor() {
071                public CacheEntry evictCacheEntry() {
072                    CacheEntry rc;
073                    synchronized (tail) {
074                        rc = tail.previous;
075                    }
076                    return rc.remove() ? rc : null;
077                }
078            };
079        }
080    
081    }