[tarantool-patches] Re: [PATCH 2/2] swim: introduce generation

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Sat Jun 22 01:00:23 MSK 2019


We have decided in a chat, that a user should be
able to get separately 'generation', 'version', and
accumulated 'incarnation' as a binary merge of these
two values. It allows in simple cases do not care
about generation/version, and stick to the incarnation
only.

Concerning API. I suggest the following C API changes:

-	uint64_t
-	swim_member_incarnation(const struct swim_member *member);

+	struct swim_incarnation {
+		uint64_t generation;
+		uint64_t version;
+	};
+
+	int
+	swim_incarnation_cmp(const struct swim_incarnation *l,
+			     const struct swim_incarnation *r);
+
+	struct swim_incarnation
+	swim_member_incarnation(const struct swim_member *member);

struct swim_incarnation will be a public structure in order to
simplify working with C API. I am trying to avoid returning some
const char * or similarly abstract thing.



Lua API changes are different. I know, we've talked about
returning a binary string as an incarnation, but then we need
separate methods to take version and generation, and waste
memory on these temporary binary strings, useless for anything
but comparison. Worse, we will desync with C API.


I've found a revolutionary feature of Lua FFI which can help us
very much. It combines your 'merged' incarnation, and my 'totally
different numbers' incarnation. In Lua FFI you can define your
own comparison operators for C structs (just learned about that)!

Method member:incarnation() will return cdata struct swim_incarnation,
with ffi.metatype containing comparators. struct swim_incarnation
will be initialized in Lua like this:


	ffi = require('ffi')
	ffi.cdef[[
		struct swim_incarnation {
			uint64_t generation;
			uint64_t version;
		};
	]]
	inc_t = ffi.typeof('struct swim_incarnation')
	inc_mt = {
		__eq = function(l, r)
			return l.generation == r.generation and
			       l.version == r.version
		end,
		__lt = function(l, r)
			return l.generation < r.generation or
			       l.generation == r.generation and l.version < r.version
		end,
		__le = function(l, r)
			return l.generation < r.generation or
			       l.generation == r.generation and l.version <= r.version
		end,
	}
	ffi.metatype(inc_t, inc_mt)
	ia = ffi.new('struct swim_incarnation')
	ib = ffi.new('struct swim_incarnation')

ia and ib can be compared using just '< > <= >= == ~=' operators,
and at the same time you can access individual members!!!

What do you think? Both about C and Lua API changes.




More information about the Tarantool-patches mailing list