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 */ 017package org.apache.activemq.broker.region.policy; 018 019import org.apache.activemq.broker.region.MessageReference; 020 021import java.io.IOException; 022import java.util.HashMap; 023import java.util.Iterator; 024import java.util.LinkedList; 025import java.util.List; 026 027/** 028 * An eviction strategy which evicts the oldest message within messages with the same property value 029 * 030 * 031 * @org.apache.xbean.XBean 032 * 033 */ 034public class UniquePropertyMessageEvictionStrategy extends MessageEvictionStrategySupport { 035 036 protected String propertyName; 037 038 public String getPropertyName() { 039 return propertyName; 040 } 041 042 public void setPropertyName(String propertyName) { 043 this.propertyName = propertyName; 044 } 045 046 @Override 047 public MessageReference[] evictMessages(LinkedList messages) throws IOException { 048 List<MessageReference> messageReferences = new LinkedList<>(messages); 049 HashMap<Object, MessageReference> pivots = new HashMap<>(); 050 051 for (MessageReference reference : messageReferences) { 052 if (propertyName != null && reference.getMessage().getProperty(propertyName) != null) { 053 Object key = reference.getMessage().getProperty(propertyName); 054 if (pivots.containsKey(key)) { 055 MessageReference pivot = pivots.get(key); 056 if (reference.getMessage().getTimestamp() > pivot.getMessage().getTimestamp()) { 057 pivots.put(key, reference); 058 } 059 } else { 060 pivots.put(key, reference); 061 } 062 } 063 } 064 065 if (pivots.isEmpty() || pivots.values().size() == messageReferences.size()) { 066 return new MessageReference[]{(MessageReference) messages.removeFirst()}; 067 } else { 068 messages.removeIf(message -> !pivots.containsValue(message)); 069 messageReferences.removeAll(pivots.values()); 070 return messageReferences.toArray(new MessageReference[0]); 071 } 072 } 073 074}