Skip to content

Commit

Permalink
std::unordered_map -> tsl::sparse_map
Browse files Browse the repository at this point in the history
A couple of minor changes are needed to work around constness issues
in tsl::sparse_map:

1. Tessil/sparse-map#20
2. Tessil/sparse-map#21

Memory savings example, Spanish translations map:
296 KiB -> 263 KiB (-33 KiB)

RG99 binary size: +36 KiB
  • Loading branch information
glebm committed Jan 16, 2023
1 parent 220dd34 commit e4216ae
Show file tree
Hide file tree
Showing 11 changed files with 51 additions and 44 deletions.
4 changes: 2 additions & 2 deletions Source/debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ bool DebugToggle = false;
bool DebugGodMode = false;
bool DebugVision = false;
bool DebugGrid = false;
std::unordered_map<int, Point> DebugCoordsMap;
tsl::sparse_map<int, Point> DebugCoordsMap;
bool DebugScrollViewEnabled = false;
std::string debugTRN;

Expand Down Expand Up @@ -366,7 +366,7 @@ std::string ExportDun(const string_view parameter)
return StrCat(levelName, " saved. Happy mapping!");
}

std::unordered_map<string_view, _talker_id> TownerShortNameToTownerId = {
tsl::sparse_map<string_view, _talker_id> TownerShortNameToTownerId = {
{ "griswold", _talker_id::TOWN_SMITH },
{ "pepin", _talker_id::TOWN_HEALER },
{ "ogden", _talker_id::TOWN_TAVERN },
Expand Down
4 changes: 2 additions & 2 deletions Source/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
#pragma once

#include <unordered_map>
#include <tsl/sparse_map.h>

#include "engine.h"
#include "engine/clx_sprite.hpp"
Expand All @@ -19,7 +19,7 @@ extern bool DebugToggle;
extern bool DebugGodMode;
extern bool DebugVision;
extern bool DebugGrid;
extern std::unordered_map<int, Point> DebugCoordsMap;
extern tsl::sparse_map<int, Point> DebugCoordsMap;
extern bool DebugScrollViewEnabled;
extern std::string debugTRN;

Expand Down
2 changes: 1 addition & 1 deletion Source/engine/render/dun_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,7 @@ void RenderBlackTileFull(uint8_t *DVL_RESTRICT dst, uint16_t dstPitch)
} // namespace

#ifdef DUN_RENDER_STATS
std::unordered_map<DunRenderType, size_t, DunRenderTypeHash> DunRenderStats;
tsl::sparse_map<DunRenderType, size_t, DunRenderTypeHash> DunRenderStats;

string_view TileTypeToString(TileType tileType)
{
Expand Down
4 changes: 2 additions & 2 deletions Source/engine/render/dun_render.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

// #define DUN_RENDER_STATS
#ifdef DUN_RENDER_STATS
#include <unordered_map>
#include <tsl/sparse_map.h>
#endif

namespace devilution {
Expand Down Expand Up @@ -249,7 +249,7 @@ struct DunRenderTypeHash {
return std::hash<uint32_t> {}((1 < static_cast<uint8_t>(t.tileType)) | static_cast<uint8_t>(t.maskType));
}
};
extern std::unordered_map<DunRenderType, size_t, DunRenderTypeHash> DunRenderStats;
extern tsl::sparse_map<DunRenderType, size_t, DunRenderTypeHash> DunRenderStats;

string_view TileTypeToString(TileType tileType);

Expand Down
18 changes: 9 additions & 9 deletions Source/engine/render/text_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

#include <array>
#include <cstddef>
#include <unordered_map>
#include <utility>

#include <fmt/compile.h>
#include <tsl/sparse_map.h>

#include "DiabloUI/diabloui.h"
#include "DiabloUI/ui_item.h"
Expand All @@ -37,9 +37,9 @@ namespace {
constexpr char32_t ZWSP = U'\u200B'; // Zero-width space

using Font = const OwnedClxSpriteList;
std::unordered_map<uint32_t, OptionalOwnedClxSpriteList> Fonts;
tsl::sparse_map<uint32_t, OptionalOwnedClxSpriteList> Fonts;

std::unordered_map<uint32_t, std::array<uint8_t, 256>> FontKerns;
tsl::sparse_map<uint32_t, std::array<uint8_t, 256>> FontKerns;
std::array<int, 6> FontSizes = { 12, 24, 30, 42, 46, 22 };
std::array<uint8_t, 6> CJKWidth = { 17, 24, 28, 41, 47, 16 };
std::array<uint8_t, 6> HangulWidth = { 15, 20, 24, 35, 39, 15 };
Expand Down Expand Up @@ -148,7 +148,7 @@ uint32_t GetFontId(GameFontTables size, uint16_t row)
return (size << 16) | row;
}

std::array<uint8_t, 256> *LoadFontKerning(GameFontTables size, uint16_t row)
const std::array<uint8_t, 256> *LoadFontKerning(GameFontTables size, uint16_t row)
{
uint32_t fontId = GetFontId(size, row);

Expand Down Expand Up @@ -389,7 +389,7 @@ uint32_t DoDrawString(const Surface &out, string_view text, Rectangle rect, Poin
UiFlags flags, GameFontTables size, text_color color, bool outline)
{
Font *font = nullptr;
std::array<uint8_t, 256> *kerning = nullptr;
const std::array<uint8_t, 256> *kerning = nullptr;
uint32_t currentUnicodeRow = 0;

char32_t next;
Expand Down Expand Up @@ -451,7 +451,7 @@ int GetLineWidth(string_view text, GameFontTables size, int spacing, int *charac

uint32_t codepoints = 0;
uint32_t currentUnicodeRow = 0;
std::array<uint8_t, 256> *kerning = nullptr;
const std::array<uint8_t, 256> *kerning = nullptr;
char32_t next;
while (!text.empty()) {
next = ConsumeFirstUtf8CodePoint(&text);
Expand Down Expand Up @@ -484,7 +484,7 @@ int GetLineWidth(string_view fmt, DrawStringFormatArg *args, std::size_t argsLen

uint32_t codepoints = 0;
uint32_t currentUnicodeRow = 0;
std::array<uint8_t, 256> *kerning = nullptr;
const std::array<uint8_t, 256> *kerning = nullptr;
char32_t prev = U'\0';
char32_t next;

Expand Down Expand Up @@ -563,7 +563,7 @@ std::string WordWrapString(string_view text, unsigned width, GameFontTables size
bool lastBreakableKeep = false;
uint32_t currentUnicodeRow = 0;
unsigned lineWidth = 0;
std::array<uint8_t, 256> *kerning = nullptr;
const std::array<uint8_t, 256> *kerning = nullptr;

char32_t codepoint = U'\0'; // the current codepoint
char32_t nextCodepoint; // the next codepoint
Expand Down Expand Up @@ -717,7 +717,7 @@ void DrawStringWithColors(const Surface &out, string_view fmt, DrawStringFormatA
const Surface clippedOut = ClipSurface(out, rect);

Font *font = nullptr;
std::array<uint8_t, 256> *kerning = nullptr;
const std::array<uint8_t, 256> *kerning = nullptr;

char32_t prev = U'\0';
char32_t next;
Expand Down
3 changes: 2 additions & 1 deletion Source/engine/trn.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "engine/trn.hpp"

#include <fmt/format.h>
#include <unordered_map>

#ifdef _DEBUG
#include "debug.h"
Expand Down
8 changes: 4 additions & 4 deletions Source/loadsave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
#include <climits>
#include <cstring>
#include <numeric>
#include <unordered_map>

#include <SDL.h>
#include <fmt/compile.h>
#include <tsl/sparse_map.h>

#include "automap.h"
#include "codec.h"
Expand Down Expand Up @@ -1616,15 +1616,15 @@ void SavePortal(SaveHelper *file, int i)
* @return a map converting from runtime item indexes to the relative position in the save file, used by SaveDroppedItemLocations
* @see SaveDroppedItemLocations
*/
std::unordered_map<uint8_t, uint8_t> SaveDroppedItems(SaveHelper &file)
tsl::sparse_map<uint8_t, uint8_t> SaveDroppedItems(SaveHelper &file)
{
// Vanilla Diablo/Hellfire initialise the ActiveItems and AvailableItems arrays based on saved data, so write valid values for compatibility
for (uint8_t i = 0; i < MAXITEMS; i++)
file.WriteLE<uint8_t>(i); // Strictly speaking everything from ActiveItemCount onwards is unused but no harm writing non-zero values here.
for (uint8_t i = 0; i < MAXITEMS; i++)
file.WriteLE<uint8_t>((i + ActiveItemCount) % MAXITEMS);

std::unordered_map<uint8_t, uint8_t> itemIndexes = { { 0, 0 } };
tsl::sparse_map<uint8_t, uint8_t> itemIndexes = { { 0, 0 } };
for (uint8_t i = 0; i < ActiveItemCount; i++) {
itemIndexes[ActiveItems[i] + 1] = i + 1;
SaveItem(file, Items[ActiveItems[i]]);
Expand All @@ -1637,7 +1637,7 @@ std::unordered_map<uint8_t, uint8_t> SaveDroppedItems(SaveHelper &file)
* @param file interface to the save file
* @param itemIndexes a map converting from runtime item indexes to the relative position in the save file
*/
void SaveDroppedItemLocations(SaveHelper &file, const std::unordered_map<uint8_t, uint8_t> &itemIndexes)
void SaveDroppedItemLocations(SaveHelper &file, const tsl::sparse_map<uint8_t, uint8_t> &itemIndexes)
{
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
Expand Down
26 changes: 14 additions & 12 deletions Source/msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#include <climits>
#include <list>
#include <memory>
#include <unordered_map>

#include <fmt/format.h>
#include <tsl/sparse_map.h>

#include "DiabloUI/diabloui.h"
#include "automap.h"
Expand Down Expand Up @@ -173,7 +173,7 @@ struct DObjectStr {

struct DLevel {
TCmdPItem item[MAXITEMS];
std::unordered_map<WorldTilePosition, DObjectStr> object;
tsl::sparse_map<WorldTilePosition, DObjectStr> object;
DMonsterStr monster[MaxMonsters];
};

Expand Down Expand Up @@ -213,14 +213,14 @@ constexpr size_t MAX_CHUNKS = MAX_MULTIPLAYERLEVELS + 4;
uint32_t sgdwOwnerWait;
uint32_t sgdwRecvOffset;
int sgnCurrMegaPlayer;
std::unordered_map<uint8_t, DLevel> DeltaLevels;
tsl::sparse_map<uint8_t, DLevel> DeltaLevels;
uint8_t sbLastCmd;
/**
* @brief buffer used to receive level deltas, size is the worst expected case assuming every object on a level was touched
*/
byte sgRecvBuf[1U + sizeof(DLevel::item) + sizeof(uint8_t) + (sizeof(WorldTilePosition) + sizeof(_cmd_id)) * MAXOBJECTS + sizeof(DLevel::monster)];
_cmd_id sgbRecvCmd;
std::unordered_map<uint8_t, LocalLevel> LocalLevels;
tsl::sparse_map<uint8_t, LocalLevel> LocalLevels;
DJunk sgJunk;
bool sgbDeltaChanged;
uint8_t sgbDeltaChunks;
Expand All @@ -240,10 +240,12 @@ uint8_t GetLevelForMultiplayer(uint8_t level, bool isSetLevel)
/** @brief Gets a delta level. */
DLevel &GetDeltaLevel(uint8_t level)
{
auto keyIt = DeltaLevels.find(level);
tsl::sparse_map<uint8_t, DLevel>::iterator keyIt = DeltaLevels.find(level);
if (keyIt != DeltaLevels.end())
return keyIt->second;
DLevel &deltaLevel = DeltaLevels[level];
return keyIt.value();
auto emplaceRet = DeltaLevels.emplace(level, DLevel {});
assert(emplaceRet.second);
DLevel &deltaLevel = emplaceRet.first.value();
memset(&deltaLevel.item, 0xFF, sizeof(deltaLevel.item));
memset(&deltaLevel.monster, 0xFF, sizeof(deltaLevel.monster));
return deltaLevel;
Expand Down Expand Up @@ -456,7 +458,7 @@ size_t DeltaImportItem(const byte *src, TCmdPItem *dst)
return size;
}

byte *DeltaExportObject(byte *dst, const std::unordered_map<WorldTilePosition, DObjectStr> &src)
byte *DeltaExportObject(byte *dst, const tsl::sparse_map<WorldTilePosition, DObjectStr> &src)
{
*dst++ = static_cast<byte>(src.size());
for (auto &pair : src) {
Expand All @@ -468,7 +470,7 @@ byte *DeltaExportObject(byte *dst, const std::unordered_map<WorldTilePosition, D
return dst;
}

const byte *DeltaImportObjects(const byte *src, std::unordered_map<WorldTilePosition, DObjectStr> &dst)
const byte *DeltaImportObjects(const byte *src, tsl::sparse_map<WorldTilePosition, DObjectStr> &dst)
{
dst.clear();

Expand Down Expand Up @@ -2606,8 +2608,8 @@ void run_delta_info()
void DeltaExportData(int pnum)
{
if (sgbDeltaChanged) {
for (auto &it : DeltaLevels) {
DLevel &deltaLevel = it.second;
for (auto it = DeltaLevels.begin(), end = DeltaLevels.end(); it != end; ++it) {
DLevel &deltaLevel = it.value();

const size_t bufferSize = 1U /* marker byte, always 0 */
+ sizeof(uint8_t) /* level id */
Expand All @@ -2618,7 +2620,7 @@ void DeltaExportData(int pnum)
std::unique_ptr<byte[]> dst { new byte[bufferSize] };

byte *dstEnd = &dst.get()[1];
*dstEnd = static_cast<byte>(it.first);
*dstEnd = static_cast<byte>(it.key());
dstEnd += sizeof(uint8_t);
dstEnd = DeltaExportItem(dstEnd, deltaLevel.item);
dstEnd = DeltaExportObject(dstEnd, deltaLevel.object);
Expand Down
10 changes: 5 additions & 5 deletions Source/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#include <cstddef>
#include <cstdint>
#include <forward_list>
#include <unordered_map>

#include <SDL_version.h>
#include <tsl/sparse_map.h>

#include "controls/controller.h"
#include "controls/controller_buttons.h"
Expand Down Expand Up @@ -685,9 +685,9 @@ struct KeymapperOptions : OptionCategoryBase {

private:
std::forward_list<Action> actions;
std::unordered_map<uint32_t, std::reference_wrapper<Action>> keyIDToAction;
std::unordered_map<uint32_t, std::string> keyIDToKeyName;
std::unordered_map<std::string, uint32_t> keyNameToKeyID;
tsl::sparse_map<uint32_t, std::reference_wrapper<Action>> keyIDToAction;
tsl::sparse_map<uint32_t, std::string> keyIDToKeyName;
tsl::sparse_map<std::string, uint32_t> keyNameToKeyID;
};

/** The Padmapper maps gamepad buttons to actions. */
Expand Down Expand Up @@ -755,7 +755,7 @@ struct PadmapperOptions : OptionCategoryBase {
std::forward_list<Action> actions;
std::array<const Action *, enum_size<ControllerButton>::value> buttonToReleaseAction;
std::array<std::string, enum_size<ControllerButton>::value> buttonToButtonName;
std::unordered_map<std::string, ControllerButton> buttonNameToButton;
tsl::sparse_map<std::string, ControllerButton> buttonNameToButton;
bool committed = false;

const Action *FindAction(ControllerButton button) const;
Expand Down
8 changes: 4 additions & 4 deletions Source/pfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

#include <sstream>
#include <string>
#include <unordered_map>

#include <fmt/compile.h>
#include <tsl/sparse_map.h>

#include "codec.h"
#include "engine.h"
Expand Down Expand Up @@ -246,7 +246,7 @@ inline bool string_ends_with(std::string const &value, std::string const &ending
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}

void CreateDetailDiffs(string_view prefix, string_view memoryMapFile, CompareInfo &compareInfoReference, CompareInfo &compareInfoActual, std::unordered_map<std::string, size_t> &foundDiffs)
void CreateDetailDiffs(string_view prefix, string_view memoryMapFile, CompareInfo &compareInfoReference, CompareInfo &compareInfoActual, tsl::sparse_map<std::string, size_t> &foundDiffs)
{
// Note: Detail diffs are currently only supported in unit tests
std::string memoryMapFileAssetName = StrCat(paths::BasePath(), "/test/fixtures/memory_map/", memoryMapFile, ".txt");
Expand All @@ -264,7 +264,7 @@ void CreateDetailDiffs(string_view prefix, string_view memoryMapFile, CompareInf
MemoryBuffer buffer(reinterpret_cast<char *>(memoryMapFileData.get()), readBytes);
std::istream reader(&buffer);

std::unordered_map<std::string, CompareCounter> counter;
tsl::sparse_map<std::string, CompareCounter> counter;

auto getCounter = [&](const std::string &counterAsString) {
auto it = counter.find(counterAsString);
Expand Down Expand Up @@ -450,7 +450,7 @@ HeroCompareResult CompareSaves(const std::string &actualSavePath, const std::str
StrAppend(message, "file \"", compareTarget.fileName, "\" has different content.");
if (!logDetails)
continue;
std::unordered_map<std::string, size_t> foundDiffs;
tsl::sparse_map<std::string, size_t> foundDiffs;
CompareInfo compareInfoReference = { fileDataReference, 0, fileSizeReference, compareTarget.isTownLevel, fileSizeReference != 0 };
CompareInfo compareInfoActual = { fileDataActual, 0, fileSizeActual, compareTarget.isTownLevel, fileSizeActual != 0 };
CreateDetailDiffs(compareTarget.fileName, compareTarget.memoryMapFileName, compareInfoReference, compareInfoActual, foundDiffs);
Expand Down
8 changes: 6 additions & 2 deletions Source/utils/language.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "utils/language.h"

#include <memory>
#include <unordered_map>
#include <vector>

#include <function_ref.hpp>
#include <tsl/sparse_map.h>

#include "engine/assets.hpp"
#include "options.h"
Expand Down Expand Up @@ -49,7 +49,11 @@ struct StringEq {
}
};

std::vector<std::unordered_map<const char *, TranslationRef, StringHash, StringEq>> translation = { {}, {} };
std::vector<
tsl::sparse_map<const char *, TranslationRef, StringHash, StringEq,
std::allocator<std::pair<const char *, TranslationRef>>, tsl::sh::power_of_two_growth_policy<2>, tsl::sh::exception_safety::basic,
tsl::sh::sparsity::high>>
translation = { {}, {} };

constexpr uint32_t TranslationRefOffsetBits = 19;
constexpr uint32_t TranslationRefSizeBits = 32 - TranslationRefOffsetBits; // 13
Expand Down

0 comments on commit e4216ae

Please sign in to comment.