add check when BlockSet::free_chunk

This commit is contained in:
obdev
2023-02-17 07:47:52 +00:00
committed by ob-robot
parent eee31cadb7
commit b0b540090f
2 changed files with 17 additions and 13 deletions

View File

@ -157,7 +157,7 @@ struct AChunk {
OB_INLINE char *blk_data(const ABlock *block) const; OB_INLINE char *blk_data(const ABlock *block) const;
OB_INLINE void mark_unused_blk_offset_bit(int offset); OB_INLINE void mark_unused_blk_offset_bit(int offset);
OB_INLINE void unmark_unused_blk_offset_bit(int offset); OB_INLINE void unmark_unused_blk_offset_bit(int offset);
OB_INLINE bool is_all_blks_unused();
union { union {
uint32_t MAGIC_CODE_; uint32_t MAGIC_CODE_;
struct { struct {
@ -361,6 +361,20 @@ void AChunk::unmark_unused_blk_offset_bit(int offset)
unused_blk_bs_.unset(offset); unused_blk_bs_.unset(offset);
} }
bool AChunk::is_all_blks_unused()
{
bool ret = false;
if (0 != washed_size_) {
auto blk_bs = blk_bs_;
blk_bs.combine(unused_blk_bs_,
[](int64_t left, int64_t right) { return (left ^ right); });
ret = -1 == blk_bs.min_bit_ge(0);
} else {
ret = -1 == blk_bs_.min_bit_ge(1);
}
return ret;
}
ABlock *AChunk::offset2blk(int offset) const ABlock *AChunk::offset2blk(int offset) const
{ {
return (ABlock*)data_ + offset; return (ABlock*)data_ + offset;

View File

@ -172,19 +172,9 @@ void BlockSet::free_block(ABlock *const block)
// head won't been NULL, // head won't been NULL,
if (head != NULL) { if (head != NULL) {
head->in_use_ = false; head->in_use_ = false;
bool all_blocks_unused = false;
// copy a temp // copy a temp
chunk->mark_unused_blk_offset_bit(chunk->blk_offset(head)); chunk->mark_unused_blk_offset_bit(chunk->blk_offset(head));
if (0 != chunk->washed_size_) { if (chunk->is_all_blks_unused()) {
auto blk_bs = chunk->blk_bs_;
blk_bs.combine(chunk->unused_blk_bs_,
[](int64_t left, int64_t right) { return (left ^ right); });
all_blocks_unused = -1 == blk_bs.min_bit_ge(0);
} else {
all_blocks_unused = -1 == chunk->blk_bs_.min_bit_ge(1);
}
if (all_blocks_unused) {
if (0 != chunk->washed_size_) { if (0 != chunk->washed_size_) {
int offset = 0; int offset = 0;
do { do {
@ -348,7 +338,7 @@ void BlockSet::free_chunk(AChunk *const chunk)
abort_unless(NULL != chunk->next_); abort_unless(NULL != chunk->next_);
abort_unless(NULL != chunk->prev_); abort_unless(NULL != chunk->prev_);
abort_unless(NULL != clist_); abort_unless(NULL != clist_);
abort_unless(chunk->is_all_blks_unused());
if (chunk == clist_) { if (chunk == clist_) {
clist_ = clist_->next_; clist_ = clist_->next_;
} }