Skip to content

Commit 77ab07e

Browse files
committed
Greatly improved db2 loading time
1 parent 1521cb2 commit 77ab07e

File tree

3 files changed

+96
-101
lines changed

3 files changed

+96
-101
lines changed

WowPacketParser/DBC/DBC.cs

Lines changed: 89 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ private static string GetHotfixCachePath()
5353
return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Settings.HotfixCachePath);
5454
}
5555

56-
public static async void Load()
56+
public static async Task Load()
5757
{
5858
if (!Directory.Exists(GetDBCPath()))
5959
{
@@ -77,7 +77,7 @@ public static async void Load()
7777
Trace.WriteLine("File name LoadTime Record count");
7878
Trace.WriteLine("---------------------------------------------------------------------");
7979

80-
Parallel.ForEach(typeof(DBC).GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), dbc =>
80+
await Task.WhenAll(typeof(DBC).GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Select(dbc => Task.Run(() =>
8181
{
8282
Type type = dbc.PropertyType.GetGenericArguments()[0];
8383

@@ -89,15 +89,14 @@ public static async void Load()
8989
if (attr == null)
9090
return;
9191

92-
var times = new List<long>();
93-
var instanceType = typeof(Storage<>).MakeGenericType(type);
92+
var instanceType = dbc.PropertyType;
9493
var countGetter = instanceType.GetProperty("Count").GetGetMethod();
95-
dynamic instance = Activator.CreateInstance(instanceType, $"{ GetDBCPath(attr.FileName) }.db2");
96-
var recordCount = (int)countGetter.Invoke(instance, new object[] { });
94+
dynamic instance = Activator.CreateInstance(instanceType, $"{GetDBCPath(attr.FileName)}.db2");
95+
var recordCount = (int)countGetter.Invoke(instance, Array.Empty<object>());
9796

9897
try
9998
{
100-
var db2Reader = new DBReader($"{ GetDBCPath(attr.FileName) }.db2");
99+
var db2Reader = new DBReader($"{GetDBCPath(attr.FileName)}.db2");
101100

102101
if (hotfixReader != null)
103102
hotfixReader.ApplyHotfixes(instance, db2Reader);
@@ -107,115 +106,117 @@ public static async void Load()
107106
catch (TargetInvocationException tie)
108107
{
109108
if (tie.InnerException is ArgumentException)
110-
throw new ArgumentException($"Failed to load {attr.FileName}.db2: {tie.InnerException.Message}");
109+
throw new ArgumentException(
110+
$"Failed to load {attr.FileName}.db2: {tie.InnerException.Message}");
111111
throw;
112112
}
113113

114114
var endTime = DateTime.Now;
115115
var span = endTime.Subtract(startTime);
116116

117-
Trace.WriteLine($"{ attr.FileName.PadRight(33) } { TimeSpan.FromTicks(span.Ticks).ToString().PadRight(28) } { recordCount.ToString().PadRight(19) }");
118-
});
117+
Trace.WriteLine($"{attr.FileName,-33} {span,-28} {recordCount,-19}");
118+
})));
119119

120120
await Task.WhenAll(Task.Run(() =>
121121
{
122-
if (AreaTable != null)
123-
foreach (var db2Info in AreaTable)
124-
{
125-
if (db2Info.Value.ParentAreaID != 0 && !Zones.ContainsKey(db2Info.Value.ParentAreaID))
126-
Zones.Add(db2Info.Value.ParentAreaID, db2Info.Value.ZoneName);
127-
}
122+
if (AreaTable == null)
123+
return;
124+
125+
foreach (var db2Info in AreaTable)
126+
if (db2Info.Value.ParentAreaID != 0 && !Zones.ContainsKey(db2Info.Value.ParentAreaID))
127+
Zones.Add(db2Info.Value.ParentAreaID, db2Info.Value.ZoneName);
128128
}), Task.Run(() =>
129129
{
130-
if (MapDifficulty != null)
131-
{
132-
foreach (var mapDifficulty in MapDifficulty)
133-
{
134-
int difficultyID = 1 << mapDifficulty.Value.DifficultyID;
135-
136-
if (MapSpawnMaskStores.ContainsKey(mapDifficulty.Value.MapID))
137-
MapSpawnMaskStores[mapDifficulty.Value.MapID] |= difficultyID;
138-
else
139-
MapSpawnMaskStores.Add(mapDifficulty.Value.MapID, difficultyID);
130+
if (MapDifficulty == null)
131+
return;
140132

141-
if (!MapDifficultyStores.ContainsKey(mapDifficulty.Value.MapID))
142-
MapDifficultyStores.Add(mapDifficulty.Value.MapID, new List<int>() { mapDifficulty.Value.DifficultyID });
143-
else
144-
MapDifficultyStores[mapDifficulty.Value.MapID].Add(mapDifficulty.Value.DifficultyID);
145-
}
133+
foreach (var mapDifficulty in MapDifficulty)
134+
{
135+
if (!MapDifficultyStores.TryGetValue(mapDifficulty.Value.MapID, out var difficulty))
136+
MapDifficultyStores.Add(mapDifficulty.Value.MapID, [mapDifficulty.Value.DifficultyID]);
137+
else
138+
difficulty.Add(mapDifficulty.Value.DifficultyID);
146139
}
147140
}), Task.Run(() =>
148141
{
149-
if (CriteriaTree != null && Achievement != null)
142+
if (CriteriaTree == null || Achievement == null)
143+
return;
144+
145+
var achievements = Achievement.Select(kvp => kvp.Value)
146+
.Where(achievement => achievement.CriteriaTree != 0)
147+
.GroupBy(achievement => achievement.CriteriaTree)
148+
.ToDictionary(
149+
group => group.Key,
150+
group => string.Join(' ', group.Select(achiev => $"AchievementID: {achiev.ID} Description: \"{achiev.Description}\"")));
151+
152+
foreach (var criteriaTree in CriteriaTree)
150153
{
151-
ICollection<AchievementEntry> achievementLists = Achievement.Values;
152-
var achievements = achievementLists.GroupBy(achievement => achievement.CriteriaTree)
153-
.ToDictionary(group => group.Key, group => group.ToList());
154+
if (criteriaTree.Value.CriteriaID == 0)
155+
continue;
156+
157+
string result = "";
158+
uint criteriaTreeID = criteriaTree.Value.Parent > 0 ? criteriaTree.Value.Parent : (uint)criteriaTree.Key;
159+
160+
if (achievements.TryGetValue(criteriaTreeID, out var achievementList))
161+
result += achievementList;
154162

155-
foreach (var criteriaTree in CriteriaTree)
163+
if (!CriteriaStores.ContainsKey((ushort)criteriaTree.Value.CriteriaID))
156164
{
157-
string result = "";
158-
uint criteriaTreeID = criteriaTree.Value.Parent > 0 ? criteriaTree.Value.Parent : (uint)criteriaTree.Key;
159-
160-
List<AchievementEntry> achievementList;
161-
if (achievements.TryGetValue(criteriaTreeID, out achievementList))
162-
foreach (var achievement in achievementList)
163-
result = $"AchievementID: {achievement.ID} Description: \"{ achievement.Description }\"";
164-
165-
if (!CriteriaStores.ContainsKey((ushort)criteriaTree.Value.CriteriaID))
166-
{
167-
if (criteriaTree.Value.Description != string.Empty)
168-
result += $" - CriteriaDescription: \"{criteriaTree.Value.Description }\"";
169-
170-
CriteriaStores.Add((ushort)criteriaTree.Value.CriteriaID, result);
171-
}
172-
else
173-
CriteriaStores[(ushort)criteriaTree.Value.CriteriaID] += $" / CriteriaDescription: \"{ criteriaTree.Value.Description }\"";
165+
if (criteriaTree.Value.Description != string.Empty)
166+
result += $" - CriteriaDescription: \"{criteriaTree.Value.Description }\"";
167+
168+
CriteriaStores.Add((ushort)criteriaTree.Value.CriteriaID, result);
174169
}
170+
else
171+
CriteriaStores[(ushort)criteriaTree.Value.CriteriaID] += $" / CriteriaDescription: \"{ criteriaTree.Value.Description }\"";
175172
}
176173
}), Task.Run(() =>
177174
{
178-
if (Faction != null && FactionTemplate != null)
179-
{
180-
foreach (var factionTemplate in FactionTemplate)
181-
{
182-
if (Faction.ContainsKey(factionTemplate.Value.Faction))
183-
FactionStores.Add((uint)factionTemplate.Key, Faction[factionTemplate.Value.Faction]);
184-
}
185-
}
175+
if (Faction == null || FactionTemplate == null)
176+
return;
177+
178+
foreach (var factionTemplate in FactionTemplate)
179+
if (Faction.TryGetValue(factionTemplate.Value.Faction, out var faction))
180+
FactionStores.Add((uint)factionTemplate.Key, faction);
186181
}), Task.Run(() =>
187182
{
188-
if (SpellEffect != null)
189-
foreach (var effect in SpellEffect)
190-
{
191-
var tuple = Tuple.Create((uint)effect.Value.SpellID, (uint)effect.Value.EffectIndex);
192-
SpellEffectStores[tuple] = effect.Value;
193-
}
183+
if (SpellEffect == null)
184+
return;
185+
186+
foreach (var effect in SpellEffect)
187+
{
188+
var tuple = Tuple.Create((uint)effect.Value.SpellID, (uint)effect.Value.EffectIndex);
189+
SpellEffectStores[tuple] = effect.Value;
190+
}
194191
}), Task.Run(() =>
195192
{
196-
if (PhaseXPhaseGroup != null)
197-
foreach (var phase in PhaseXPhaseGroup)
198-
{
199-
if (!PhasesByGroup.TryGetValue(phase.Value.PhaseGroupID, out var phases))
200-
PhasesByGroup.Add(phase.Value.PhaseGroupID, [phase.Value.PhaseID]);
201-
else
202-
phases.Add(phase.Value.PhaseID);
203-
204-
if (!PhaseGroupsByPhase.TryGetValue(phase.Value.PhaseID, out var phaseGroups))
205-
PhaseGroupsByPhase.Add(phase.Value.PhaseID, [phase.Value.PhaseGroupID]);
206-
else
207-
phaseGroups.Add(phase.Value.PhaseGroupID);
208-
}
193+
if (PhaseXPhaseGroup == null)
194+
return;
195+
196+
foreach (var phase in PhaseXPhaseGroup)
197+
{
198+
if (!PhasesByGroup.TryGetValue(phase.Value.PhaseGroupID, out var phases))
199+
PhasesByGroup.Add(phase.Value.PhaseGroupID, [phase.Value.PhaseID]);
200+
else
201+
phases.Add(phase.Value.PhaseID);
202+
203+
if (!PhaseGroupsByPhase.TryGetValue(phase.Value.PhaseID, out var phaseGroups))
204+
PhaseGroupsByPhase.Add(phase.Value.PhaseID, [phase.Value.PhaseGroupID]);
205+
else
206+
phaseGroups.Add(phase.Value.PhaseGroupID);
207+
}
209208
}), Task.Run(() =>
210209
{
211-
if (BroadcastTextDuration != null)
212-
foreach (var broadcastTextDuration in BroadcastTextDuration)
213-
{
214-
if (!BroadcastTextDurations.ContainsKey(broadcastTextDuration.Value.BroadcastTextID))
215-
BroadcastTextDurations.Add(broadcastTextDuration.Value.BroadcastTextID, [broadcastTextDuration.Value.Locale]);
216-
else
217-
BroadcastTextDurations[broadcastTextDuration.Value.BroadcastTextID].Add(broadcastTextDuration.Value.Locale);
218-
}
210+
if (BroadcastTextDuration == null)
211+
return;
212+
213+
foreach (var broadcastTextDuration in BroadcastTextDuration)
214+
{
215+
if (!BroadcastTextDurations.TryGetValue(broadcastTextDuration.Value.BroadcastTextID, out var durations))
216+
BroadcastTextDurations.Add(broadcastTextDuration.Value.BroadcastTextID, [broadcastTextDuration.Value.Locale]);
217+
else
218+
durations.Add(broadcastTextDuration.Value.Locale);
219+
}
219220
}));
220221
}
221222

@@ -241,7 +242,6 @@ public static uint GetEmptyAnimStateID()
241242
}
242243

