libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::DatabaseRaw< MinWriteSize > Class Template Reference

适用于最小写入单元受限的 Flash 存储的数据库实现 (Database implementation for Flash storage with minimum write unit restrictions). More...

#include <database.hpp>

Inheritance diagram for LibXR::DatabaseRaw< MinWriteSize >:
[legend]
Collaboration diagram for LibXR::DatabaseRaw< MinWriteSize >:
[legend]

Data Structures

struct  BlockBoolData
 
class  BlockBoolUtil
 
struct  FlashInfo
 Flash 存储的块信息结构 (Structure representing a Flash storage block). More...
 
struct  KeyInfo
 键信息结构,存储键的元数据 (Structure containing key metadata). More...
 

Public Member Functions

ErrorCode Get (Database::KeyBase &key) override
 获取数据库中的键值 (Retrieve the key's value from the database).
 
ErrorCode Set (KeyBase &key, RawData data) override
 设置数据库中的键值 (Set the key's value in the database).
 
ErrorCode Add (KeyBase &key) override
 添加新键到数据库 (Add a new key to the database).
 
 DatabaseRaw (Flash &flash, size_t recycle_threshold=128)
 构造函数,初始化 Flash 存储和缓冲区 (Constructor to initialize Flash storage and buffer).
 
void Init ()
 初始化数据库存储区,确保主备块正确 (Initialize database storage, ensuring main and backup blocks are valid).
 
void Restore ()
 还原存储数据,清空 Flash 区域 (Restore storage data, clearing Flash memory area).
 
ErrorCode Recycle ()
 回收 Flash 空间,整理数据 (Recycle Flash storage space and organize data).
 

Private Types

enum class  BlockType : uint8_t { MAIN = 0 , BACKUP = 1 }
 

Private Member Functions

size_t AvailableSize ()
 计算可用的存储空间大小 (Calculate the available storage size).
 
ErrorCode AddKeyBody (size_t name_len, size_t size, size_t &key_buf_offset)
 
ErrorCode AddKey (size_t name_offset, size_t name_len, const void *data, size_t size)
 
ErrorCode AddKey (const char *name, const void *data, size_t size)
 
ErrorCode SetKeyCommon (size_t key_offset, size_t name_len, const void *data, size_t size)
 
ErrorCode SetKey (size_t name_offset, size_t name_length, const void *data, size_t size)
 
ErrorCode SetKey (const char *name, const void *data, size_t size, bool recycle=true)
 
size_t GetKeyData (size_t offset)
 
size_t GetKeyName (size_t offset)
 
void InitBlock (BlockType block)
 
bool IsBlockInited (BlockType block)
 
bool IsBlockEmpty (BlockType block)
 
bool IsBlockError (BlockType block)
 
size_t GetKeySize (size_t offset)
 
size_t GetNextKey (size_t offset)
 
size_t GetLastKey (BlockType block)
 
bool KeyDataCompare (size_t offset, const void *data, size_t size)
 
bool KeyNameCompare (size_t offset, const char *name)
 
bool KeyNameCompare (size_t offset_a, size_t offset_b)
 
void CopyFlashData (size_t dst_offset, size_t src_offset, size_t size)
 
size_t SearchKey (const char *name)
 
size_t AlignSize (size_t size)
 计算对齐后的大小 (Calculate the aligned size).
 
ErrorCode Write (size_t offset, ConstRawData data)
 以最小写入单元对齐的方式写入数据 (Write data aligned to the minimum write unit).
 

Private Attributes

size_t recycle_threshold_ = 0
 回收阈值 (Recycle threshold).
 
Flashflash_
 目标 Flash 存储设备 (Target Flash storage device).
 
uint32_t block_size_
 Flash 块大小 (Flash block size).
 
uint8_t write_buffer_ [MinWriteSize]
 写入缓冲区 (Write buffer).
 

Static Private Attributes

static constexpr uint32_t FLASH_HEADER
 Flash 头部标识 (Flash header identifier).
 
static constexpr uint32_t CHECKSUM_BYTE = 0x9abcedf0
 校验字节 (Checksum byte).
 

Detailed Description

template<size_t MinWriteSize>
class LibXR::DatabaseRaw< MinWriteSize >

适用于最小写入单元受限的 Flash 存储的数据库实现 (Database implementation for Flash storage with minimum write unit restrictions).

This class provides key-value storage management for Flash memory that requires data to be written in fixed-size blocks. 此类提供适用于 Flash 存储的键值存储管理,该存储要求数据以固定大小块写入。

Template Parameters
MinWriteSizeFlash 的最小写入单元大小 (Minimum write unit size for Flash storage).

Definition at line 328 of file database.hpp.

Member Enumeration Documentation

◆ BlockType

template<size_t MinWriteSize>
enum class LibXR::DatabaseRaw::BlockType : uint8_t
strongprivate
Enumerator
MAIN 

主块 (Main block).

BACKUP 

备份块 (Backup block).

Definition at line 335 of file database.hpp.

336 {
337 MAIN = 0,
338 BACKUP = 1
339 };
@ MAIN
主块 (Main block).
@ BACKUP
备份块 (Backup block).

Constructor & Destructor Documentation

◆ DatabaseRaw()

template<size_t MinWriteSize>
LibXR::DatabaseRaw< MinWriteSize >::DatabaseRaw ( Flash & flash,
size_t recycle_threshold = 128 )
inlineexplicit

构造函数,初始化 Flash 存储和缓冲区 (Constructor to initialize Flash storage and buffer).

Parameters
flash目标 Flash 存储设备 (Target Flash storage device).
recycle_threshold回收阈值 (Recycle threshold).

Definition at line 971 of file database.hpp.

972 : recycle_threshold_(recycle_threshold), flash_(flash)
973 {
974 ASSERT(flash.MinEraseSize() * 2 <= flash_.Size());
975 ASSERT(flash_.MinWriteSize() <= MinWriteSize);
976 auto block_num = static_cast<size_t>(flash_.Size() / flash.MinEraseSize());
977 block_size_ = block_num / 2 * flash.MinEraseSize();
978 Init();
979 }
uint32_t block_size_
Flash 块大小 (Flash block size).
Definition database.hpp:460
void Init()
初始化数据库存储区,确保主备块正确 (Initialize database storage, ensuring main and backup blocks are valid).
Definition database.hpp:985
Flash & flash_
目标 Flash 存储设备 (Target Flash storage device).
Definition database.hpp:459
size_t recycle_threshold_
回收阈值 (Recycle threshold).
Definition database.hpp:458
size_t Size() const
Returns the size of the flash memory area. 获取闪存存储区域的大小。
Definition flash.hpp:82
size_t MinWriteSize() const
Returns the minimum writable block size in bytes. 获取最小可写块大小(字节)。
Definition flash.hpp:73

Member Function Documentation

◆ Add()

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::Add ( KeyBase & key)
inlineoverridevirtual

添加新键到数据库 (Add a new key to the database).

Parameters
key需要添加的键 (Key to add).
Returns
操作结果 (Operation result).

Implements LibXR::Database.

Definition at line 959 of file database.hpp.

960 {
961 return AddKey(key.name_, key.raw_data_.addr_, key.raw_data_.size_);
962 }

◆ AddKey() [1/2]

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::AddKey ( const char * name,
const void * data,
size_t size )
inlineprivate

Definition at line 561 of file database.hpp.

562 {
563 size_t name_len = strlen(name) + 1;
564 if (auto ans = SearchKey(name))
565 {
566 return SetKey(name, data, size);
567 }
568 size_t key_buf_offset = 0;
569 ErrorCode ec = AddKeyBody(name_len, size, key_buf_offset);
570 if (ec != ErrorCode::OK)
571 {
572 return ec;
573 }
574 Write(GetKeyName(key_buf_offset), {reinterpret_cast<const uint8_t*>(name), name_len});
575 Write(GetKeyData(key_buf_offset), {reinterpret_cast<const uint8_t*>(data), size});
576 return ErrorCode::OK;
577 }
ErrorCode Write(size_t offset, ConstRawData data)
以最小写入单元对齐的方式写入数据 (Write data aligned to the minimum write unit).
Definition database.hpp:890

◆ AddKey() [2/2]

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::AddKey ( size_t name_offset,
size_t name_len,
const void * data,
size_t size )
inlineprivate

Definition at line 548 of file database.hpp.

549 {
550 size_t key_buf_offset = 0;
551 ErrorCode ec = AddKeyBody(name_len, size, key_buf_offset);
552 if (ec != ErrorCode::OK)
553 {
554 return ec;
555 }
556 CopyFlashData(GetKeyName(key_buf_offset), name_offset, name_len);
557 Write(GetKeyData(key_buf_offset), {reinterpret_cast<const uint8_t*>(data), size});
558 return ErrorCode::OK;
559 }

◆ AddKeyBody()

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::AddKeyBody ( size_t name_len,
size_t size,
size_t & key_buf_offset )
inlineprivate

Definition at line 474 of file database.hpp.

475 {
476 bool recycle = false;
477 add_again:
478 size_t last_key_offset = GetLastKey(BlockType::MAIN);
479 key_buf_offset = 0;
480
481 if (AvailableSize() <
482 AlignSize(sizeof(KeyInfo)) + AlignSize(name_len) + AlignSize(size))
483 {
484 if (!recycle)
485 {
486 Recycle();
487 recycle = true;
488 // NOLINTNEXTLINE
489 goto add_again;
490 }
491 else
492 {
493 ASSERT(false);
494 return ErrorCode::FULL;
495 }
496 }
497
498 if (last_key_offset == 0)
499 {
500 FlashInfo flash_info;
501 flash_info.header = FLASH_HEADER;
502 KeyInfo& tmp_key = flash_info.key;
503 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.no_next_key, false);
504 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.available_flag, false);
505 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.uninit, false);
506 tmp_key.SetNameLength(0);
507 tmp_key.SetDataSize(0);
508 Write(0, flash_info);
509 key_buf_offset = GetNextKey(OFFSET_OF(FlashInfo, key));
510 }
511 else
512 {
513 key_buf_offset = GetNextKey(last_key_offset);
514 }
515
516 KeyInfo new_key = {};
517 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.no_next_key, true);
518 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.available_flag, true);
519 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.uninit, true);
520 new_key.SetNameLength(name_len);
521 new_key.SetDataSize(size);
522
523 Write(key_buf_offset, new_key);
524 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.uninit, false);
525
526 if (last_key_offset != 0)
527 {
528 KeyInfo last_key;
529 flash_.Read(last_key_offset, last_key);
530 KeyInfo new_last_key = {};
531 BlockBoolUtil<MinWriteSize>::SetFlag(new_last_key.no_next_key, false);
532 BlockBoolUtil<MinWriteSize>::SetFlag(
533 new_last_key.available_flag,
534 BlockBoolUtil<MinWriteSize>::ReadFlag(last_key.available_flag));
535 BlockBoolUtil<MinWriteSize>::SetFlag(
536 new_last_key.uninit, BlockBoolUtil<MinWriteSize>::ReadFlag(last_key.uninit));
537 new_last_key.SetNameLength(last_key.GetNameLength());
538 new_last_key.SetDataSize(last_key.GetDataSize());
539
540 Write(last_key_offset, new_last_key);
541 }
542
543 Write(key_buf_offset, new_key);
544
545 return ErrorCode::OK;
546 }
size_t AvailableSize()
计算可用的存储空间大小 (Calculate the available storage size).
Definition database.hpp:468
static constexpr uint32_t FLASH_HEADER
Flash 头部标识 (Flash header identifier).
Definition database.hpp:330
ErrorCode Recycle()
回收 Flash 空间,整理数据 (Recycle Flash storage space and organize data).
size_t AlignSize(size_t size)
计算对齐后的大小 (Calculate the aligned size).
Definition database.hpp:878
virtual ErrorCode Read(size_t offset, RawData data)
Reads data from the flash memory. 从闪存中读取数据。
Definition flash.cpp:12

