mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 17:27:59 +01:00
decompression uses less memory
This commit is contained in:
parent
a062a22e72
commit
96b61c73dc
1 changed files with 58 additions and 26 deletions
|
@ -15,18 +15,30 @@ void StoreYamlComponent::dump_config() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Entry {
|
||||||
|
uint32_t p : 24;
|
||||||
|
uint32_t c : 8;
|
||||||
|
};
|
||||||
|
|
||||||
class Decompressor {
|
class Decompressor {
|
||||||
std::map<uint16_t, std::string> codes_; // TODO: replace string with char + index to next char
|
std::map<uint16_t, Entry> codes_;
|
||||||
size_t pos_{0};
|
size_t pos_;
|
||||||
uint8_t size_{0};
|
uint8_t size_;
|
||||||
uint32_t buff_{0};
|
uint32_t buff_;
|
||||||
size_t code_index_;
|
size_t code_index_;
|
||||||
uint8_t code_width_;
|
uint8_t code_width_;
|
||||||
|
Entry prev_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Decompressor() {
|
Decompressor() { this->reset(); }
|
||||||
for (int i = 0; i < 256; i++) {
|
|
||||||
this->codes_[i] = std::string(1, (char) i);
|
void reset() {
|
||||||
|
this->pos_ = 0;
|
||||||
|
this->size_ = 0;
|
||||||
|
this->buff_ = 0;
|
||||||
|
this->codes_.clear();
|
||||||
|
for (uint32_t i = 0; i < 256; i++) {
|
||||||
|
this->codes_[i] = Entry{.p = 0, .c = i};
|
||||||
}
|
}
|
||||||
this->code_index_ = this->codes_.size();
|
this->code_index_ = this->codes_.size();
|
||||||
this->code_width_ = 9; // log2next + 1
|
this->code_width_ = 9; // log2next + 1
|
||||||
|
@ -47,40 +59,60 @@ class Decompressor {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_code() {
|
const Entry *get_entry(uint16_t &code) {
|
||||||
if (this->code_index_ == ((1 << this->code_width_) - 1)) {
|
if (this->code_index_ == ((1 << this->code_width_) - 1)) {
|
||||||
this->code_width_++;
|
this->code_width_++;
|
||||||
}
|
}
|
||||||
uint32_t c = get_bits(this->code_width_);
|
code = (uint16_t) get_bits(this->code_width_);
|
||||||
auto i = this->codes_.find(c);
|
auto i = this->codes_.find(code);
|
||||||
if (i != this->codes_.end()) {
|
if (i != this->codes_.end()) {
|
||||||
return i->second;
|
return &i->second;
|
||||||
}
|
}
|
||||||
if (c != this->codes_.size()) {
|
if (code != this->codes_.size()) {
|
||||||
this->pos_ = ESPHOME_YAML_SIZE; // error in input, set eof
|
this->pos_ = ESPHOME_YAML_SIZE; // error in input, set eof
|
||||||
}
|
}
|
||||||
return std::string();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_code(const std::string &c) { this->codes_[this->code_index_++] = c; }
|
|
||||||
|
|
||||||
bool is_eof() const { return this->pos_ >= ESPHOME_YAML_SIZE; }
|
bool is_eof() const { return this->pos_ >= ESPHOME_YAML_SIZE; }
|
||||||
|
|
||||||
|
std::string get_string(const Entry *entry) const {
|
||||||
|
std::string s(1, (char) entry->c);
|
||||||
|
while (entry->p != 0) {
|
||||||
|
entry = &this->codes_.find(entry->p)->second;
|
||||||
|
s = std::string(1, (char) entry->c) + s;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_first() {
|
||||||
|
this->reset();
|
||||||
|
uint16_t code = 0;
|
||||||
|
const Entry *entry = this->get_entry(code);
|
||||||
|
std::string s = this->get_string(entry);
|
||||||
|
this->prev_.c = (uint32_t) s[0];
|
||||||
|
this->prev_.p = code;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_next() {
|
||||||
|
uint16_t code = 0;
|
||||||
|
const Entry *entry = this->get_entry(code);
|
||||||
|
if (entry == nullptr)
|
||||||
|
entry = &this->prev_;
|
||||||
|
std::string s = this->get_string(entry);
|
||||||
|
this->prev_.c = s[0];
|
||||||
|
this->codes_[this->code_index_++] = this->prev_;
|
||||||
|
this->prev_.p = code;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void StoreYamlComponent::log(bool dump_config) const {
|
void StoreYamlComponent::log(bool dump_config) const {
|
||||||
Decompressor *dec = new Decompressor();
|
Decompressor *dec = new Decompressor();
|
||||||
|
std::string yaml = dec->get_first();
|
||||||
std::string c = dec->get_code();
|
|
||||||
std::string prev = c;
|
|
||||||
std::string yaml = c;
|
|
||||||
|
|
||||||
while (!dec->is_eof()) {
|
while (!dec->is_eof()) {
|
||||||
std::string c = dec->get_code();
|
yaml += dec->get_next();
|
||||||
if (c.empty())
|
|
||||||
c = prev + prev[0];
|
|
||||||
dec->add_code(prev + c[0]);
|
|
||||||
prev = c;
|
|
||||||
yaml += c;
|
|
||||||
// print line by line because the logger cannot handle too much data
|
// print line by line because the logger cannot handle too much data
|
||||||
// it also uses less memory
|
// it also uses less memory
|
||||||
size_t newline = 0;
|
size_t newline = 0;
|
||||||
|
|
Loading…
Reference in a new issue