Cell * cell_get_next (Cell *in_cell) { if (cell_size(in_cell) == 0) { return NULL; } if (in_cell->next != NULL) { return in_cell->next; } offset ofs = offset_make_relative(cell_get_offset(in_cell), cell_size(in_cell)); if (!offset_is_valid(ofs)) { return NULL; } if (!bin_within(cell_get_bin(in_cell), ofs)) { return NULL; } Cell *next = cell_get(cell_get_hive(in_cell), cell_get_bin(in_cell), ofs); in_cell->next = next; return next; }
gboolean cell_is_valid(Cell *in_cell) { if (in_cell == NULL) { return FALSE; } if (cell_check_mark(in_cell, CELL_FLAG_VALID)) { return TRUE; } if (!offset_is_valid(cell_get_offset(in_cell))) return FALSE; cell_set_mark(in_cell, CELL_FLAG_VALID); return TRUE; }
Cell * cell_alloc (Hive *hdesc, offset ofs, int size) { Cell *ret_val = NULL; int required_size = size + sizeof (struct CellHeader); rra_debug("Allocating new cell of size %d", size); if (hive_get_state(hdesc) & HMODE_NOALLOC) { rra_warning( _("Hive is in no-allocation mode, can't allocate blocks.")); return NULL; } /* Check current page first */ if (offset_is_valid(ofs)) { Bin *p = hive_find_bin (hdesc, ofs); ret_val = bin_find_free_cell (p, required_size); } /* Then check whole hive */ if (!ret_val) { ret_val = hive_find_free_cell (hdesc, required_size); } if (ret_val) { cell_split (ret_val, size); get_data(ret_val)->head.size = -get_data(ret_val)->head.size; cell_clear (ret_val); bin_set_dirty(cell_get_bin(ret_val)); } else { rra_warning(N_("failed to alloc %d bytes."), size); } return ret_val; }
static gboolean cell_split (Cell *in_cell, guint32 len) { rra_debug("Spliting cell %#010x with length %d", offset_to_begin(cell_get_offset(in_cell)), len); if (cell_is_allocd (in_cell)) { return FALSE; } if (cell_get_data_length (in_cell) < len) { return FALSE; } int new_size = len + sizeof (struct CellHeader); if (new_size % 8) new_size += 8 - (new_size % 8); /* If a secondary cell is large enough split in_cell and make a new * one */ if (cell_size (in_cell) - new_size >= HBB_MIN_LEN) { offset new_ofs = offset_make_relative(cell_get_offset(in_cell), new_size); if (offset_is_valid(new_ofs)) { cell_init(cell_get_hive(in_cell), cell_get_bin(in_cell), new_ofs, cell_size(in_cell) - new_size); get_data(in_cell)->head.size = new_size; in_cell->next = NULL; } } return TRUE; }
bool Q::is_valid() { return length_is_valid() && offset_is_valid(); }