◆ AlignSize()

template<size_t MinWriteSize>
size_t LibXR::DatabaseRaw< MinWriteSize >::AlignSize ( size_t size)
inlineprivate

计算对齐后的大小 (Calculate the aligned size).

Parameters
size需要对齐的大小 (Size to align).
Returns
对齐后的大小 (Aligned size).

Definition at line 878 of file database.hpp.

879 {
880 return static_cast<size_t>((size + MinWriteSize - 1) / MinWriteSize) * MinWriteSize;
881 }

◆ AvailableSize()

template<size_t MinWriteSize>
size_t LibXR::DatabaseRaw< MinWriteSize >::AvailableSize ( )
inlineprivate

计算可用的存储空间大小 (Calculate the available storage size).

Returns
剩余的可用字节数 (Remaining available bytes).

Definition at line 468 of file database.hpp.

469 {
470 auto offset = GetNextKey(GetLastKey(BlockType::MAIN));
471 return block_size_ - sizeof(CHECKSUM_BYTE) - offset;
472 }
static constexpr uint32_t CHECKSUM_BYTE
校验字节 (Checksum byte).
Definition database.hpp:333

◆ CopyFlashData()

template<size_t MinWriteSize>
void LibXR::DatabaseRaw< MinWriteSize >::CopyFlashData ( size_t dst_offset,
size_t src_offset,
size_t size )
inlineprivate

