Caching of spine item sizes for faster book loading (saves 1-4 seconds).

This commit is contained in:
Jonas Diemer 2025-12-18 11:09:05 +01:00
parent 063a1df851
commit 1a14b371fe
2 changed files with 45 additions and 12 deletions

View File

@ -148,21 +148,53 @@ bool Epub::load() {
return false; return false;
} }
// determine size of spine items initializeSpineItemSizes();
Serial.printf("[%lu] [EBP] Loaded ePub: %s\n", millis(), filepath.c_str());
return true;
}
void Epub::initializeSpineItemSizes(){
setupCacheDir();
size_t spineItemsCount = getSpineItemsCount(); size_t spineItemsCount = getSpineItemsCount();
size_t spineItemsSize = 0; size_t cumSpineItemSize = 0;
if (SD.exists((getCachePath() + "/spine_size.bin").c_str())) {
File f = SD.open((getCachePath() + "/spine_size.bin").c_str());
uint8_t data[4];
for (size_t i = 0; i < spineItemsCount; i++) {
f.read(data, 4);
cumSpineItemSize = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
cumulativeSpineItemSize.emplace_back(cumSpineItemSize);
// Serial.printf("[%lu] [EBP] Loading item %d size %u to %u %u\n", millis(),
// i, cumSpineItemSize, data[1], data[0]);
}
f.close();
} else {
File f = SD.open((getCachePath() + "/spine_size.bin").c_str(), FILE_WRITE);
uint8_t data[4];
// determine size of spine items
for (size_t i = 0; i < spineItemsCount; i++) { for (size_t i = 0; i < spineItemsCount; i++) {
std::string spineItem = getSpineItem(i); std::string spineItem = getSpineItem(i);
size_t s = 0; size_t s = 0;
getItemSize(spineItem, &s); getItemSize(spineItem, &s);
spineItemsSize += s; cumSpineItemSize += s;
cumulativeSpineItemSize.emplace_back(spineItemsSize); cumulativeSpineItemSize.emplace_back(cumSpineItemSize);
// and persist to cache
data[0] = cumSpineItemSize & 0xFF;
data[1] = (cumSpineItemSize >> 8) & 0xFF;
data[2] = (cumSpineItemSize >> 16) & 0xFF;
data[3] = (cumSpineItemSize >> 24) & 0xFF;
// Serial.printf("[%lu] [EBP] Persisting item %d size %u to %u %u\n", millis(),
// i, cumSpineItemSize, data[1], data[0]);
f.write(data, 4);
} }
Serial.printf("[%lu] [EBP] Book size: %u\n", millis(), spineItemsSize);
Serial.printf("[%lu] [EBP] Loaded ePub: %s\n", millis(), filepath.c_str()); f.close();
}
return true; Serial.printf("[%lu] [EBP] Book size: %lu\n", millis(), cumSpineItemSize);
} }
bool Epub::clearCache() const { bool Epub::clearCache() const {

View File

@ -32,6 +32,7 @@ class Epub {
bool findContentOpfFile(std::string* contentOpfFile) const; bool findContentOpfFile(std::string* contentOpfFile) const;
bool parseContentOpf(const std::string& contentOpfFilePath); bool parseContentOpf(const std::string& contentOpfFilePath);
bool parseTocNcxFile(); bool parseTocNcxFile();
void initializeSpineItemSizes();
public: public:
explicit Epub(std::string filepath, const std::string& cacheDir) : filepath(std::move(filepath)) { explicit Epub(std::string filepath, const std::string& cacheDir) : filepath(std::move(filepath)) {