20ErrorCode Get(Database::KeyBase& key)
override
22 auto ans = SearchKey(key.name_);
25 return ErrorCode::NOT_FOUND;
29 ReadFlashOrExit(ans, key_buffer);
31 if (key.raw_data_.size_ != key_buffer.
GetDataSize())
33 return ErrorCode::FAILED;
36 ReadFlashOrExit(GetKeyData(ans), key.raw_data_);
48ErrorCode Set(KeyBase& key, RawData data)
override
50 return SetKey(key.name_, data.addr_, data.size_);
60 return AddKey(key.name_, key.raw_data_.addr_, key.raw_data_.size_);
70explicit DatabaseRaw(Flash& flash,
size_t recycle_threshold = 128)
71 : recycle_threshold_(recycle_threshold), flash_(flash)
73 ASSERT(flash.MinEraseSize() * 2 <= flash_.Size());
74 ASSERT(flash_.MinWriteSize() <= MinWriteSize);
75 auto block_num =
static_cast<size_t>(flash_.Size() / flash.MinEraseSize());
76 block_size_ = block_num / 2 * flash.MinEraseSize();
99 if (IsBackupComplete(used_size) ||
100 (!IsBlockValid(BlockType::MAIN) && IsBackupRestorable(used_size)))
102 EraseFlashOrExit(0, block_size_);
103 CopyBlockPrefixAndChecksum(BlockType::MAIN, BlockType::BACKUP, used_size);
108 if (!IsBlockValid(BlockType::MAIN))
110 InitBlock(BlockType::MAIN);
112 if (IsBlockValid(BlockType::BACKUP) && !IsBlockEmpty(BlockType::BACKUP))
130 InitBlock(BlockType::MAIN);
161 size_t key_offset = GetSentinelOffset(BlockType::MAIN);
163 ReadFlashOrExit(key_offset, key);
164 while (NextChainKey(BlockType::MAIN, key_offset, key))
166 if (IsKeyLive(key) && IsKeyNameTerminated(key_offset, key))
168 used_size += GetKeySpan(key);
171 if (used_size + GetCrcSize() > GetChecksumOffset())
173 return ErrorCode::FULL;
176 if (!IsBackupPrepared())
181 size_t backup_last_key = GetSentinelOffset(BlockType::BACKUP);
182 key_offset = GetSentinelOffset(BlockType::MAIN);
183 ReadFlashOrExit(key_offset, key);
184 while (NextChainKey(BlockType::MAIN, key_offset, key))
186 if (!IsKeyLive(key) || !IsKeyNameTerminated(key_offset, key))
191 const size_t new_key_offset = GetNextKey(backup_last_key);
193 CopyFlashData(GetKeyName(new_key_offset), GetKeyName(key_offset),
195 CopyFlashData(GetKeyData(new_key_offset), GetKeyData(key_offset), key.
GetDataSize());
197 LinkKey(BlockType::BACKUP, backup_last_key);
198 backup_last_key = new_key_offset;
200 DEV_ASSERT(GetNextKey(backup_last_key) - block_size_ == used_size);
202 const uint32_t crc = GetBackupCrc(used_size);
203 WriteFlashOrExit(GetBlockOffset(BlockType::BACKUP) + used_size, crc);
204 WriteBlockChecksum(BlockType::BACKUP);
206 EraseFlashOrExit(0, block_size_);
207 CopyBlockPrefixAndChecksum(BlockType::MAIN, BlockType::BACKUP, used_size);
211 return ErrorCode::OK;
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
size_t OffsetOf(MemberType OwnerType::*member) noexcept
计算成员在宿主对象中的偏移量 Computes the offset of a member within the owning object
键信息结构,存储键的元数据 Structure containing key metadata.
BlockBoolData< MinWriteSize > uninit
该键是否未初始化
uint32_t GetDataSize() const
获取数据字节数 / Get the payload size in bytes.
uint8_t GetNameLength() const
获取键名长度 / Get the key name length.