/* * pmemobj_list_move -- moves object between lists */ int pmemobj_list_move(PMEMobjpool *pop, size_t pe_old_offset, void *head_old, size_t pe_new_offset, void *head_new, PMEMoid dest, int before, PMEMoid oid) { LOG(3, "pop %p pe_old_offset %zu pe_new_offset %zu" " head_old %p head_new %p dest.off 0x%016jx" " before %d oid.off 0x%016jx", pop, pe_old_offset, pe_new_offset, head_old, head_new, dest.off, before, oid.off); /* log notice message if used inside a transaction */ _POBJ_DEBUG_NOTICE_IN_TX(); ASSERT(OBJ_OID_IS_VALID(pop, oid)); ASSERT(OBJ_OID_IS_VALID(pop, dest)); if (pe_old_offset >= pop->size) { ERR("pe_old_offset (%lu) too big", pe_old_offset); return EINVAL; } if (pe_new_offset >= pop->size) { ERR("pe_new_offset (%lu) too big", pe_new_offset); return EINVAL; } return list_move(pop, pe_old_offset, head_old, pe_new_offset, head_new, dest, before, oid); }
/* * pmemobj_list_insert -- adds object to a list */ int pmemobj_list_insert(PMEMobjpool *pop, size_t pe_offset, void *head, PMEMoid dest, int before, PMEMoid oid) { LOG(3, "pop %p pe_offset %zu head %p dest.off 0x%016jx before %d" " oid.off 0x%016jx", pop, pe_offset, head, dest.off, before, oid.off); /* log notice message if used inside a transaction */ _POBJ_DEBUG_NOTICE_IN_TX(); ASSERT(OBJ_OID_IS_VALID(pop, oid)); ASSERT(OBJ_OID_IS_VALID(pop, dest)); return list_insert(pop, pe_offset, head, dest, before, oid); }
/* * pmemobj_list_remove -- removes object from a list */ int pmemobj_list_remove(PMEMobjpool *pop, size_t pe_offset, void *head, PMEMoid oid, int free) { LOG(3, "pop %p pe_offset %zu head %p oid.off 0x%016jx free %d", pop, pe_offset, head, oid.off, free); /* log notice message if used inside a transaction */ _POBJ_DEBUG_NOTICE_IN_TX(); ASSERT(OBJ_OID_IS_VALID(pop, oid)); if (pe_offset >= pop->size) { ERR("pe_offset (%lu) too big", pe_offset); return EINVAL; } if (free) { struct oob_header *pobj = OOB_HEADER_FROM_OID(pop, oid); ASSERT(pobj->data.user_type < PMEMOBJ_NUM_OID_TYPES); void *lhead = &pop->store->bytype[pobj->data.user_type].head; return list_remove_free(pop, lhead, pe_offset, head, &oid); } else return list_remove(pop, pe_offset, head, oid); }
/* * pmemobj_zrealloc -- resizes an existing object, any new space is zeroed. */ int pmemobj_zrealloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size, unsigned int type_num) { LOG(3, "pop %p oid.off 0x%016jx size %zu type_num %u", pop, oidp->off, size, type_num); /* log notice message if used inside a transaction */ _POBJ_DEBUG_NOTICE_IN_TX(); ASSERT(OBJ_OID_IS_VALID(pop, *oidp)); return obj_realloc_common(pop, pop->store, oidp, size, type_num, constructor_zalloc, constructor_zrealloc); }
/* * pmemobj_list_insert_new -- adds new object to a list */ PMEMoid pmemobj_list_insert_new(PMEMobjpool *pop, size_t pe_offset, void *head, PMEMoid dest, int before, size_t size, unsigned int type_num, void (*constructor)(PMEMobjpool *pop, void *ptr, void *arg), void *arg) { LOG(3, "pop %p pe_offset %zu head %p dest.off 0x%016jx before %d" " size %zu type_num %u", pop, pe_offset, head, dest.off, before, size, type_num); /* log notice message if used inside a transaction */ _POBJ_DEBUG_NOTICE_IN_TX(); ASSERT(OBJ_OID_IS_VALID(pop, dest)); if (type_num >= PMEMOBJ_NUM_OID_TYPES) { errno = EINVAL; ERR("!pmemobj_list_insert_new"); LOG(2, "type_num has to be in range [0, %i]", PMEMOBJ_NUM_OID_TYPES - 1); return OID_NULL; } if (size > PMEMOBJ_MAX_ALLOC_SIZE) { ERR("requested size too large"); errno = ENOMEM; return OID_NULL; } if (pe_offset >= pop->size) { ERR("pe_offset (%lu) too big", pe_offset); errno = EINVAL; return OID_NULL; } struct list_head *lhead = &pop->store->bytype[type_num].head; struct carg_bytype carg; carg.user_type = (type_num_t)type_num; carg.constructor = constructor; carg.arg = arg; carg.zero_init = 0; PMEMoid retoid = OID_NULL; list_insert_new(pop, lhead, pe_offset, head, dest, before, size, constructor_alloc_bytype, &carg, &retoid); return retoid; }
/* * pmemobj_alloc_usable_size -- returns usable size of object */ size_t pmemobj_alloc_usable_size(PMEMoid oid) { LOG(3, "oid.off 0x%016jx", oid.off); if (oid.off == 0) return 0; PMEMobjpool *pop = cuckoo_get(pools, oid.pool_uuid_lo); ASSERTne(pop, NULL); ASSERT(OBJ_OID_IS_VALID(pop, oid)); return (pmalloc_usable_size(pop, oid.off - OBJ_OOB_SIZE) - OBJ_OOB_SIZE); }
/* * pmemobj_free -- frees an existing object */ void pmemobj_free(PMEMoid *oidp) { LOG(3, "oid.off 0x%016jx", oidp->off); /* log notice message if used inside a transaction */ _POBJ_DEBUG_NOTICE_IN_TX(); if (oidp->off == 0) return; PMEMobjpool *pop = cuckoo_get(pools, oidp->pool_uuid_lo); ASSERTne(pop, NULL); ASSERT(OBJ_OID_IS_VALID(pop, *oidp)); obj_free(pop, oidp); }
/* * pmemobj_zrealloc -- resizes an existing object, any new space is zeroed. */ int pmemobj_zrealloc(PMEMobjpool *pop, PMEMoid *oidp, size_t size, unsigned int type_num) { ASSERTne(oidp, NULL); LOG(3, "pop %p oid.off 0x%016jx size %zu type_num %u", pop, oidp->off, size, type_num); /* log notice message if used inside a transaction */ _POBJ_DEBUG_NOTICE_IN_TX(); ASSERT(OBJ_OID_IS_VALID(pop, *oidp)); if (type_num >= PMEMOBJ_NUM_OID_TYPES) { errno = EINVAL; ERR("invalid type_num %u", type_num); return -1; } return obj_realloc_common(pop, pop->store, oidp, size, (type_num_t)type_num, 1); }
/* * pmemobj_next - returns next object of specified type */ PMEMoid pmemobj_next(PMEMoid oid) { LOG(3, "oid.off 0x%016jx", oid.off); if (oid.off == 0) return OID_NULL; PMEMobjpool *pop = cuckoo_get(pools, oid.pool_uuid_lo); ASSERTne(pop, NULL); ASSERT(OBJ_OID_IS_VALID(pop, oid)); struct oob_header *pobj = OOB_HEADER_FROM_OID(pop, oid); uint16_t user_type = pobj->data.user_type; ASSERT(user_type < PMEMOBJ_NUM_OID_TYPES); if (pobj->oob.pe_next.off != pop->store->bytype[user_type].head.pe_first.off) return pobj->oob.pe_next; else return OID_NULL; }