Gilles Barbier
04/01/2021, 4:01 PMval b = "1".toByteArray()
val s = mutableSetOf("1".toByteArray())
s.remove(b) // <== this does not work, probably because "1".toByteArray() != "1".toByteArray()
s.removeIf { b.contentEquals(it) } // <= this works
Rob Elliot
04/01/2021, 4:09 PMSet
with arrays; `Set`’s contract is to use equals
and hashCode
to ensure no duplicates, and on the JVM I’m 99% sure every array is unique and cannot be equal to another array.Gilles Barbier
04/01/2021, 4:11 PMTomasz Krakowiak
04/01/2021, 4:12 PMByteArray
does not implement collection. ByteArray
does not overrides equals
Rob Elliot
04/01/2021, 4:13 PMGilles Barbier
04/01/2021, 4:13 PMTomasz Krakowiak
04/01/2021, 4:19 PMGilles Barbier
04/01/2021, 4:22 PMTomasz Krakowiak
04/01/2021, 4:24 PMinline class Bytes(val content : ByteArray) {
override fun equals(other : Bytes) = TODO()
}
Or somthing like that to make it work : )Tomasz Krakowiak
04/01/2021, 4:25 PMGilles Barbier
04/01/2021, 4:37 PMclass InMemoryKeySetStorage() : KeySetStorage, Flushable {
val storage = ConcurrentHashMap<String, MutableSet<Bytes>>()
override suspend fun getSet(key: String): Set<ByteArray> {
return getBytesPerKey(key).map { it.content }.toSet()
}
override suspend fun addToSet(key: String, value: ByteArray) {
getBytesPerKey(key).add(Bytes(value))
}
override suspend fun removeFromSet(key: String, value: ByteArray) {
getBytesPerKey(key).remove(Bytes(value))
// clean key if now empty
if (getSet(key).isEmpty()) storage.remove(key)
}
override fun flush() {
storage.clear()
}
private fun getBytesPerKey(key: String): MutableSet<Bytes> {
return storage[key]
?: run {
val set = mutableSetOf<Bytes>()
storage[key] = set
set
}
}
class Bytes(val content : ByteArray) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Bytes
if (!content.contentEquals(other.content)) return false
return true
}
override fun hashCode(): Int {
return content.contentHashCode()
}
}
}
Tomasz Krakowiak
04/01/2021, 4:38 PMTomasz Krakowiak
04/01/2021, 4:42 PMif (getSet(key).isEmpty()) storage.remove(key)
requires synchronizationTomasz Krakowiak
04/01/2021, 4:43 PMConcurrentHashMap
which suggest you want your data structure to be concurrent, but mutableSetOf
returns non-concurrent set implementation.Tomasz Krakowiak
04/01/2021, 4:45 PMrun
provides any kind of synchronization?Tomasz Krakowiak
04/01/2021, 4:48 PMTomasz Krakowiak
04/01/2021, 4:51 PMNir
04/01/2021, 5:16 PMTomasz Krakowiak
04/01/2021, 5:35 PMNir
04/01/2021, 5:36 PMNir
04/01/2021, 5:36 PMNir
04/01/2021, 5:36 PMNir
04/01/2021, 5:36 PMNir
04/01/2021, 5:37 PMNir
04/01/2021, 5:37 PMTomasz Krakowiak
04/01/2021, 5:37 PMNir
04/01/2021, 5:37 PMTomasz Krakowiak
04/01/2021, 5:38 PMval storage = ConcurrentHashMap<String, MutableSet<Bytes>>()
Nir
04/01/2021, 5:38 PMNir
04/01/2021, 5:38 PMNir
04/01/2021, 5:38 PMNir
04/01/2021, 5:38 PMTomasz Krakowiak
04/01/2021, 5:40 PMNir
04/01/2021, 5:40 PMTomasz Krakowiak
04/01/2021, 5:40 PMNir
04/01/2021, 5:41 PMTomasz Krakowiak
04/01/2021, 5:41 PMNir
04/01/2021, 5:42 PMNir
04/01/2021, 5:42 PMTomasz Krakowiak
04/01/2021, 5:42 PMNir
04/01/2021, 5:42 PMNir
04/01/2021, 5:43 PMTomasz Krakowiak
04/01/2021, 5:43 PMA Multimap that cannot hold duplicate key-value pairs.From guava SetMultimap Javadoc
Tomasz Krakowiak
04/01/2021, 5:44 PMNir
04/01/2021, 5:44 PMTomasz Krakowiak
04/01/2021, 5:45 PMSetMultimap
Nir
04/01/2021, 5:45 PMMap<String, Set<Value>> is not equivalent to a MultiMap<String, Value>
Tomasz Krakowiak
04/01/2021, 5:47 PMTomasz Krakowiak [7:40 PM]
Maybe SetMultimap?
Nir [7:40 PM]
well, still not really the same, they store the same data, but not the same complexity guarantees. There's no way to check in O(1) if there's a byte belonging to a string, in a Multimap<String, Bytes>
Nir
04/01/2021, 5:48 PMTomasz Krakowiak
04/01/2021, 5:48 PMNir
04/01/2021, 5:49 PMNir
04/01/2021, 5:49 PM