Definition at line 816 of file database.hpp.

817 {
818 for (size_t i = 0; i < size; i += MinWriteSize)
819 {
820 flash_.Read(src_offset + i, {write_buffer_, MinWriteSize});
821 flash_.Write(dst_offset + i, {write_buffer_, MinWriteSize});
822 }
823 }
uint8_t write_buffer_[MinWriteSize]
写入缓冲区 (Write buffer).
Definition database.hpp:461
virtual ErrorCode Write(size_t offset, ConstRawData data)=0
Writes data to the flash memory. 向闪存写入数据。

◆ Get()

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::Get ( Database::KeyBase & key)
inlineoverridevirtual

获取数据库中的键值 (Retrieve the key's value from the database).

Parameters
key需要获取的键 (Key to retrieve).
Returns
操作结果,如果找到则返回 ErrorCode::OK,否则返回 ErrorCode::NOT_FOUND (Operation result, returns ErrorCode::OK if found, otherwise ErrorCode::NOT_FOUND).

Implements LibXR::Database.

Definition at line 925 of file database.hpp.

926 {
927 auto ans = SearchKey(key.name_);
928 if (!ans)
929 {
930 return ErrorCode::NOT_FOUND;
931 }
932
933 KeyInfo key_buffer;
934 flash_.Read(ans, key_buffer);
935
936 if (key.raw_data_.size_ < key_buffer.GetDataSize())
937 {
938 return ErrorCode::FAILED;
939 }
940
941 flash_.Read(GetKeyData(ans), key.raw_data_);
942
943 return ErrorCode::OK;
944 }

◆ GetKeyData()

template<size_t MinWriteSize>
size_t LibXR::DatabaseRaw< MinWriteSize >::GetKeyData ( size_t offset)
inlineprivate

Definition at line 657 of file database.hpp.

658 {
659 KeyInfo key;
660 flash_.Read(offset, key);
661 return offset + AlignSize(sizeof(KeyInfo)) + AlignSize(key.GetNameLength());
662 }

◆ GetKeyName()

template<size_t MinWriteSize>
size_t LibXR::DatabaseRaw< MinWriteSize >::GetKeyName ( size_t offset)
inlineprivate

Definition at line 664 of file database.hpp.

664{ return offset + AlignSize(sizeof(KeyInfo)); }

◆ GetKeySize()

template<size_t MinWriteSize>
size_t LibXR::DatabaseRaw< MinWriteSize >::GetKeySize ( size_t offset)
inlineprivate

Definition at line 724 of file database.hpp.

725 {
726 KeyInfo key;
727 flash_.Read(offset, key);
728 return AlignSize(sizeof(KeyInfo)) + AlignSize(key.GetNameLength()) +
729 AlignSize(key.GetDataSize());
730 }

◆ GetLastKey()

template<size_t MinWriteSize>
size_t LibXR::DatabaseRaw< MinWriteSize >::GetLastKey ( BlockType block)
inlineprivate

Definition at line 739 of file database.hpp.

740 {
741 if (IsBlockEmpty(block))
742 {
743 return 0;
744 }
745
746 KeyInfo key;
747 size_t key_offset = OFFSET_OF(FlashInfo, key);
748 if (block != BlockType::MAIN)
749 {
750 key_offset += block_size_;
751 }
752 flash_.Read(key_offset, key);
753 while (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key))
754 {
755 key_offset = GetNextKey(key_offset);
756 flash_.Read(key_offset, key);
757 }
758 return key_offset;
759 }

