1 /* <lambda>null2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.kairos.internal.util 18 19 import com.android.systemui.kairos.internal.store.NoValue 20 import java.util.concurrent.ConcurrentHashMap 21 import java.util.concurrent.ConcurrentMap 22 23 internal class ConcurrentNullableHashMap<K, V> 24 private constructor(private val inner: ConcurrentHashMap<Any, Any>) : 25 ConcurrentMap<K, V>, AbstractMutableMap<K, V>() { 26 27 constructor() : this(ConcurrentHashMap()) 28 29 constructor(capacity: Int) : this(ConcurrentHashMap(capacity)) 30 31 override fun get(key: K): V? = inner[key ?: NullValue]?.let { toNullable<V>(it) } 32 33 fun getValue(key: K): V = toNullable(inner.getValue(key ?: NullValue)) 34 35 @Suppress("UNCHECKED_CAST") 36 override fun put(key: K, value: V): V? = 37 inner.put(key ?: NullValue, value ?: NullValue)?.takeIf { it !== NullValue } as V? 38 39 operator fun set(key: K, value: V) { 40 put(key, value) 41 } 42 43 fun toMap(): Map<K, V> = 44 inner.asSequence().associate { (k, v) -> toNullable<K>(k) to toNullable(v) } 45 46 override fun clear() { 47 inner.clear() 48 } 49 50 override fun remove(key: K, value: V): Boolean = inner.remove(key ?: NoValue, value ?: NoValue) 51 52 override val entries: MutableSet<MutableMap.MutableEntry<K, V>> = 53 object : AbstractMutableSet<MutableMap.MutableEntry<K, V>>() { 54 val wrapped = inner.entries 55 56 override fun add(element: MutableMap.MutableEntry<K, V>): Boolean { 57 val e = 58 object : MutableMap.MutableEntry<Any, Any> { 59 override val key: Any 60 get() = element.key ?: NullValue 61 62 override val value: Any 63 get() = element.value ?: NullValue 64 65 override fun setValue(newValue: Any): Any = 66 element.setValue(toNullable(newValue)) ?: NullValue 67 } 68 return wrapped.add(e) 69 } 70 71 override val size: Int 72 get() = wrapped.size 73 74 override fun iterator(): MutableIterator<MutableMap.MutableEntry<K, V>> { 75 val iter = wrapped.iterator() 76 return object : MutableIterator<MutableMap.MutableEntry<K, V>> { 77 override fun hasNext(): Boolean = iter.hasNext() 78 79 override fun next(): MutableMap.MutableEntry<K, V> { 80 val element = iter.next() 81 return object : MutableMap.MutableEntry<K, V> { 82 override val key: K 83 get() = toNullable(element.key) 84 85 override val value: V 86 get() = toNullable(element.value) 87 88 override fun setValue(newValue: V): V = 89 toNullable(element.setValue(newValue ?: NullValue)) 90 } 91 } 92 93 override fun remove() { 94 iter.remove() 95 } 96 } 97 } 98 } 99 100 override fun replace(key: K, oldValue: V, newValue: V): Boolean = 101 inner.replace(key ?: NullValue, oldValue ?: NullValue, newValue ?: NullValue) 102 103 override fun replace(key: K, value: V): V? = 104 inner.replace(key ?: NullValue, value ?: NullValue)?.let { toNullable<V>(it) } 105 106 override fun putIfAbsent(key: K, value: V): V? = 107 inner.putIfAbsent(key ?: NullValue, value ?: NullValue)?.let { toNullable<V>(it) } 108 109 @Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE") 110 private inline fun <T> toNullable(value: Any): T = value.takeIf { it !== NullValue } as T 111 112 fun isNotEmpty(): Boolean = inner.isNotEmpty() 113 114 @Suppress("UNCHECKED_CAST") 115 override fun remove(key: K): V? = 116 inner.remove(key ?: NullValue)?.takeIf { it !== NullValue } as V? 117 118 fun asSequence(): Sequence<Pair<K, V>> = 119 inner.asSequence().map { (key, value) -> toNullable<K>(key) to toNullable(value) } 120 121 override fun isEmpty(): Boolean = inner.isEmpty() 122 123 override fun containsKey(key: K): Boolean = inner.containsKey(key ?: NullValue) 124 125 fun getOrPut(key: K, defaultValue: () -> V): V = 126 toNullable(inner.getOrPut(key) { defaultValue() ?: NullValue }) 127 } 128 129 private object NullValue 130