int block_next_lin(struct map_rect_priv *mr) { struct coord_rect r; for (;;) { block_lin_count++; block_mem+=sizeof(struct block *); mr->b.block_num++; if (! mr->b.block_num) mr->b.p=mr->file->begin+0x2000; else mr->b.p=mr->b.block_start+block_get_blocks(mr->b.b)*512; if (mr->b.p >= mr->file->end) { dbg(lvl_debug,"end of blocks %p vs %p\n", mr->b.p, mr->file->end); return 0; } mr->b.block_start=mr->b.p; mr->b.b=block_get(&mr->b.p); mr->b.p_start=mr->b.p; mr->b.end=mr->b.block_start+block_get_size(mr->b.b); if (block_get_count(mr->b.b) == -1) { dbg(lvl_warning,"empty blocks\n"); return 0; } block_get_r(mr->b.b, &r); if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->u.c_rect, &r)) { block_active_count++; block_active_mem+=block_get_blocks(mr->b.b)*512-sizeof(struct block *); dbg(lvl_debug,"block ok\n"); return 1; } dbg(lvl_info,"block not in cur_sel\n"); } }
int block_get_byindex(struct file *file, int idx, struct block_priv *blk) { dbg(lvl_debug,"idx=%d\n", idx); blk->b=block_get_byid(file, idx, &blk->p); blk->block_start=(unsigned char *)(blk->b); blk->p_start=blk->p; blk->end=blk->block_start+block_get_size(blk->b); return 1; }
void *bucket_split(Bucket *bucket, Bucket *buckets, uint32_t bucket_index, Heap *heap, uint32_t block_size) { uint32_t first_block_index = bucket_get_first_block_index(bucket); Block *first_block_header = block_get_header(heap, first_block_index); uint32_t first_block_size = block_get_size(first_block_header); // Calculate the remaining size of the first block. uint32_t rem_size = first_block_size - block_size; // Create a new header for the new block we have created. uint32_t alloc_index = first_block_index + block_size_to_bytes(rem_size); Block *alloc_header = block_get_header(heap, alloc_index); uint32_t next_block_index = block_get_next_index(first_block_header); Block *next_block_header = block_get_header(heap, next_block_index); // If we are simply replacing the block, we don't need to update the previous // and next indexes of memory, since they will not change: no blocks are // being created or merged. if (rem_size != 0) { block_set_size(alloc_header, block_size); block_set_prev_index(alloc_header, first_block_index); block_set_next_index(alloc_header, next_block_index); } block_set_allocated(alloc_header, true); // If there is no left over space in the block, there is no need to split it. // Simply remove this block from the bucket and return an address to it. if (rem_size == 0) { bucket_remove(bucket, heap, first_block_index); return &heap->memory[block_index_skip_header(alloc_index)]; } // Update the header of the remaining part of the block. block_set_next_index(first_block_header, alloc_index); block_set_size(first_block_header, rem_size); // Update the header of the next block. next_block_header = block_get_header(heap, next_block_index); block_set_prev_index(next_block_header, alloc_index); // If the remaining space from the block is now too small for its bucket, it // is removed from this bucket and reinserted into the bucket structure. uint32_t first_block_bucket_index = block_get_bucket_index( first_block_header); if (first_block_bucket_index != bucket_index) { bucket_remove(bucket, heap, first_block_index); bucket_insert(&buckets[first_block_bucket_index], heap, first_block_index); } return &heap->memory[block_index_skip_header(alloc_index)]; }
int block_next(struct map_rect_priv *mr) { int blk_num,coord,r_h,r_w; struct block_bt_priv *bt=&mr->b.bt; struct coord_rect r; if (!mr->b.binarytree || ! mr->cur_sel) return block_next_lin(mr); for (;;) { if (! bt->p) { dbg(lvl_debug,"block 0x%x\n", bt->next); if (bt->next == -1) return 0; bt->b=block_get_byid(mr->file, bt->next, &bt->p); bt->end=(unsigned char *)mr->b.bt.b+block_get_size(mr->b.bt.b); bt->next=block_get_next(bt->b); bt->order=0; dbg(lvl_debug,"size 0x%x next 0x%x\n", block_get_size(bt->b), block_get_next(bt->b)); if (! mr->b.bt.block_count) { #if 0 if (debug) { printf("idx rect "); block_rect_print(&mr->b.bt.b->r); } #endif block_get_r(bt->b, &bt->r); bt->r_curr=bt->r; coord=get_u32(&mr->b.bt.p); } else { bt->p=(unsigned char *)bt->b+0xc; } bt->block_count++; } while (mr->b.bt.p < mr->b.bt.end) { block_idx_count++; blk_num=get_u32(&mr->b.bt.p); coord=get_u32(&mr->b.bt.p); block_mem+=8; dbg(lvl_debug,"%p vs %p coord 0x%x ", mr->b.bt.end, mr->b.bt.p, coord); dbg(lvl_debug,"block 0x%x", blk_num); r_w=bt->r_curr.rl.x-bt->r_curr.lu.x; r_h=bt->r_curr.lu.y-bt->r_curr.rl.y; #if 0 if (debug) { printf(" rect1 "); block_rect_print(&bt->r_curr); printf(" %dx%d", r_w, r_h); } #endif mr->b.b=NULL; if (blk_num != -1) { block_mem+=8; if (coord_rect_overlap(&mr->cur_sel->u.c_rect, &bt->r_curr)) { mr->b.b=block_get_byid(mr->file, blk_num, &mr->b.p); mr->b.block_num=blk_num; dbg_assert(mr->b.b != NULL); mr->b.block_start=(unsigned char *)(mr->b.b); mr->b.p_start=mr->b.p; mr->b.end=mr->b.block_start+block_get_size(mr->b.b); block_get_r(mr->b.b, &r); block_rect_same(&r, &bt->r_curr); } } if (coord != -1) { bt->stack[bt->stackp]=bt->r_curr; if (r_w > r_h) { bt->r_curr.rl.x=coord; bt->stack[bt->stackp].lu.x=coord+1; } else { bt->r_curr.lu.y=coord; bt->stack[bt->stackp].rl.y=coord+1; } bt->stackp++; dbg_assert(bt->stackp < BT_STACK_SIZE); } else { if (bt->stackp) { bt->stackp--; bt->r_curr=bt->stack[bt->stackp]; } else { bt->r_curr=bt->r; bt->order++; if (bt->order > 100) return 0; } } if (mr->b.b) { block_active_count++; block_active_mem+=block_get_blocks(mr->b.b)*512; return 1; } } bt->p=NULL; } return 0; }