◆ GetNextKey()

template<size_t MinWriteSize>
size_t LibXR::DatabaseRaw< MinWriteSize >::GetNextKey ( size_t offset)
inlineprivate

Definition at line 732 of file database.hpp.

733 {
734 KeyInfo key;
735 flash_.Read(offset, key);
736 return offset + GetKeySize(offset);
737 }

◆ Init()

template<size_t MinWriteSize>
void LibXR::DatabaseRaw< MinWriteSize >::Init ( )
inline

初始化数据库存储区,确保主备块正确 (Initialize database storage, ensuring main and backup blocks are valid).

Definition at line 985 of file database.hpp.

986 {
987 if (!IsBlockInited(BlockType::BACKUP) || IsBlockError(BlockType::BACKUP))
988 {
989 InitBlock(BlockType::BACKUP);
990 }
991
992 if (!IsBlockInited(BlockType::MAIN) || IsBlockError(BlockType::MAIN))
993 {
994 if (IsBlockEmpty(BlockType::BACKUP))
995 {
996 InitBlock(BlockType::MAIN);
997 }
998 else
999 {
1001 for (uint32_t i = 0; i < block_size_; i += MinWriteSize)
1002 {
1003 flash_.Read(i + block_size_, {write_buffer_, MinWriteSize});
1004 flash_.Write(i, {write_buffer_, MinWriteSize});
1005 }
1006 }
1007 }
1008
1009 if (!IsBlockEmpty(BlockType::BACKUP))
1010 {
1011 InitBlock(BlockType::BACKUP);
1012 }
1013
1014 KeyInfo key;
1015 size_t key_offset = OFFSET_OF(FlashInfo, key);
1016 flash_.Read(key_offset, key);
1017 size_t need_cycle = 0;
1018 while (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key))
1019 {
1020 key_offset = GetNextKey(key_offset);
1021
1022 if (key_offset + sizeof(key) >= flash_.Size())
1023 {
1024 InitBlock(BlockType::MAIN);
1025 break;
1026 }
1027
1028 flash_.Read(key_offset, key);
1029
1030 // TODO: 恢复损坏数据
1031 if (BlockBoolUtil<MinWriteSize>::ReadFlag(key.uninit))
1032 {
1033 InitBlock(BlockType::MAIN);
1034 break;
1035 }
1036 if (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.available_flag))
1037 {
1038 need_cycle += 1;
1039 }
1040 }
1041
1042 if (need_cycle > recycle_threshold_)
1043 {
1044 Recycle();
1045 }
1046 }
virtual ErrorCode Erase(size_t offset, size_t size)=0
Erases a section of the flash memory. 擦除闪存的指定区域。

