mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-28 15:57:31 +02:00
Move common collectors to new utility class
This commit is contained in:
@@ -0,0 +1,359 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.utils
|
||||
|
||||
import java.util.function.BiConsumer
|
||||
|
||||
object CacheCollectors {
|
||||
fun interface BiFilter<K, V> {
|
||||
fun filter(
|
||||
k: K,
|
||||
v: V,
|
||||
): Boolean
|
||||
}
|
||||
|
||||
class BiFilterCollector<K, V>(
|
||||
val filter: BiFilter<K, V>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: ArrayList<V> = ArrayList()
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
if (filter.filter(k, v)) {
|
||||
results.add(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BiFilterUniqueCollector<K, V>(
|
||||
val filter: BiFilter<K, V>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: HashSet<V> = HashSet()
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
if (filter.filter(k, v)) {
|
||||
results.add(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun interface BiMapper<K, V, R> {
|
||||
fun map(
|
||||
k: K,
|
||||
v: V,
|
||||
): R?
|
||||
}
|
||||
|
||||
fun interface BiMapperNotNull<K, V, R> {
|
||||
fun map(
|
||||
k: K,
|
||||
v: V,
|
||||
): R
|
||||
}
|
||||
|
||||
class BiMapCollector<K, V, R>(
|
||||
val mapper: BiMapper<K, V, R?>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: ArrayList<R> = ArrayList()
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
val result = mapper.map(k, v)
|
||||
if (result != null) {
|
||||
results.add(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BiAssociateCollector<K, V, T, U>(
|
||||
val size: Int,
|
||||
val mapper: BiMapperNotNull<K, V, Pair<T, U>>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: LinkedHashMap<T, U> = LinkedHashMap(size)
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
val pair = mapper.map(k, v)
|
||||
results.put(pair.first, pair.second)
|
||||
}
|
||||
}
|
||||
|
||||
class BiAssociateNotNullCollector<K, V, T, U>(
|
||||
val size: Int,
|
||||
val mapper: BiMapper<K, V, Pair<T, U>?>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: LinkedHashMap<T, U> = LinkedHashMap(size)
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
val pair = mapper.map(k, v)
|
||||
if (pair != null) {
|
||||
results.put(pair.first, pair.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BiAssociateWithCollector<K, V, U>(
|
||||
val size: Int,
|
||||
val mapper: BiMapper<K, V, U?>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: LinkedHashMap<K, U?> = LinkedHashMap(size)
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
results.put(k, mapper.map(k, v))
|
||||
}
|
||||
}
|
||||
|
||||
class BiAssociateNotNullWithCollector<K, V, U>(
|
||||
val size: Int,
|
||||
val mapper: BiMapper<K, V, U>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: LinkedHashMap<K, U> = LinkedHashMap(size)
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
val newValue = mapper.map(k, v)
|
||||
if (newValue != null) {
|
||||
results.put(k, newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BiMapUniqueCollector<K, V, R>(
|
||||
val mapper: BiMapper<K, V, R?>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: HashSet<R> = HashSet()
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
val result = mapper.map(k, v)
|
||||
if (result != null) {
|
||||
results.add(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BiMapFlattenCollector<K, V, R>(
|
||||
val mapper: BiMapper<K, V, Collection<R>?>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: ArrayList<R> = ArrayList()
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
val result = mapper.map(k, v)
|
||||
if (result != null) {
|
||||
results.addAll(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BiMapFlattenUniqueCollector<K, V, R>(
|
||||
val mapper: BiMapper<K, V, Collection<R>?>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: HashSet<R> = HashSet()
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
val result = mapper.map(k, v)
|
||||
if (result != null) {
|
||||
results.addAll(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun interface BiNotNullMapper<K, V, R> {
|
||||
fun map(
|
||||
k: K,
|
||||
v: V,
|
||||
): R
|
||||
}
|
||||
|
||||
class BiNotNullMapCollector<K, V, R>(
|
||||
val mapper: BiNotNullMapper<K, V, R>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results: ArrayList<R> = ArrayList()
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
results.add(mapper.map(k, v))
|
||||
}
|
||||
}
|
||||
|
||||
fun interface BiSumOf<K, V> {
|
||||
fun map(
|
||||
k: K,
|
||||
v: V,
|
||||
): Int
|
||||
}
|
||||
|
||||
class BiMaxOfCollector<K, V>(
|
||||
val filter: BiFilter<K, V>,
|
||||
val comparator: Comparator<V>,
|
||||
) : BiConsumer<K, V> {
|
||||
var maxK: K? = null
|
||||
var maxV: V? = null
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
if (filter.filter(k, v)) {
|
||||
if (maxK == null || comparator.compare(v, maxV) > 0) {
|
||||
maxK = k
|
||||
maxV = v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BiSumOfCollector<K, V>(
|
||||
val mapper: BiSumOf<K, V>,
|
||||
) : BiConsumer<K, V> {
|
||||
var sum = 0
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
sum += mapper.map(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
fun interface BiSumOfLong<K, V> {
|
||||
fun map(
|
||||
k: K,
|
||||
v: V,
|
||||
): Long
|
||||
}
|
||||
|
||||
class BiSumOfLongCollector<K, V>(
|
||||
val mapper: BiSumOfLong<K, V>,
|
||||
) : BiConsumer<K, V> {
|
||||
var sum = 0L
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
sum += mapper.map(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
class BiGroupByCollector<K, V, R>(
|
||||
val mapper: BiNotNullMapper<K, V, R>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results = HashMap<R, ArrayList<V>>()
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
val group = mapper.map(k, v)
|
||||
|
||||
val list = results[group]
|
||||
if (list == null) {
|
||||
val answer = ArrayList<V>()
|
||||
answer.add(v)
|
||||
results[group] = answer
|
||||
} else {
|
||||
list.add(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BiCountByGroupCollector<K, V, R>(
|
||||
val mapper: BiNotNullMapper<K, V, R>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results = HashMap<R, Int>()
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
val group = mapper.map(k, v)
|
||||
|
||||
val count = results[group]
|
||||
if (count == null) {
|
||||
results[group] = 1
|
||||
} else {
|
||||
results[group] = count + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BiSumByGroupCollector<K, V, R>(
|
||||
val mapper: BiNotNullMapper<K, V, R>,
|
||||
val sumOf: BiNotNullMapper<K, V, Long>,
|
||||
) : BiConsumer<K, V> {
|
||||
var results = HashMap<R, Long>()
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
val group = mapper.map(k, v)
|
||||
|
||||
val sum = results[group]
|
||||
if (sum == null) {
|
||||
results[group] = sumOf.map(k, v)
|
||||
} else {
|
||||
results[group] = sum + sumOf.map(k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BiCountIfCollector<K, V>(
|
||||
val filter: BiFilter<K, V>,
|
||||
) : BiConsumer<K, V> {
|
||||
var count = 0
|
||||
|
||||
override fun accept(
|
||||
k: K,
|
||||
v: V,
|
||||
) {
|
||||
if (filter.filter(k, v)) count++
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user