Skip to content

Commit bbebbaa

Browse files
Abdukodiri KurbonzodaAbduqodiri Qurbonzoda
authored andcommitted
Implement PersistentOrderedMap
1 parent 9de2bf8 commit bbebbaa

File tree

10 files changed

+602
-6
lines changed

10 files changed

+602
-6
lines changed

kotlinx-collections-immutable/src/main/kotlin/kotlinx/collections/immutable/extensions.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import kotlinx.collections.immutable.implementations.immutableMap.PersistentHash
2323
import kotlinx.collections.immutable.implementations.immutableMap.PersistentHashMapBuilder
2424
import kotlinx.collections.immutable.implementations.immutableSet.PersistentHashSet
2525
import kotlinx.collections.immutable.implementations.immutableSet.PersistentHashSetBuilder
26+
import kotlinx.collections.immutable.implementations.persistentOrderedMap.PersistentOrderedMap
2627
import kotlinx.collections.immutable.implementations.persistentOrderedSet.PersistentOrderedSet
2728

2829
//@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@@ -135,7 +136,7 @@ fun <E> persistentSetOf(): PersistentSet<E> = PersistentOrderedSet.emptyOf<E>()
135136

136137
fun <E> persistentHashSetOf(vararg elements: E): PersistentSet<E> = PersistentHashSet.emptyOf<E>().addAll(elements.asList())
137138

138-
fun <K, V> persistentMapOf(vararg pairs: Pair<K, V>): PersistentMap<K, V> = ImmutableOrderedMap.emptyOf<K,V>().mutate { it += pairs }
139+
fun <K, V> persistentMapOf(vararg pairs: Pair<K, V>): PersistentMap<K, V> = PersistentOrderedMap.emptyOf<K,V>().mutate { it += pairs }
139140
fun <K, V> persistentHashMapOf(vararg pairs: Pair<K, V>): PersistentMap<K, V> = PersistentHashMap.emptyOf<K,V>().mutate { it += pairs }
140141

141142
@Deprecated("Use persistentListOf instead.", ReplaceWith("persistentListOf(*elements)"))
@@ -190,21 +191,21 @@ fun <T> Iterable<T>.toPersistentSet(): PersistentSet<T> =
190191
?: persistentSetOf<T>() + this
191192

192193
fun <T> Set<T>.toPersistentHashSet(): PersistentSet<T>
193-
= this as? ImmutableHashSet
194+
= this as? PersistentHashSet
194195
?: (this as? PersistentHashSetBuilder<T>)?.build()
195196
?: PersistentHashSet.emptyOf<T>() + this
196197

197198

198199
fun <K, V> Map<K, V>.toImmutableMap(): ImmutableMap<K, V>
199200
= this as? ImmutableMap
200201
?: (this as? PersistentMap.Builder)?.build()
201-
?: ImmutableOrderedMap.emptyOf<K, V>().putAll(this)
202+
?: PersistentOrderedMap.emptyOf<K, V>().putAll(this)
202203

203204

204205
fun <K, V> Map<K, V>.toPersistentMap(): PersistentMap<K, V>
205206
= this as? PersistentMap<K, V>
206207
?: (this as? PersistentMap.Builder<K, V>)?.build()
207-
?: ImmutableOrderedMap.emptyOf<K, V>().putAll(this)
208+
?: PersistentOrderedMap.emptyOf<K, V>().putAll(this)
208209

209210
fun <K, V> Map<K, V>.toPersistentHashMap(): PersistentMap<K, V>
210211
= this as? PersistentMap

kotlinx-collections-immutable/src/main/kotlin/kotlinx/collections/immutable/implementations/immutableMap/PersistentHashMapContentIterators.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ private class MapEntry<out K, out V>(override val key: K, override val value: V)
7979

8080