243244
public static readonly Dictionary<uint, string> Zones = new Dictionary<uint, string>();
244-
public static readonly Dictionary<int, int> MapSpawnMaskStores = new Dictionary<int, int>();
245245
public static readonly Dictionary<int, List<int>> MapDifficultyStores = new Dictionary<int, List<int>>();
246246
public static readonly Dictionary<ushort, string> CriteriaStores = new Dictionary<ushort, string>();
247247
public static readonly Dictionary<uint, FactionEntry> FactionStores = new Dictionary<uint, FactionEntry>();

WowPacketParser/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ private static void Main(string[] args)
6363
{
6464
var startTime = DateTime.Now;
6565

66-
DBC.DBC.Load();
66+
DBC.DBC.Load().Wait();
6767

6868
var span = DateTime.Now.Subtract(startTime);
6969
Trace.WriteLine($"DBC loaded in { span.ToFormattedString() }.");

WowPacketParser/Store/Objects/WoWObject.cs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.Linq;
23
using WowPacketParser.Enums;
34
using WowPacketParser.Misc;
45
using WowPacketParser.Proto;
@@ -86,24 +87,18 @@ public int GetDefaultSpawnMask()
8687
{
8788
// 3 is the most common spawnmask outside of continents although it is not correct in all cases
8889
// TODO: read map/instance db to guess correct spawnmask
89-
if (Settings.UseDBC && DBC.DBC.MapSpawnMaskStores != null)
90-
{
91-
if (DBC.DBC.MapSpawnMaskStores.ContainsKey((int)Map))
92-
return DBC.DBC.MapSpawnMaskStores[(int)Map];
93-
}
90+
if (Settings.UseDBC && DBC.DBC.MapDifficultyStores.TryGetValue((int)Map, out var difficultyIds))
91+
return difficultyIds.Aggregate(0, (a, b) => a | (1 << b));
9492

9593
return MapIsContinent(Map) ? 1 : 3;
9694
}
9795

9896
public List<int> GetDefaultSpawnDifficulties()
9997
{
100-
if (Settings.UseDBC && DBC.DBC.MapDifficultyStores != null)
101-
{
102-
if (DBC.DBC.MapDifficultyStores.ContainsKey((int)Map))
103-
return DBC.DBC.MapDifficultyStores[(int)Map];
104-
}
98+
if (Settings.UseDBC && DBC.DBC.MapDifficultyStores.TryGetValue((int)Map, out var difficultyIds))
99+
return difficultyIds;
105100

106-
return new List<int>();
101+
return [];
107102
}
108103

109104
private static bool MapIsContinent(uint mapId)

0 commit comments

Comments
 (0)