◆ InitBlock()

template<size_t MinWriteSize>
void LibXR::DatabaseRaw< MinWriteSize >::InitBlock ( BlockType block)
inlineprivate

Definition at line 666 of file database.hpp.

667 {
668 size_t offset = 0;
669 if (block == BlockType::BACKUP)
670 {
671 offset = block_size_;
672 }
673 flash_.Erase(offset, block_size_);
674
675 FlashInfo info; // padding filled with 0xFF by constructor
676 info.header = FLASH_HEADER;
677 KeyInfo& tmp_key = info.key;
678 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.no_next_key, true);
679 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.available_flag, true);
680 BlockBoolUtil<MinWriteSize>::SetFlag(tmp_key.uninit, false);
681 tmp_key.SetNameLength(0);
682 tmp_key.SetDataSize(0);
683 Write(offset, {reinterpret_cast<uint8_t*>(&info), sizeof(FlashInfo)});
684 Write(offset + block_size_ - AlignSize(sizeof(CHECKSUM_BYTE)),
685 {&CHECKSUM_BYTE, sizeof(CHECKSUM_BYTE)});
686 }

◆ IsBlockEmpty()

template<size_t MinWriteSize>
bool LibXR::DatabaseRaw< MinWriteSize >::IsBlockEmpty ( BlockType block)
inlineprivate

Definition at line 700 of file database.hpp.

701 {
702 size_t offset = 0;
703 if (block == BlockType::BACKUP)
704 {
705 offset = block_size_;
706 }
707 FlashInfo flash_data;
708 flash_.Read(offset, flash_data);
709 return BlockBoolUtil<MinWriteSize>::ReadFlag(flash_data.key.available_flag) == true;
710 }

◆ IsBlockError()

template<size_t MinWriteSize>
bool LibXR::DatabaseRaw< MinWriteSize >::IsBlockError ( BlockType block)
inlineprivate

Definition at line 712 of file database.hpp.

713 {
714 size_t offset = 0;
715 if (block == BlockType::BACKUP)
716 {
717 offset = block_size_;
718 }
719 uint32_t checksum = 0;
720 flash_.Read(offset + block_size_ - AlignSize(sizeof(CHECKSUM_BYTE)), checksum);
721 return checksum != CHECKSUM_BYTE;
722 }

◆ IsBlockInited()

