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.broker.region.cursors; 018 019 import java.util.ArrayList; 020 import java.util.HashMap; 021 import java.util.Iterator; 022 import java.util.List; 023 import java.util.Map; 024 import org.apache.activemq.broker.region.MessageReference; 025 import org.apache.activemq.command.MessageId; 026 027 public class OrderedPendingList implements PendingList { 028 PendingNode root = null; 029 PendingNode tail = null; 030 final Map<MessageId, PendingNode> map = new HashMap<MessageId, PendingNode>(); 031 032 public PendingNode addMessageFirst(MessageReference message) { 033 PendingNode node = new PendingNode(this, message); 034 if (root == null) { 035 root = node; 036 tail = node; 037 } else { 038 root.linkBefore(node); 039 } 040 this.map.put(message.getMessageId(), node); 041 return node; 042 } 043 044 public PendingNode addMessageLast(MessageReference message) { 045 PendingNode node = new PendingNode(this, message); 046 if (root == null) { 047 root = node; 048 } else { 049 tail.linkAfter(node); 050 } 051 tail = node; 052 this.map.put(message.getMessageId(), node); 053 return node; 054 } 055 056 public void clear() { 057 this.root = null; 058 this.tail = null; 059 this.map.clear(); 060 } 061 062 public boolean isEmpty() { 063 return this.map.isEmpty(); 064 } 065 066 public Iterator<MessageReference> iterator() { 067 return new Iterator<MessageReference>() { 068 private PendingNode current = null; 069 private PendingNode next = root; 070 071 public boolean hasNext() { 072 return next != null; 073 } 074 075 public MessageReference next() { 076 MessageReference result = null; 077 this.current = this.next; 078 result = this.current.getMessage(); 079 this.next = (PendingNode) this.next.getNext(); 080 return result; 081 } 082 083 public void remove() { 084 if (this.current != null && this.current.getMessage() != null) { 085 map.remove(this.current.getMessage().getMessageId()); 086 } 087 removeNode(this.current); 088 } 089 }; 090 } 091 092 public void remove(MessageReference message) { 093 if (message != null) { 094 PendingNode node = this.map.remove(message.getMessageId()); 095 removeNode(node); 096 } 097 } 098 099 public int size() { 100 return this.map.size(); 101 } 102 103 void removeNode(PendingNode node) { 104 if (node != null) { 105 map.remove(node.getMessage().getMessageId()); 106 if (root == node) { 107 root = (PendingNode) node.getNext(); 108 } 109 if (tail == node) { 110 tail = (PendingNode) node.getPrevious(); 111 } 112 node.unlink(); 113 } 114 } 115 116 List<PendingNode> getAsList() { 117 List<PendingNode> result = new ArrayList<PendingNode>(size()); 118 PendingNode node = root; 119 while (node != null) { 120 result.add(node); 121 node = (PendingNode) node.getNext(); 122 } 123 return result; 124 } 125 126 @Override 127 public String toString() { 128 return "OrderedPendingList(" + System.identityHashCode(this) + ")"; 129 } 130 131 }