diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/utils/CacheOperations.kt b/quartz/src/main/java/com/vitorpamplona/quartz/utils/CacheOperations.kt new file mode 100644 index 000000000..b1c9a9ccc --- /dev/null +++ b/quartz/src/main/java/com/vitorpamplona/quartz/utils/CacheOperations.kt @@ -0,0 +1,173 @@ +/** + * 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 + +interface CacheOperations { + fun forEach(consumer: BiConsumer) + + fun size(): Int + + fun filter(consumer: CacheCollectors.BiFilter): List { + val runner = CacheCollectors.BiFilterCollector(consumer) + forEach(runner) + return runner.results + } + + fun filterIntoSet(consumer: CacheCollectors.BiFilter): Set { + val runner = CacheCollectors.BiFilterUniqueCollector(consumer) + forEach(runner) + return runner.results + } + + fun map(consumer: CacheCollectors.BiNotNullMapper): List { + val runner = CacheCollectors.BiNotNullMapCollector(consumer) + forEach(runner) + return runner.results + } + + fun mapNotNull(consumer: CacheCollectors.BiMapper): List { + val runner = CacheCollectors.BiMapCollector(consumer) + forEach(runner) + return runner.results + } + + fun mapNotNullIntoSet(consumer: CacheCollectors.BiMapper): Set { + val runner = CacheCollectors.BiMapUniqueCollector(consumer) + forEach(runner) + return runner.results + } + + fun mapFlatten(consumer: CacheCollectors.BiMapper?>): List { + val runner = CacheCollectors.BiMapFlattenCollector(consumer) + forEach(runner) + return runner.results + } + + fun mapFlattenIntoSet(consumer: CacheCollectors.BiMapper?>): Set { + val runner = CacheCollectors.BiMapFlattenUniqueCollector(consumer) + forEach(runner) + return runner.results + } + + fun maxOrNullOf( + filter: CacheCollectors.BiFilter, + comparator: Comparator, + ): V? { + val runner = CacheCollectors.BiMaxOfCollector(filter, comparator) + forEach(runner) + return runner.maxV + } + + fun sumOf(consumer: CacheCollectors.BiSumOf): Int { + val runner = CacheCollectors.BiSumOfCollector(consumer) + forEach(runner) + return runner.sum + } + + fun sumOfLong(consumer: CacheCollectors.BiSumOfLong): Long { + val runner = CacheCollectors.BiSumOfLongCollector(consumer) + forEach(runner) + return runner.sum + } + + fun groupBy(consumer: CacheCollectors.BiNotNullMapper): Map> { + val runner = CacheCollectors.BiGroupByCollector(consumer) + forEach(runner) + return runner.results + } + + fun countByGroup(consumer: CacheCollectors.BiNotNullMapper): Map { + val runner = CacheCollectors.BiCountByGroupCollector(consumer) + forEach(runner) + return runner.results + } + + fun sumByGroup( + groupMap: CacheCollectors.BiNotNullMapper, + sumOf: CacheCollectors.BiNotNullMapper, + ): Map { + val runner = CacheCollectors.BiSumByGroupCollector(groupMap, sumOf) + forEach(runner) + return runner.results + } + + fun count(consumer: CacheCollectors.BiFilter): Int { + val runner = CacheCollectors.BiCountIfCollector(consumer) + forEach(runner) + return runner.count + } + + fun associate(transform: (K, V) -> Pair): Map { + val runner = CacheCollectors.BiAssociateCollector(size(), transform) + forEach(runner) + return runner.results + } + + fun associateNotNull(transform: (K, V) -> Pair?): Map { + val runner = CacheCollectors.BiAssociateNotNullCollector(size(), transform) + forEach(runner) + return runner.results + } + + fun associateWith(transform: (K, V) -> U?): Map { + val runner = CacheCollectors.BiAssociateWithCollector(size(), transform) + forEach(runner) + return runner.results + } + + fun associateNotNullWith(transform: (K, V) -> U): Map { + val runner = CacheCollectors.BiAssociateNotNullWithCollector(size(), transform) + forEach(runner) + return runner.results + } + + fun joinToString( + separator: CharSequence = ", ", + prefix: CharSequence = "", + postfix: CharSequence = "", + limit: Int = -1, + truncated: CharSequence = "...", + transform: ((K, V) -> CharSequence)? = null, + ): String { + val buffer = StringBuilder() + buffer.append(prefix) + var count = 0 + forEach { key, value -> + val str = if (transform != null) transform(key, value) else "" + if (str.isNotEmpty()) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + when { + transform != null -> buffer.append(str) + else -> buffer.append("$key $value") + } + } else { + return@forEach + } + } + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer.toString() + } +}