/* * list_insert_after -- (internal) insert element at offset after an element */ static size_t list_insert_after(PMEMobjpool *pop, struct redo_log *redo, size_t redo_index, struct list_args_insert *args, struct list_args_common *args_common, uint64_t *next_offset, uint64_t *prev_offset) { LOG(15, NULL); /* current->next = dest->next and current->prev = dest */ *next_offset = args->dest_entry_ptr->pe_next.off; *prev_offset = args->dest.off; /* dest->next = current and dest->next->prev = current */ uint64_t dest_next_off = args->dest.off + NEXT_OFF; u64_add_offset(&dest_next_off, args_common->pe_offset); uint64_t dest_next_prev_off = args->dest_entry_ptr->pe_next.off + PREV_OFF; u64_add_offset(&dest_next_prev_off, args_common->pe_offset); redo_log_store(pop->redo, redo, redo_index + 0, dest_next_off, args_common->obj_doffset); redo_log_store(pop->redo, redo, redo_index + 1, dest_next_prev_off, args_common->obj_doffset); return redo_index + 2; }
/* * list_insert_after -- (internal) insert element at offset after an element */ static size_t list_insert_after(PMEMobjpool *pop, struct operation_context *ctx, struct list_args_insert *args, struct list_args_common *args_common, uint64_t *next_offset, uint64_t *prev_offset) { LOG(15, NULL); /* current->next = dest->next and current->prev = dest */ *next_offset = args->dest_entry_ptr->pe_next.off; *prev_offset = args->dest.off; /* dest->next = current and dest->next->prev = current */ uint64_t dest_next_off = args->dest.off + NEXT_OFF; u64_add_offset(&dest_next_off, args_common->pe_offset); uint64_t dest_next_prev_off = args->dest_entry_ptr->pe_next.off + PREV_OFF; u64_add_offset(&dest_next_prev_off, args_common->pe_offset); void *dest_next_ptr = (char *)pop + dest_next_off; void *dest_next_prev_ptr = (char *)pop + dest_next_prev_off; operation_add_entry(ctx, dest_next_ptr, args_common->obj_doffset, ULOG_OPERATION_SET); operation_add_entry(ctx, dest_next_prev_ptr, args_common->obj_doffset, ULOG_OPERATION_SET); return 0; }
/* * list_fill_entry_redo_log -- (internal) fill new entry using redo log * * Used to update entry in existing object. */ static size_t list_fill_entry_redo_log(PMEMobjpool *pop, struct redo_log *redo, size_t redo_index, struct list_args_common *args, uint64_t next_offset, uint64_t prev_offset, int set_uuid) { LOG(15, NULL); struct pmem_ops *ops = &pop->p_ops; ASSERTne(args->entry_ptr, NULL); ASSERTne(args->obj_doffset, 0); if (set_uuid) { VALGRIND_ADD_TO_TX(&(args->entry_ptr->pe_next.pool_uuid_lo), sizeof(args->entry_ptr->pe_next.pool_uuid_lo)); VALGRIND_ADD_TO_TX(&(args->entry_ptr->pe_prev.pool_uuid_lo), sizeof(args->entry_ptr->pe_prev.pool_uuid_lo)); /* don't need to fill pool uuid using redo log */ args->entry_ptr->pe_next.pool_uuid_lo = pop->uuid_lo; args->entry_ptr->pe_prev.pool_uuid_lo = pop->uuid_lo; VALGRIND_REMOVE_FROM_TX( &(args->entry_ptr->pe_next.pool_uuid_lo), sizeof(args->entry_ptr->pe_next.pool_uuid_lo)); VALGRIND_REMOVE_FROM_TX( &(args->entry_ptr->pe_prev.pool_uuid_lo), sizeof(args->entry_ptr->pe_prev.pool_uuid_lo)); pmemops_persist(ops, args->entry_ptr, sizeof(*args->entry_ptr)); } else { ASSERTeq(args->entry_ptr->pe_next.pool_uuid_lo, pop->uuid_lo); ASSERTeq(args->entry_ptr->pe_prev.pool_uuid_lo, pop->uuid_lo); } /* set current->next and current->prev using redo log */ uint64_t next_off_off = args->obj_doffset + NEXT_OFF; uint64_t prev_off_off = args->obj_doffset + PREV_OFF; u64_add_offset(&next_off_off, args->pe_offset); u64_add_offset(&prev_off_off, args->pe_offset); redo_log_store(pop->redo, redo, redo_index + 0, next_off_off, next_offset); redo_log_store(pop->redo, redo, redo_index + 1, prev_off_off, prev_offset); return redo_index + 2; }
/* * list_fill_entry_redo_log -- (internal) fill new entry using redo log * * Used to update entry in existing object. */ static size_t list_fill_entry_redo_log(PMEMobjpool *pop, struct operation_context *ctx, struct list_args_common *args, uint64_t next_offset, uint64_t prev_offset, int set_uuid) { LOG(15, NULL); struct pmem_ops *ops = &pop->p_ops; ASSERTne(args->entry_ptr, NULL); ASSERTne(args->obj_doffset, 0); if (set_uuid) { VALGRIND_ADD_TO_TX(&(args->entry_ptr->pe_next.pool_uuid_lo), sizeof(args->entry_ptr->pe_next.pool_uuid_lo)); VALGRIND_ADD_TO_TX(&(args->entry_ptr->pe_prev.pool_uuid_lo), sizeof(args->entry_ptr->pe_prev.pool_uuid_lo)); /* don't need to fill pool uuid using redo log */ args->entry_ptr->pe_next.pool_uuid_lo = pop->uuid_lo; args->entry_ptr->pe_prev.pool_uuid_lo = pop->uuid_lo; VALGRIND_REMOVE_FROM_TX( &(args->entry_ptr->pe_next.pool_uuid_lo), sizeof(args->entry_ptr->pe_next.pool_uuid_lo)); VALGRIND_REMOVE_FROM_TX( &(args->entry_ptr->pe_prev.pool_uuid_lo), sizeof(args->entry_ptr->pe_prev.pool_uuid_lo)); pmemops_persist(ops, args->entry_ptr, sizeof(*args->entry_ptr)); } else { ASSERTeq(args->entry_ptr->pe_next.pool_uuid_lo, pop->uuid_lo); ASSERTeq(args->entry_ptr->pe_prev.pool_uuid_lo, pop->uuid_lo); } /* set current->next and current->prev using redo log */ uint64_t next_off_off = args->obj_doffset + NEXT_OFF; uint64_t prev_off_off = args->obj_doffset + PREV_OFF; u64_add_offset(&next_off_off, args->pe_offset); u64_add_offset(&prev_off_off, args->pe_offset); void *next_ptr = (char *)pop + next_off_off; void *prev_ptr = (char *)pop + prev_off_off; operation_add_entry(ctx, next_ptr, next_offset, ULOG_OPERATION_SET); operation_add_entry(ctx, prev_ptr, prev_offset, ULOG_OPERATION_SET); return 0; }
/* * list_remove_single -- (internal) remove element from single list */ static size_t list_remove_single(PMEMobjpool *pop, struct operation_context *ctx, struct list_args_remove *args) { LOG(15, NULL); if (args->entry_ptr->pe_next.off == args->obj_doffset) { /* only one element on list */ ASSERTeq(args->head->pe_first.off, args->obj_doffset); ASSERTeq(args->entry_ptr->pe_prev.off, args->obj_doffset); return list_update_head(pop, ctx, args->head, 0); } else { /* set next->prev = prev and prev->next = next */ uint64_t next_off = args->entry_ptr->pe_next.off; uint64_t next_prev_off = next_off + PREV_OFF; u64_add_offset(&next_prev_off, args->pe_offset); uint64_t prev_off = args->entry_ptr->pe_prev.off; uint64_t prev_next_off = prev_off + NEXT_OFF; u64_add_offset(&prev_next_off, args->pe_offset); void *prev_ptr = (char *)pop + next_prev_off; void *next_ptr = (char *)pop + prev_next_off; operation_add_entry(ctx, prev_ptr, prev_off, ULOG_OPERATION_SET); operation_add_entry(ctx, next_ptr, next_off, ULOG_OPERATION_SET); if (args->head->pe_first.off == args->obj_doffset) { /* removing element is the first one */ return list_update_head(pop, ctx, args->head, next_off); } else { return 0; } } }
/* * list_remove_single -- (internal) remove element from single list */ static size_t list_remove_single(PMEMobjpool *pop, struct redo_log *redo, size_t redo_index, struct list_args_remove *args) { LOG(15, NULL); if (args->entry_ptr->pe_next.off == args->obj_doffset) { /* only one element on list */ ASSERTeq(args->head->pe_first.off, args->obj_doffset); ASSERTeq(args->entry_ptr->pe_prev.off, args->obj_doffset); return list_update_head(pop, redo, redo_index, args->head, 0); } else { /* set next->prev = prev and prev->next = next */ uint64_t next_off = args->entry_ptr->pe_next.off; uint64_t next_prev_off = next_off + PREV_OFF; u64_add_offset(&next_prev_off, args->pe_offset); uint64_t prev_off = args->entry_ptr->pe_prev.off; uint64_t prev_next_off = prev_off + NEXT_OFF; u64_add_offset(&prev_next_off, args->pe_offset); redo_log_store(pop->redo, redo, redo_index + 0, next_prev_off, prev_off); redo_log_store(pop->redo, redo, redo_index + 1, prev_next_off, next_off); redo_index += 2; if (args->head->pe_first.off == args->obj_doffset) { /* removing element is the first one */ return list_update_head(pop, redo, redo_index, args->head, next_off); } else { return redo_index; } } }