template<size_t MinWriteSize>
bool LibXR::DatabaseRaw< MinWriteSize >::IsBlockInited ( BlockType block)
inlineprivate

Definition at line 688 of file database.hpp.

689 {
690 size_t offset = 0;
691 if (block == BlockType::BACKUP)
692 {
693 offset = block_size_;
694 }
695 FlashInfo flash_data;
696 flash_.Read(offset, flash_data);
697 return flash_data.header == FLASH_HEADER;
698 }

◆ KeyDataCompare()

template<size_t MinWriteSize>
bool LibXR::DatabaseRaw< MinWriteSize >::KeyDataCompare ( size_t offset,
const void * data,
size_t size )
inlineprivate

Definition at line 761 of file database.hpp.

762 {
763 KeyInfo key;
764 flash_.Read(offset, key);
765 size_t key_data_offset = GetKeyData(offset);
766 uint8_t data_buffer = 0;
767 for (size_t i = 0; i < size; i++)
768 {
769 flash_.Read(key_data_offset + i, data_buffer);
770 if (data_buffer != (reinterpret_cast<const uint8_t*>(data))[i])
771 {
772 return true;
773 }
774 }
775 return false;
776 }

◆ KeyNameCompare() [1/2]

template<size_t MinWriteSize>
bool LibXR::DatabaseRaw< MinWriteSize >::KeyNameCompare ( size_t offset,
const char * name )
inlineprivate

Definition at line 778 of file database.hpp.

779 {
780 KeyInfo key;
781 flash_.Read(offset, key);
782 for (size_t i = 0; i < key.GetNameLength(); i++)
783 {
784 uint8_t data_buffer = 0;
785 flash_.Read(offset + AlignSize(sizeof(KeyInfo)) + i, data_buffer);
786 if (data_buffer != name[i])
787 {
788 return true;
789 }
790 }
791 return false;
792 }

◆ KeyNameCompare() [2/2]

template<size_t MinWriteSize>
bool LibXR::DatabaseRaw< MinWriteSize >::KeyNameCompare ( size_t offset_a,
size_t offset_b )
inlineprivate

Definition at line 794 of file database.hpp.

795 {
796 KeyInfo key_a, key_b;
797 flash_.Read(offset_a, key_a);
798 flash_.Read(offset_b, key_b);
799 if (key_a.GetNameLength() != key_b.GetNameLength())
800 {
801 return true;
802 }
803 for (size_t i = 0; i < key_a.GetNameLength(); i++)
804 {
805 uint8_t data_buffer_a = 0, data_buffer_b = 0;
806 flash_.Read(offset_a + sizeof(KeyInfo) + i, data_buffer_a);
807 flash_.Read(offset_b + sizeof(KeyInfo) + i, data_buffer_b);
808 if (data_buffer_a != data_buffer_b)
809 {
810 return true;
811 }
812 }
813 return false;
814 }

◆ Recycle()

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::Recycle ( )
inline

回收 Flash 空间,整理数据 (Recycle Flash storage space and organize data).

Moves valid keys from the main block to the backup block and erases the main block. 将主存储块中的有效键移动到备份块,并擦除主存储块。

Returns
操作结果 (Operation result).

Definition at line 1068 of file database.hpp.

1069 {
1070 if (IsBlockEmpty(BlockType::MAIN))
1071 {
1072 return ErrorCode::OK;
1073 }
1074
1075 KeyInfo key;
1076 size_t key_offset = OFFSET_OF(FlashInfo, key);
1077 flash_.Read(key_offset, key);
1078
1079 if (!IsBlockEmpty(BlockType::BACKUP))
1080 {
1081 InitBlock(BlockType::BACKUP);
1082 }
1083
1084 size_t write_buff_offset = OFFSET_OF(FlashInfo, key) + block_size_;
1085
1086 auto new_key = KeyInfo{};
1087 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.uninit, false);
1088 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.available_flag, false);
1089 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.no_next_key, false);
1090 Write(write_buff_offset, new_key);
1091
1092 write_buff_offset += GetKeySize(write_buff_offset);
1093
1094 do
1095 {
1096 key_offset = GetNextKey(key_offset);
1097 flash_.Read(key_offset, key);
1098
1099 if (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.available_flag))
1100 {
1101 continue;
1102 }
1103
1104 Write(write_buff_offset, key);
1105 write_buff_offset += AlignSize(sizeof(KeyInfo));
1106 CopyFlashData(write_buff_offset, GetKeyName(key_offset), key.GetNameLength());
1107 write_buff_offset += AlignSize(key.GetNameLength());
1108 CopyFlashData(write_buff_offset, GetKeyData(key_offset), key.GetDataSize());
1109 write_buff_offset += AlignSize(key.GetDataSize());
1110 } while (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key));
1111
1113 for (uint32_t i = 0; i < block_size_; i += MinWriteSize)
1114 {
1115 flash_.Read(i + block_size_, {write_buffer_, MinWriteSize});
1116 flash_.Write(i, {write_buffer_, MinWriteSize});
1117 }
1118
1119 InitBlock(BlockType::BACKUP);
1120
1121 return ErrorCode::OK;
1122 }

