Пример #1
0
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");
	}
}
Пример #2
0
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;
}
Пример #3
0
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)];
}
Пример #4
0
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;
}