forked from ad-freiburg/qlever
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a Strong Type for Memory Sizes (ad-freiburg#1032)
Add a class `ad_utility::MemorySize` that stores an amount of memory in bytes in a strongly typed manner. It can be parsed from strings (e.g. "4 kB" or "8.3 GB") and set from user defined literals (`4.34_GB` etc.). This commit does not yet use the `MemorySize`, but this is left for following PRs.
- Loading branch information
Showing
19 changed files
with
1,681 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
add_library(memorySize MemorySize.cpp | ||
generated/MemorySizeLanguageLexer.cpp | ||
generated/MemorySizeLanguageParser.cpp MemorySizeParser.cpp) | ||
qlever_target_link_libraries(memorySize antlr4_static util) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright 2022, University of Freiburg, | ||
// Chair of Algorithms and Data Structures. | ||
// Author: Andre Schlegel (July of 2023, | ||
// [email protected]) | ||
|
||
#include "util/MemorySize/MemorySize.h" | ||
|
||
#include <absl/strings/str_cat.h> | ||
|
||
#include <cinttypes> | ||
#include <ranges> | ||
#include <string_view> | ||
|
||
#include "util/Cache.h" | ||
#include "util/ConstexprMap.h" | ||
#include "util/ConstexprUtils.h" | ||
#include "util/Exception.h" | ||
#include "util/HashMap.h" | ||
#include "util/MemorySize/MemorySizeParser.h" | ||
#include "util/MemorySize/generated/MemorySizeLanguageLexer.h" | ||
#include "util/MemorySize/generated/MemorySizeLanguageParser.h" | ||
|
||
namespace ad_utility { | ||
// _____________________________________________________________________________ | ||
std::string MemorySize::asString() const { | ||
// Convert number and memory unit name to the string, we want to return. | ||
auto toString = [](const auto number, std::string_view unitName) { | ||
return absl::StrCat(number, " ", unitName); | ||
}; | ||
|
||
/* | ||
Choosing the memory unit type is done by choosing the unit type, in which | ||
range `memoryInBytes_` is contained. | ||
A memory unit type normally has the range `[hisSize, | ||
sizeOfTheNextBiggerUnit)`. | ||
Only exceptions are: | ||
- `TB`, which has no upper bound, because it's our biggest unit. | ||
- `kB`, which has the lower bound `100'000` instead of `1'000`. Typically, for | ||
such small sizes you still want the exact value because they mean something | ||
,e.g. a block size or a page size etc.. | ||
*/ | ||
constexpr ad_utility::ConstexprMap<char, size_t, 4> memoryUnitLowerBound( | ||
{std::pair<char, size_t>{'k', ad_utility::pow(10, 5)}, | ||
std::pair<char, size_t>{'M', detail::numBytesPerUnit.at("MB")}, | ||
std::pair<char, size_t>{'G', detail::numBytesPerUnit.at("GB")}, | ||
std::pair<char, size_t>{'T', detail::numBytesPerUnit.at("TB")}}); | ||
|
||
// Go through the units from top to bottom, in terms of size, and choose the | ||
// first one, that is smaller/equal to `memoryInBytes_`. | ||
if (memoryInBytes_ >= memoryUnitLowerBound.at('T')) { | ||
return toString(getTerabytes(), "TB"); | ||
} else if (memoryInBytes_ >= memoryUnitLowerBound.at('G')) { | ||
return toString(getGigabytes(), "GB"); | ||
} else if (memoryInBytes_ >= memoryUnitLowerBound.at('M')) { | ||
return toString(getMegabytes(), "MB"); | ||
} else if (memoryInBytes_ >= memoryUnitLowerBound.at('k')) { | ||
return toString(getKilobytes(), "kB"); | ||
} else { | ||
// Just return the amount of bytes. | ||
return toString(memoryInBytes_, "B"); | ||
} | ||
} | ||
|
||
// _____________________________________________________________________________ | ||
MemorySize MemorySize::parse(std::string_view str) { | ||
return MemorySizeParser::parseMemorySize(str); | ||
} | ||
|
||
// _____________________________________________________________________________ | ||
std::ostream& operator<<(std::ostream& os, const ad_utility::MemorySize& mem) { | ||
os << mem.asString(); | ||
return os; | ||
} | ||
|
||
} // namespace ad_utility |
Oops, something went wrong.