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 325 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 332 of file database.hpp.

333 {
334 MAIN = 0,
335 BACKUP = 1
336 };
@ 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 968 of file database.hpp.

969 : recycle_threshold_(recycle_threshold), flash_(flash)
970 {
971 ASSERT(flash.MinEraseSize() * 2 <= flash_.Size());
972 ASSERT(flash_.MinWriteSize() <= MinWriteSize);
973 auto block_num = static_cast<size_t>(flash_.Size() / flash.MinEraseSize());
974 block_size_ = block_num / 2 * flash.MinEraseSize();
975 Init();
976 }
uint32_t block_size_
Flash 块大小 (Flash block size).
Definition database.hpp:457
void Init()
初始化数据库存储区,确保主备块正确 (Initialize database storage, ensuring main and backup blocks are valid).
Definition database.hpp:982
Flash & flash_
目标 Flash 存储设备 (Target Flash storage device).
Definition database.hpp:456
size_t recycle_threshold_
回收阈值 (Recycle threshold).
Definition database.hpp:455
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 956 of file database.hpp.

957 {
958 return AddKey(key.name_, key.raw_data_.addr_, key.raw_data_.size_);
959 }

◆ 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 558 of file database.hpp.

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

◆ 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 545 of file database.hpp.

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

◆ 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 471 of file database.hpp.

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

876 {
877 return static_cast<size_t>((size + MinWriteSize - 1) / MinWriteSize) * MinWriteSize;
878 }

◆ AvailableSize()

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

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

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

Definition at line 465 of file database.hpp.

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

◆ 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 813 of file database.hpp.

814 {
815 for (size_t i = 0; i < size; i += MinWriteSize)
816 {
817 flash_.Read(src_offset + i, {write_buffer_, MinWriteSize});
818 flash_.Write(dst_offset + i, {write_buffer_, MinWriteSize});
819 }
820 }
uint8_t write_buffer_[MinWriteSize]
写入缓冲区 (Write buffer).
Definition database.hpp:458
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 922 of file database.hpp.

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

◆ GetKeyData()

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

Definition at line 654 of file database.hpp.

655 {
656 KeyInfo key;
657 flash_.Read(offset, key);
658 return offset + AlignSize(sizeof(KeyInfo)) + AlignSize(key.GetNameLength());
659 }

◆ GetKeyName()

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

Definition at line 661 of file database.hpp.

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

◆ GetKeySize()

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

Definition at line 721 of file database.hpp.

722 {
723 KeyInfo key;
724 flash_.Read(offset, key);
725 return AlignSize(sizeof(KeyInfo)) + AlignSize(key.GetNameLength()) +
726 AlignSize(key.GetDataSize());
727 }

◆ GetLastKey()

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

Definition at line 736 of file database.hpp.

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

◆ GetNextKey()

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

Definition at line 729 of file database.hpp.

730 {
731 KeyInfo key;
732 flash_.Read(offset, key);
733 return offset + GetKeySize(offset);
734 }

◆ Init()

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

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

Definition at line 982 of file database.hpp.

983 {
984 if (!IsBlockInited(BlockType::BACKUP) || IsBlockError(BlockType::BACKUP))
985 {
986 InitBlock(BlockType::BACKUP);
987 }
988
989 if (!IsBlockInited(BlockType::MAIN) || IsBlockError(BlockType::MAIN))
990 {
991 if (IsBlockEmpty(BlockType::BACKUP))
992 {
993 InitBlock(BlockType::MAIN);
994 }
995 else
996 {
998 for (uint32_t i = 0; i < block_size_; i += MinWriteSize)
999 {
1000 flash_.Read(i + block_size_, {write_buffer_, MinWriteSize});
1001 flash_.Write(i, {write_buffer_, MinWriteSize});
1002 }
1003 }
1004 }
1005
1006 if (!IsBlockEmpty(BlockType::BACKUP))
1007 {
1008 InitBlock(BlockType::BACKUP);
1009 }
1010
1011 KeyInfo key;
1012 size_t key_offset = OFFSET_OF(FlashInfo, key);
1013 flash_.Read(key_offset, key);
1014 size_t need_cycle = 0;
1015 while (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.no_next_key))
1016 {
1017 key_offset = GetNextKey(key_offset);
1018 flash_.Read(key_offset, key);
1019 // TODO: 恢复损坏数据
1020 if (BlockBoolUtil<MinWriteSize>::ReadFlag(key.uninit))
1021 {
1022 InitBlock(BlockType::MAIN);
1023 break;
1024 }
1025 if (!BlockBoolUtil<MinWriteSize>::ReadFlag(key.available_flag))
1026 {
1027 need_cycle += 1;
1028 }
1029 }
1030
1031 if (need_cycle > recycle_threshold_)
1032 {
1033 Recycle();
1034 }
1035 }
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 663 of file database.hpp.

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

◆ IsBlockEmpty()

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

Definition at line 697 of file database.hpp.

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

◆ IsBlockError()

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

Definition at line 709 of file database.hpp.

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

◆ IsBlockInited()

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

Definition at line 685 of file database.hpp.

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

◆ KeyDataCompare()

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

Definition at line 758 of file database.hpp.

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

◆ KeyNameCompare() [1/2]

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

Definition at line 775 of file database.hpp.

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

◆ KeyNameCompare() [2/2]

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

Definition at line 791 of file database.hpp.

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

◆ 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 1057 of file database.hpp.

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

◆ Restore()

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

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

Definition at line 1041 of file database.hpp.

1042 {
1043 InitBlock(BlockType::MAIN);
1044 InitBlock(BlockType::BACKUP);
1045 }

◆ SearchKey()

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

Definition at line 822 of file database.hpp.

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

◆ 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 950 of file database.hpp.

951 {
952 memcpy(key.raw_data_.addr_, data.addr_, data.size_);
953 return SetKey(key.name_, data.addr_, data.size_);
954 }

◆ 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 611 of file database.hpp.

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

◆ 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 605 of file database.hpp.

606 {
607 size_t key_offset = SearchKey(name_offset, name_length);
608 return SetKeyCommon(key_offset, name_length, data, size);
609 }

◆ 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 576 of file database.hpp.

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

◆ 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 887 of file database.hpp.

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

Field Documentation

◆ block_size_

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

Flash 块大小 (Flash block size).

Definition at line 457 of file database.hpp.

◆ CHECKSUM_BYTE

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

校验字节 (Checksum byte).

Definition at line 330 of file database.hpp.

◆ flash_

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

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

Definition at line 456 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 327 of file database.hpp.

◆ recycle_threshold_

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

回收阈值 (Recycle threshold).

Definition at line 455 of file database.hpp.

◆ write_buffer_

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

写入缓冲区 (Write buffer).

Definition at line 458 of file database.hpp.


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