Skip to content

Commit b7a5274

Browse files
committed
Added enumset to uniquemap to speed up getTriggeredUniques calls - should make iterating on all units and getting all unit triggers, viable :D
1 parent 9fc7be8 commit b7a5274

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

core/src/com/unciv/models/ruleset/unique/UniqueMap.kt

+17-9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ open class UniqueMap() {
1010
// 750 including deprecated, and EnumMap creates a N-sized array where N is the number of objects in the enum
1111
private val typedUniqueMap = EnumMap<UniqueType, ArrayList<Unique>>(UniqueType::class.java)
1212

13+
// Another memory-speed tradeoff - enumset is super fast and also super cheap, but it's not nothing
14+
// This is used to speed up triggered uniques - in other words, when we want to find all uniques with a certain modifier.
15+
// Rather than mapping all uniques thus triggered, this just stores whether any unique has that trigger -
16+
// because most of the time is spent iterating on uniques, in uniquemaps that have no such trigger in the first place!
17+
private val triggerEnumSet = EnumSet.noneOf(UniqueType::class.java)
18+
1319
constructor(uniques: Sequence<Unique>) : this() {
1420
addUniques(uniques.asIterable())
1521
}
@@ -21,10 +27,11 @@ open class UniqueMap() {
2127
val existingArrayList = innerUniqueMap[unique.placeholderText]
2228
if (existingArrayList != null) existingArrayList.add(unique)
2329
else innerUniqueMap[unique.placeholderText] = arrayListOf(unique)
24-
30+
2531
if (unique.type == null) return
2632
if (typedUniqueMap[unique.type] != null) return
2733
typedUniqueMap[unique.type] = innerUniqueMap[unique.placeholderText]
34+
triggerEnumSet.add(unique.type)
2835
}
2936

3037
/** Calls [addUnique] on each item from [uniques] */
@@ -36,20 +43,20 @@ open class UniqueMap() {
3643
val existingArrayList = innerUniqueMap[unique.placeholderText]
3744
existingArrayList?.remove(unique)
3845
}
39-
46+
4047
fun clear() {
4148
innerUniqueMap.clear()
4249
typedUniqueMap.clear()
4350
}
44-
51+
4552
// Pure functions
46-
53+
4754
fun hasUnique(uniqueType: UniqueType, state: StateForConditionals = StateForConditionals.EmptyState) =
4855
getUniques(uniqueType).any { it.conditionalsApply(state) && !it.isTimedTriggerable }
4956

5057
fun hasUnique(uniqueTag: String, state: StateForConditionals = StateForConditionals.EmptyState) =
5158
getUniques(uniqueTag).any { it.conditionalsApply(state) && !it.isTimedTriggerable }
52-
59+
5360
fun hasTagUnique(tagUnique: String) =
5461
innerUniqueMap.containsKey(tagUnique)
5562

@@ -62,7 +69,7 @@ open class UniqueMap() {
6269
?.asSequence()
6370
?: emptySequence()
6471

65-
fun getMatchingUniques(uniqueType: UniqueType, state: StateForConditionals = StateForConditionals.EmptyState) =
72+
fun getMatchingUniques(uniqueType: UniqueType, state: StateForConditionals = StateForConditionals.EmptyState) =
6673
getUniques(uniqueType)
6774
// Same as .filter | .flatMap, but more cpu/mem performant (7.7 GB vs ?? for test)
6875
.flatMap {
@@ -83,8 +90,8 @@ open class UniqueMap() {
8390
else -> it.getMultiplied(state)
8491
}
8592
}
86-
87-
fun hasMatchingUnique(uniqueType: UniqueType, state: StateForConditionals = StateForConditionals.EmptyState) =
93+
94+
fun hasMatchingUnique(uniqueType: UniqueType, state: StateForConditionals = StateForConditionals.EmptyState) =
8895
getUniques(uniqueType).any { it.conditionalsApply(state) }
8996

9097
fun hasMatchingUnique(uniqueTag: String, state: StateForConditionals = StateForConditionals.EmptyState) =
@@ -95,11 +102,12 @@ open class UniqueMap() {
95102

96103
fun getTriggeredUniques(trigger: UniqueType, stateForConditionals: StateForConditionals,
97104
triggerFilter: (Unique) -> Boolean = { true }): Sequence<Unique> {
105+
if (!triggerEnumSet.contains(trigger)) return emptySequence() // Common case - no such unique exists
98106
return getAllUniques().filter { unique ->
99107
unique.getModifiers(trigger).any(triggerFilter) && unique.conditionalsApply(stateForConditionals)
100108
}.flatMap { it.getMultiplied(stateForConditionals) }
101109
}
102-
110+
103111
companion object{
104112
val EMPTY = UniqueMap()
105113
}

0 commit comments

Comments
 (0)