diff --git a/src/box/memtx_allocator.h b/src/box/memtx_allocator.h index eeb8492cb19be21c36c6737b586764dcede54213..fdddef0bf33c3235b97f81387dd2ab2a8b48edd0 100644 --- a/src/box/memtx_allocator.h +++ b/src/box/memtx_allocator.h @@ -129,13 +129,13 @@ class MemtxAllocator { * it. Otherwise, it's put in the garbage collection list to be free as * soon as the last snapshot using it is destroyed. */ - static void free_tuple(struct tuple *tuple, bool is_temporary) + static void free_tuple(struct tuple *tuple) { struct memtx_tuple *memtx_tuple = container_of( tuple, struct memtx_tuple, base); if (mode != MEMTX_ENGINE_DELAYED_FREE || memtx_tuple->version == snapshot_version || - is_temporary) { + tuple_has_flag(tuple, TUPLE_IS_TEMPORARY)) { immediate_free_tuple(memtx_tuple); } else { delayed_free_tuple(memtx_tuple); diff --git a/src/box/memtx_engine.cc b/src/box/memtx_engine.cc index 9a7258922c6cc8fe74b28b2b197ffdd45bb78bce..7276662ba892b104d0b9cd98994f8b6fcc5a4bcc 100644 --- a/src/box/memtx_engine.cc +++ b/src/box/memtx_engine.cc @@ -1457,6 +1457,8 @@ memtx_tuple_new_raw_impl(struct tuple_format *format, const char *data, } tuple_create(tuple, 0, tuple_format_id(format), data_offset, tuple_len, make_compact); + if (format->is_temporary) + tuple_set_flag(tuple, TUPLE_IS_TEMPORARY); tuple_format_ref(format); raw = (char *) tuple + data_offset; field_map_build(&builder, raw - field_map_size); @@ -1480,7 +1482,7 @@ memtx_tuple_delete(struct tuple_format *format, struct tuple *tuple) { assert(tuple_is_unreferenced(tuple)); say_debug("%s(%p)", __func__, tuple); - MemtxAllocator<ALLOC>::free_tuple(tuple, format->is_temporary); + MemtxAllocator<ALLOC>::free_tuple(tuple); tuple_format_unref(format); } diff --git a/src/box/tuple.h b/src/box/tuple.h index 4c5c99de0f64753068e8cbc940190ad3303ad406..ab5592e834c84a6b740cc78216a11196a4629727 100644 --- a/src/box/tuple.h +++ b/src/box/tuple.h @@ -313,6 +313,11 @@ enum tuple_flag { * be clarified by transaction engine. */ TUPLE_IS_DIRTY = 1, + /** + * The tuple belongs to a temporary space so it can be freed + * immediately while a snapshot is in progress. + */ + TUPLE_IS_TEMPORARY = 2, tuple_flag_MAX, }; @@ -682,7 +687,8 @@ tuple_delete(struct tuple *tuple) { say_debug("%s(%p)", __func__, tuple); assert(tuple->local_refs == 0); - assert(tuple->flags == 0); + assert(!tuple_has_flag(tuple, TUPLE_HAS_UPLOADED_REFS)); + assert(!tuple_has_flag(tuple, TUPLE_IS_DIRTY)); struct tuple_format *format = tuple_format(tuple); format->vtab.tuple_delete(format, tuple); }