001/** 002 * The MIT License (MIT) 003 * 004 * Copyright (c) 2019 nobark (tools4j), Marco Terzer, Anton Anufriev 005 * 006 * Permission is hereby granted, free of charge, to any person obtaining a copy 007 * of this software and associated documentation files (the "Software"), to deal 008 * in the Software without restriction, including without limitation the rights 009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 010 * copies of the Software, and to permit persons to whom the Software is 011 * furnished to do so, subject to the following conditions: 012 * 013 * The above copyright notice and this permission notice shall be included in all 014 * copies or substantial portions of the Software. 015 * 016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 022 * SOFTWARE. 023 */ 024package org.tools4j.nobark.queue; 025 026import java.util.function.BiConsumer; 027 028/** 029 * A conflation queue is a queue with a safety mechanism to prevent overflow. Values are enqueued with a conflation 030 * key, and if a value with the same key already resides in the queue then the two values will be "conflated". 031 * Conflation in the simplest case means that the most recent value survives and replaces older values; some more 032 * advanced implementations support merging when conflation occurs. 033 * 034 * @param <K> the type of the conflation key 035 * @param <V> the type of values in the queue 036 */ 037public interface ConflationQueue<K,V> { 038 /** 039 * Returns the appender object used by the producer to enqueue values. Some conflation queue implementations return 040 * thread-safe appender instances, other implementations return an instance per caller thread. Hence it is highly 041 * recommended to access the appender via this method directly from the producer thread and not share it between 042 * threads. 043 * 044 * @return the appender object used to enqueue values 045 */ 046 Appender<K,V> appender(); 047 048 /** 049 * Returns the poller object used by the consumer to poll values. Some conflation queue implementations return 050 * thread-safe poller instances, other implementations return an instance per caller thread. Hence it is highly 051 * recommended to access the poller via this method directly from the consumer thread and not share it between 052 * threads. 053 * 054 * @return the poller object used to poll values 055 */ 056 Poller<K,V> poller(); 057 058 /** 059 * Returns the number of elements in this queue. 060 * 061 * <p>Beware that, unlike in most collections, this method may 062 * <em>NOT</em> be a constant-time operation. Because of the 063 * asynchronous nature of concurrent queues, determining the current 064 * number of elements may require an O(n) traversal. 065 * Additionally, if elements are added or removed during execution 066 * of this method, the returned result may be inaccurate. Thus, 067 * this method is typically not very useful in concurrent 068 * applications. 069 * 070 * @return the number of elements in this queue 071 */ 072 int size(); 073 074 /** 075 * Appender used by the producer to enqueue values. 076 * 077 * @param <K> the type of the conflation key 078 * @param <V> the type of values in the queue 079 */ 080 interface Appender<K,V> { 081 /** 082 * Enqueue the specified value using the given conflation key. If conflation occurred, the conflated value 083 * is returned. If no conflation occurs, null is returned, or for {@link ExchangeConflationQueue} 084 * implementations an exchange value from the poller may be returned if present. 085 * 086 * @param conflationKey the conflation key 087 * @param value the value to enqueue 088 * @return the conflated value if conflation occurred, or otherwise null or an exchange value from the poller 089 * for {@link ExchangeConflationQueue} implementations 090 */ 091 V enqueue(K conflationKey, V value); 092 } 093 094 /** 095 * Poller object used by the consumer to poll values. 096 * 097 * @param <K> the type of the conflation key 098 * @param <V> the type of values in the queue 099 */ 100 interface Poller<K, V> { 101 /** 102 * Polls the queue passing a consumer which is invoked with conflation key and polled value if the queue was 103 * non-empty. Returns the polled value if any value was present in the queue, or null if the queue was empty. 104 * 105 * @param consumer consumer for conflation key and polled value 106 * @return the polled value, or null if the queue was empty 107 */ 108 V poll(BiConsumer<? super K, ? super V> consumer); 109 110 /** 111 * Polls the queue and returns the value if any value was present in the queue, or null if the queue was empty. 112 * 113 * @return the polled value, or null if the queue was empty 114 */ 115 default V poll() { 116 return poll((k,v) -> {}); 117 } 118 } 119}