◆ Restore()

template<size_t MinWriteSize>
void LibXR::DatabaseRaw< MinWriteSize >::Restore ( )
inline

还原存储数据,清空 Flash 区域 (Restore storage data, clearing Flash memory area).

Definition at line 1052 of file database.hpp.

1053 {
1054 InitBlock(BlockType::MAIN);
1055 InitBlock(BlockType::BACKUP);
1056 }

◆ SearchKey()

template<size_t MinWriteSize>
size_t LibXR::DatabaseRaw< MinWriteSize >::SearchKey ( const char * name)
inlineprivate

Definition at line 825 of file database.hpp.

826 {
827 if (IsBlockEmpty(BlockType::MAIN))
828 {
829 return 0;
830 }
831
832 KeyInfo key;
833 size_t key_offset = OFFSET_OF(FlashInfo, key);
834 flash_.Read(key_offset, key);
835
836 size_t ans = 0, need_cycle = 0;
837
838 while (true)
839 {
840 if (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.available_flag))
841 {
842 key_offset = GetNextKey(key_offset);
843 flash_.Read(key_offset, key);
844 need_cycle++;
845 continue;
846 }
847
848 if (!KeyNameCompare(key_offset, name))
849 {
850 ans = key_offset;
851 break;
852 }
853
854 if (BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key))
855 {
856 break;
857 }
858
859 key_offset = GetNextKey(key_offset);
860 flash_.Read(key_offset, key);
861 }
862
863 if (need_cycle > recycle_threshold_)
864 {
865 Recycle();
866 return SearchKey(name);
867 }
868
869 return ans;
870 }

◆ Set()

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::Set ( KeyBase & key,
RawData data )
inlineoverridevirtual

设置数据库中的键值 (Set the key's value in the database).

Parameters
key目标键 (Target key).
data需要存储的新值 (New value to store).
Returns
操作结果 (Operation result).

Implements LibXR::Database.

Definition at line 953 of file database.hpp.

954 {
955 LibXR::Memory::FastCopy(key.raw_data_.addr_, data.addr_, data.size_);
956 return SetKey(key.name_, data.addr_, data.size_);
957 }
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
Definition libxr_mem.cpp:3

◆ SetKey() [1/2]

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::SetKey ( const char * name,
const void * data,
size_t size,
bool recycle = true )
inlineprivate

Definition at line 614 of file database.hpp.

615 {
616 size_t key_offset = SearchKey(name);
617 if (key_offset)
618 {
619 KeyInfo key;
620 flash_.Read(key_offset, key);
621 if (key.GetDataSize() == size)
622 {
623 if (KeyDataCompare(key_offset, data, size))
624 {
625 if (AvailableSize() < AlignSize(size) + AlignSize(sizeof(KeyInfo)) +
626 AlignSize(key.GetNameLength()))
627 {
628 if (recycle)
629 {
630 Recycle();
631 return SetKey(name, data, size, false);
632 }
633 else
634 {
635 ASSERT(false);
636 return ErrorCode::FULL;
637 }
638 }
639 KeyInfo new_key = {};
640 BlockBoolUtil<MinWriteSize>::SetFlag(
641 new_key.no_next_key,
642 BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key));
643 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.available_flag, false);
644 BlockBoolUtil<MinWriteSize>::SetFlag(
645 new_key.uninit, BlockBoolUtil<MinWriteSize>::ReadFlag(key.uninit));
646 new_key.SetNameLength(key.GetNameLength());
647 new_key.SetDataSize(size);
648 Write(key_offset, new_key);
649 return AddKey(GetKeyName(key_offset), key.GetNameLength(), data, size);
650 }
651 return ErrorCode::OK;
652 }
653 }
654 return ErrorCode::FAILED;
655 }