8181
internal abstract class PersistentHashMapBaseIterator<K, V, T>(node: TrieNode<K, V>,
82-
protected val path: Array<TrieNodeBaseIterator<K, V, T>>) : Iterator<T> {
82+
protected val path: Array<TrieNodeBaseIterator<K, V, T>>) : Iterator<T> {
8383
private var pathLastIndex = 0
8484
private var hasNext = true
8585

kotlinx-collections-immutable/src/main/kotlin/kotlinx/collections/immutable/implementations/immutableMap/TrieNode.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ internal class TrieNode<K, V>(var dataMap: Int,
412412
val keyIndex = keyDataIndex(keyPosition)
413413

414414
if (key == keyAtIndex(keyIndex)) {
415+
if (valueAtKeyIndex(keyIndex) === value) { return this }
415416
return mutableUpdateValueAtIndex(keyIndex, value, mutator)
416417
}
417418
mutator.size++
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Copyright 2016-2018 JetBrains s.r.o.
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 kotlinx.collections.immutable.implementations.persistentOrderedMap
18+
19+
import kotlinx.collections.immutable.ImmutableCollection
20+
import kotlinx.collections.immutable.ImmutableSet
21+
import kotlinx.collections.immutable.PersistentMap
22+
import kotlinx.collections.immutable.implementations.immutableMap.PersistentHashMap
23+
import kotlinx.collections.immutable.mutate
24+
25+
internal class Links<out K, out V>(val value: V, val previous: K?, val next: K?)
26+
27+
internal class PersistentOrderedMap<K, V>(internal val firstKey: K?,
28+
internal val lastKey: K?,
29+
internal val map: PersistentHashMap<K, Links<K, V>>): AbstractMap<K, V>(), PersistentMap<K, V> {
30+
31+
override val size: Int
32+
get() = map.size
33+
34+
override val keys: ImmutableSet<K>
35+
get() {
36+
return PersistentOrderedMapKeys(this)
37+
}
38+
39+
override val values: ImmutableCollection<V>
40+
get() {
41+
return PersistentOrderedMapValues(this)
42+
}
43+
44+
override val entries: ImmutableSet<Map.Entry<K, V>>
45+
get() {
46+
return createEntries()
47+
}
48+
49+
private fun createEntries(): ImmutableSet<Map.Entry<K, V>> {
50+
return PersistentOrderedMapEntries(this)
51+
}
52+
53+
// TODO: compiler bug: this bridge should be generated automatically
54+
@PublishedApi
55+
internal fun getEntries(): Set<Map.Entry<K, V>> {
56+
return createEntries()
57+
}
58+
59+
override fun containsKey(key: K): Boolean {
60+
return map.containsKey(key)
61+
}
62+
63+
override fun get(key: K): V? {
64+
return map[key]?.value
65+
}
66+
67+
override fun put(key: K, value: @UnsafeVariance V): PersistentOrderedMap<K, V> {
68+
val links = map[key]
69+
if (links != null) {
70+
if (links.value == value) {
71+
return this
72+
}
73+
val newMap = map.put(key, Links(value, links.previous, links.next))
74+
return PersistentOrderedMap(firstKey, lastKey, newMap)
75+
}
76+
if (isEmpty()) {
77+
val newMap = map.put(key, Links(value, null, null))
78+
return PersistentOrderedMap(key, key, newMap)
79+
}
80+
val oldLinks = map[lastKey]!!
81+
assert(oldLinks.next == null)
82+
val newLinks = Links(oldLinks.value, oldLinks.previous, key)
83+
val newMap = map.put(lastKey as K, newLinks).put(key, Links(value, lastKey, null))
84+
return PersistentOrderedMap(firstKey, key, newMap)
85+
}
86+
87+
override fun remove(key: K): PersistentOrderedMap<K, V> {
88+
val links = map[key] ?: return this
89+
90+
var newMap = map.remove(key)
91+
if (key != firstKey) {
92+
val previousLinks = newMap[links.previous]!!
93+
assert(previousLinks.next == key)
94+
newMap = newMap.put(links.previous as K, Links(previousLinks.value, previousLinks.previous, links.next))
95+
}
96+
if (key != lastKey) {
97+
val nextLinks = newMap[links.next]!!
98+
assert(nextLinks.previous == key)
99+
newMap = newMap.put(links.next as K, Links(nextLinks.value, links.previous, nextLinks.next))
100+
}
101+
val newFirstKey = if (key == firstKey) links.next else firstKey
102+
val newLastKey = if (key == lastKey) links.previous else lastKey
103+
return PersistentOrderedMap(newFirstKey, newLastKey, newMap)
104+
}
105+
106+
override fun remove(key: K, value: @UnsafeVariance V): PersistentOrderedMap<K, V> {
107+
val links = map[key] ?: return this
108+
return if (links.value == value) this.remove(key) else this
109+
}
110+
111+
override fun putAll(m: Map<out K, @UnsafeVariance V>): PersistentMap<K, V> {
112+
return this.mutate { it.putAll(m) }
113+
}
114+
115+
override fun clear(): PersistentMap<K, V> {
116+
return emptyOf()
117+
}
118+
119+
override fun builder(): PersistentMap.Builder<K, V> {
120+
return PersistentOrderedMapBuilder(this)
121+
}
122+
123+
internal companion object {
124+
private val EMPTY = PersistentOrderedMap<Nothing, Nothing>(null, null, PersistentHashMap.emptyOf())
125+
internal fun <K, V> emptyOf(): PersistentOrderedMap<K, V> = EMPTY as PersistentOrderedMap<K, V>
126+
}
127+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright 2016-2018 JetBrains s.r.o.
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 kotlinx.collections.immutable.implementations.persistentOrderedMap
18+
19+
import kotlinx.collections.immutable.PersistentMap
20+
21+
internal class PersistentOrderedMapBuilder<K, V>(private var map: PersistentOrderedMap<K, V>) : AbstractMutableMap<K, V>(), PersistentMap.Builder<K, V> {
22+
internal var firstKey = map.firstKey
23+
private var lastKey = map.lastKey
24+
internal val mapBuilder = map.map.builder()
25+
26+
override val size: Int
27+
get() = mapBuilder.size
28+
29+
override fun build(): PersistentMap<K, V> {
30+
val newMap = mapBuilder.build()
31+
map = if (newMap === map.map) {
32+
assert(firstKey === map.firstKey)
33+
assert(lastKey === map.lastKey)
34+
map
35+
} else {
36+
PersistentOrderedMap(firstKey, lastKey, newMap)
37+
}
38+
return map
39+
}
40+
41+
override val entries: MutableSet<MutableMap.MutableEntry<K, V>>
42+
get() {
43+
return PersistentOrderedMapBuilderEntries(this)
44+
}
45+
46+
override val keys: MutableSet<K>
47+
get() {
48+
return PersistentOrderedMapBuilderKeys(this)
49+
}
50+
51+
override val values: MutableCollection<V>
52+
get() {
53+
return PersistentOrderedMapBuilderValues(this)
54+
}
55+
56+
override fun containsKey(key: K): Boolean {
57+
return mapBuilder.containsKey(key)
58+
}
59+
60+
override fun get(key: K): V? {
61+
return mapBuilder[key]?.value
62+
}
63+
64+
override fun put(key: K, value: @UnsafeVariance V): V? {
65+
val links = mapBuilder[key]
66+
if (links != null) {
67+
if (links.value == value) {
68+
return value
69+
}
70+
mapBuilder[key] = Links(value, links.previous, links.next)
71+
return links.value
72+
}
73+
74+
if (isEmpty()) { // isEmpty
75+
firstKey = key
76+
lastKey = key
77+
mapBuilder[key] = Links<K, V>(value, null, null)
78+
return null
79+
}
80+
val oldLinks = mapBuilder[lastKey]!!
81+
assert(oldLinks.next == null)
82+
val newLinks = Links(oldLinks.value, oldLinks.previous, key)
83+
84+
mapBuilder[lastKey as K] = newLinks
85+
mapBuilder[key] = Links(value, lastKey, null)
86+
lastKey = key
87+
return null
88+
}
89+
90+
override fun remove(key: K): V? {
91+
val links = mapBuilder.remove(key) ?: return null
92+
93+
if (links.previous != null) {
94+
val previousLinks = mapBuilder[links.previous]!!
95+
assert(previousLinks.next == key)
96+
mapBuilder[links.previous] = Links(previousLinks.value, previousLinks.previous, links.next)
97+
}
98+
if (links.next != null) {
99+
val nextLinks = mapBuilder[links.next]!!
100+
assert(nextLinks.previous == key)
101+
mapBuilder[links.next] = Links(nextLinks.value, links.previous, nextLinks.next)
102+
}
103+
firstKey = if (key == firstKey) links.next else firstKey
104+
lastKey = if (key == lastKey) links.previous else lastKey
105+
return links.value
106+
}
107+
108+
override fun clear() {
109+
mapBuilder.clear()
110+
firstKey = null
111+
lastKey = null
112+
}
113+
}

0 commit comments

Comments
 (0)