Skip to content

Commit 7837ade

Browse files
committed
Optimizations for mapper classes
1 parent aec0927 commit 7837ade

7 files changed

Lines changed: 89 additions & 10 deletions

File tree

ImperatorToCK3/Mappers/Culture/CultureMapper.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using commonItems;
22
using ImperatorToCK3.CK3.Cultures;
33
using ImperatorToCK3.Mappers.Region;
4+
using System;
45
using System.Collections.Generic;
56
using System.Linq;
67

@@ -18,6 +19,7 @@ public CultureMapper(ImperatorRegionMapper irRegionMapper, CK3RegionMapper ck3Re
1819
Logger.Info($"Loaded {cultureMappingRules.Count} cultural links.");
1920

2021
RemoveInvalidRules(cultures);
22+
BuildLookup();
2123

2224
Logger.IncrementProgress();
2325
}
@@ -30,6 +32,7 @@ public CultureMapper(BufferedReader reader, ImperatorRegionMapper irRegionMapper
3032
parser.ParseStream(reader);
3133

3234
RemoveInvalidRules(cultures);
35+
BuildLookup();
3336
}
3437

3538
private void RegisterKeys(Parser parser) {
@@ -44,14 +47,35 @@ private void RemoveInvalidRules(CultureCollection cultures) {
4447
Logger.Debug($"{removedCount} culture mapping rules removed due to specified CK3 cultures not existing.");
4548
}
4649
}
47-
50+
51+
private void BuildLookup() {
52+
cultureRuleLookup.Clear();
53+
foreach (var rule in cultureMappingRules) {
54+
foreach (var irCulture in rule.IrCultures) {
55+
if (!cultureRuleLookup.TryGetValue(irCulture, out var list)) {
56+
list = new List<CultureMappingRule>();
57+
cultureRuleLookup[irCulture] = list;
58+
}
59+
list.Add(rule);
60+
}
61+
}
62+
}
63+
4864
public string? Match(
4965
string irCulture,
5066
ulong? ck3ProvinceId,
5167
ulong? irProvinceId,
5268
string? historicalTag
5369
) {
54-
foreach (var cultureMappingRule in cultureMappingRules) {
70+
if (string.IsNullOrEmpty(irCulture)) {
71+
return null;
72+
}
73+
74+
if (!cultureRuleLookup.TryGetValue(irCulture, out var rules)) {
75+
return null;
76+
}
77+
78+
foreach (var cultureMappingRule in rules) {
5579
var possibleMatch = cultureMappingRule.Match(irCulture, ck3ProvinceId, irProvinceId, historicalTag, irRegionMapper, ck3RegionMapper);
5680
if (possibleMatch is not null) {
5781
return possibleMatch;
@@ -61,6 +85,7 @@ private void RemoveInvalidRules(CultureCollection cultures) {
6185
}
6286

6387
private readonly List<CultureMappingRule> cultureMappingRules = new();
88+
private readonly Dictionary<string, List<CultureMappingRule>> cultureRuleLookup = new(StringComparer.Ordinal);
6489
private readonly ImperatorRegionMapper irRegionMapper;
6590
private readonly CK3RegionMapper ck3RegionMapper;
6691
}

ImperatorToCK3/Mappers/Culture/CultureMappingRule.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ CK3RegionMapper ck3RegionMapper
8080
}
8181

8282
public string CK3CultureId { get; private set; } = string.Empty;
83+
public IReadOnlySet<string> IrCultures => cultures;
8384

8485
private readonly SortedSet<string> cultures = new();
8586
private readonly SortedSet<string> irHistoricalTags = new();

ImperatorToCK3/Mappers/Government/GovernmentMapper.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace ImperatorToCK3.Mappers.Government;
88

99
internal sealed class GovernmentMapper {
1010
private readonly List<GovernmentMapping> mappings = [];
11+
private readonly Dictionary<string, List<GovernmentMapping>> mappingLookup = new(StringComparer.Ordinal);
1112

1213
public GovernmentMapper(ICollection<string> ck3GovernmentIds) {
1314
Logger.Info("Parsing government mappings...");
@@ -20,6 +21,7 @@ public GovernmentMapper(ICollection<string> ck3GovernmentIds) {
2021

2122
Logger.Debug("Removing invalid government links...");
2223
RemoveInvalidLinks(ck3GovernmentIds);
24+
BuildLookup();
2325
}
2426
private void RegisterKeys(Parser parser) {
2527
parser.RegisterKeyword("link", reader => {
@@ -39,9 +41,30 @@ private void RemoveInvalidLinks(ICollection<string> ck3GovernmentIds) {
3941
mappings.Remove(mapping);
4042
}
4143
}
42-
43-
public string? GetCK3GovernmentForImperatorGovernment(string irGovernmentId, TitleRank? rank, string? irCultureId, IReadOnlyCollection<string> enabledCK3Dlcs) {
44+
45+
private void BuildLookup() {
46+
mappingLookup.Clear();
4447
foreach (var mapping in mappings) {
48+
foreach (var irGovernmentId in mapping.ImperatorGovernmentIds) {
49+
if (!mappingLookup.TryGetValue(irGovernmentId, out var list)) {
50+
list = new List<GovernmentMapping>();
51+
mappingLookup[irGovernmentId] = list;
52+
}
53+
list.Add(mapping);
54+
}
55+
}
56+
}
57+
58+
public string? GetCK3GovernmentForImperatorGovernment(string irGovernmentId, TitleRank? rank, string? irCultureId, IReadOnlyCollection<string> enabledCK3Dlcs) {
59+
if (string.IsNullOrEmpty(irGovernmentId)) {
60+
return null;
61+
}
62+
63+
if (!mappingLookup.TryGetValue(irGovernmentId, out var candidates)) {
64+
return null;
65+
}
66+
67+
foreach (var mapping in candidates) {
4568
var match = mapping.Match(irGovernmentId, rank, irCultureId, enabledCK3Dlcs);
4669
if (match is not null) {
4770
return match;

ImperatorToCK3/Mappers/Province/ProvinceMapper.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace ImperatorToCK3.Mappers.Province;
88

99
internal sealed class ProvinceMapper {
10+
private static readonly List<ulong> EmptyProvinceList = [];
1011
private readonly Dictionary<ulong, List<ulong>> imperatorToCK3ProvinceMap = [];
1112
private readonly Dictionary<ulong, List<ulong>> ck3ToImperatorProvinceMap = [];
1213

@@ -61,14 +62,14 @@ public List<ulong> GetImperatorProvinceNumbers(ulong ck3ProvinceNumber) {
6162
if (ck3ToImperatorProvinceMap.TryGetValue(ck3ProvinceNumber, out var impProvs)) {
6263
return impProvs;
6364
}
64-
return [];
65+
return EmptyProvinceList;
6566
}
6667

6768
public List<ulong> GetCK3ProvinceNumbers(ulong impProvinceNumber) {
6869
if (imperatorToCK3ProvinceMap.TryGetValue(impProvinceNumber, out var ck3Provs)) {
6970
return ck3Provs;
7071
}
71-
return [];
72+
return EmptyProvinceList;
7273
}
7374

7475
public void DetectInvalidMappings(MapData irMapData, MapData ck3MapData) {

ImperatorToCK3/Mappers/Religion/ReligionMapper.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using commonItems.Collections;
33
using ImperatorToCK3.CK3.Religions;
44
using ImperatorToCK3.Mappers.Region;
5+
using System;
56
using System.Collections.Generic;
67
using System.IO;
78

@@ -22,6 +23,7 @@ public ReligionMapper(ReligionCollection ck3Religions, ImperatorRegionMapper imp
2223
Logger.Info($"Loaded {religionMappings.Count} religious links.");
2324

2425
RemoveMappingsWithNonexistentCK3Faiths(ck3Religions);
26+
BuildLookup();
2527

2628
Logger.IncrementProgress();
2729
}
@@ -34,14 +36,36 @@ public ReligionMapper(BufferedReader reader, ReligionCollection ck3Religions, Im
3436
parser.ParseStream(reader);
3537

3638
RemoveMappingsWithNonexistentCK3Faiths(ck3Religions);
39+
BuildLookup();
3740
}
3841

3942
private void RemoveMappingsWithNonexistentCK3Faiths(ReligionCollection ck3Religions) {
4043
religionMappings.RemoveWhere(m=>m.CK3FaithId is not null && ck3Religions.GetFaith(m.CK3FaithId) is null);
4144
}
4245

46+
private void BuildLookup() {
47+
religionLookup.Clear();
48+
foreach (var mapping in religionMappings) {
49+
foreach (var irReligionId in mapping.IrReligionIds) {
50+
if (!religionLookup.TryGetValue(irReligionId, out var list)) {
51+
list = new List<ReligionMapping>();
52+
religionLookup[irReligionId] = list;
53+
}
54+
list.Add(mapping);
55+
}
56+
}
57+
}
58+
4359
public string? Match(string irReligionId, string? ck3CultureId, ulong? ck3ProvinceId, ulong? irProvinceId, string? irHistoricalTag, Configuration config) {
44-
foreach (var religionMapping in religionMappings) {
60+
if (string.IsNullOrEmpty(irReligionId)) {
61+
return null;
62+
}
63+
64+
if (!religionLookup.TryGetValue(irReligionId, out var candidates)) {
65+
return null;
66+
}
67+
68+
foreach (var religionMapping in candidates) {
4569
var possibleMatch = religionMapping.Match(irReligionId, ck3CultureId, ck3ProvinceId, irProvinceId, irHistoricalTag, config, imperatorRegionMapper, ck3RegionMapper);
4670
if (possibleMatch is not null) {
4771
return possibleMatch;
@@ -57,6 +81,7 @@ private void RegisterKeys(Parser parser) {
5781
parser.IgnoreAndLogUnregisteredItems();
5882
}
5983
private readonly List<ReligionMapping> religionMappings = new();
84+
private readonly Dictionary<string, List<ReligionMapping>> religionLookup = new(StringComparer.Ordinal);
6085
private readonly ImperatorRegionMapper imperatorRegionMapper;
6186
private readonly CK3RegionMapper ck3RegionMapper;
6287
}

ImperatorToCK3/Mappers/Religion/ReligionMapping.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace ImperatorToCK3.Mappers.Religion;
66

77
internal sealed class ReligionMapping {
88
private readonly SortedSet<string> irReligionIds = [];
9+
public IReadOnlySet<string> IrReligionIds => irReligionIds;
910
public string? CK3FaithId { get; private set; }
1011
private readonly SortedSet<string> ck3CultureIds = [];
1112

ImperatorToCK3/Mappers/TagTitle/TagTitleMapper.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ public void RegisterGovernorship(string imperatorRegion, string imperatorCountry
9898
}
9999

100100
// Attempt a title match
101-
foreach (var mapping in titleMappings.ToArray()) {
101+
for (int i = 0; i < titleMappings.Count; ++i) {
102+
var mapping = titleMappings[i];
102103
var match = mapping.GovernorshipMatch(rank, titles, governorship, provMapper, irProvinces);
103104
if (match is null) {
104105
continue;
@@ -112,7 +113,9 @@ public void RegisterGovernorship(string imperatorRegion, string imperatorCountry
112113
// So, if the given title ID belongs to h_china de jure hierarchy, we skip it and remove the mapping.
113114
if (titles.TryGetValue(match, out var ck3Title) && ck3Title.GetDeJureLiegeOfRank(TitleRank.hegemony)?.Id == "h_china") {
114115
Logger.Debug($"Governorship title {match} belongs to h_china de jure hierarchy! Skipping mapping for governorship in region {governorship.Region.Id} of country {country.Tag}.");
115-
titleMappings.Remove(mapping);
116+
titleMappings.RemoveAt(i);
117+
// move back one index so we don't skip the element that shifted into this slot
118+
--i;
116119
continue;
117120
}
118121

@@ -298,7 +301,7 @@ private static string GetTitlePrefixForRank(TitleRank titleRank) {
298301
private readonly List<TitleMapping> titleMappings = new();
299302
private readonly Dictionary<ulong, string> registeredCountryTitles = new(); // We store already mapped countries here.
300303
private readonly Dictionary<string, string> registeredGovernorshipTitles = new(); // We store already mapped governorships here.
301-
private readonly SortedSet<string> usedTitles = new();
304+
private readonly HashSet<string> usedTitles = new(StringComparer.Ordinal);
302305

303306
private readonly HashSet<string> hegemonyKeywords = [];
304307
private readonly HashSet<string> empireKeywords = ["empire"];

0 commit comments

Comments
 (0)