◆ SetKey() [2/2]

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::SetKey ( size_t name_offset,
size_t name_length,
const void * data,
size_t size )
inlineprivate

Definition at line 608 of file database.hpp.

609 {
610 size_t key_offset = SearchKey(name_offset, name_length);
611 return SetKeyCommon(key_offset, name_length, data, size);
612 }

◆ SetKeyCommon()

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::SetKeyCommon ( size_t key_offset,
size_t name_len,
const void * data,
size_t size )
inlineprivate

Definition at line 579 of file database.hpp.

581 {
582 if (key_offset)
583 {
584 KeyInfo key;
585 flash_.Read(key_offset, key);
586 if (key.GetDataSize() == size)
587 {
588 if (KeyDataCompare(key_offset, data, size))
589 {
590 KeyInfo new_key = {};
591 BlockBoolUtil<MinWriteSize>::SetFlag(
592 new_key.no_next_key,
593 BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key));
594 BlockBoolUtil<MinWriteSize>::SetFlag(new_key.available_flag, false);
595 BlockBoolUtil<MinWriteSize>::SetFlag(
596 new_key.uninit, BlockBoolUtil<MinWriteSize>::ReadFlag(key.uninit));
597 new_key.SetNameLength(name_len);
598 new_key.SetDataSize(size);
599 Write(key_offset, new_key);
600 return AddKey(GetKeyName(key_offset), name_len, data, size);
601 }
602 return ErrorCode::OK;
603 }
604 }
605 return ErrorCode::FAILED;
606 }

◆ Write()

template<size_t MinWriteSize>
ErrorCode LibXR::DatabaseRaw< MinWriteSize >::Write ( size_t offset,
ConstRawData data )
inlineprivate

以最小写入单元对齐的方式写入数据 (Write data aligned to the minimum write unit).

Parameters
offset写入偏移量 (Write offset).
data要写入的数据 (Data to write).
Returns
操作结果 (Operation result).

Definition at line 890 of file database.hpp.

891 {
892 if (data.size_ == 0)
893 {
894 return ErrorCode::OK;
895 }
896
897 if (data.size_ % MinWriteSize == 0)
898 {
899 return flash_.Write(offset, data);
900 }
901 else
902 {
903 auto final_block_index = data.size_ - data.size_ % MinWriteSize;
904 if (final_block_index != 0)
905 {
906 flash_.Write(offset, {data.addr_, final_block_index});
907 }
908 memset(write_buffer_, 0xff, MinWriteSize);
910 write_buffer_, reinterpret_cast<const uint8_t*>(data.addr_) + final_block_index,
911 data.size_ % MinWriteSize);
912 return flash_.Write(offset + final_block_index, {write_buffer_, MinWriteSize});
913 }
914 }

Field Documentation

◆ block_size_

template<size_t MinWriteSize>
uint32_t LibXR::DatabaseRaw< MinWriteSize >::block_size_
private

Flash 块大小 (Flash block size).

Definition at line 460 of file database.hpp.

◆ CHECKSUM_BYTE

template<size_t MinWriteSize>
uint32_t LibXR::DatabaseRaw< MinWriteSize >::CHECKSUM_BYTE = 0x9abcedf0
staticconstexprprivate

校验字节 (Checksum byte).

Definition at line 333 of file database.hpp.

◆ flash_

template<size_t MinWriteSize>
Flash& LibXR::DatabaseRaw< MinWriteSize >::flash_
private

目标 Flash 存储设备 (Target Flash storage device).

Definition at line 459 of file database.hpp.

◆ FLASH_HEADER

template<size_t MinWriteSize>
uint32_t LibXR::DatabaseRaw< MinWriteSize >::FLASH_HEADER
staticconstexprprivate
Initial value:
=
0x12345678 + LIBXR_DATABASE_VERSION

Flash 头部标识 (Flash header identifier).

Definition at line 330 of file database.hpp.

◆ recycle_threshold_

template<size_t MinWriteSize>
size_t LibXR::DatabaseRaw< MinWriteSize >::recycle_threshold_ = 0
private

回收阈值 (Recycle threshold).

Definition at line 458 of file database.hpp.

◆ write_buffer_

template<size_t MinWriteSize>
uint8_t LibXR::DatabaseRaw< MinWriteSize >::write_buffer_[MinWriteSize]
private

写入缓冲区 (Write buffer).

Definition at line 461 of file database.hpp.


The documentation for this class was generated from the following file: