[tarantool-patches] [PATCH 07/10] swim: pairs() function to iterate over member table
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Wed May 15 22:36:44 MSK 2019
The last patch in the series of Lua bindings exposure exposes
iterators API to be able to iterate over a member table in a
'for' loop like it would just a Lua table.
Part of #3234
---
src/lua/swim.lua | 34 ++++++++++++++++++
test/swim/swim.result | 78 +++++++++++++++++++++++++++++++++++++++++
test/swim/swim.test.lua | 15 ++++++++
3 files changed, 127 insertions(+)
diff --git a/src/lua/swim.lua b/src/lua/swim.lua
index e40edda18..6e55ffeba 100644
--- a/src/lua/swim.lua
+++ b/src/lua/swim.lua
@@ -557,6 +557,39 @@ local function swim_set_payload(s, payload)
return true
end
+--
+-- Lua pairs() or similar function should return 3 values:
+-- iterator function, iterator object, a key before first. This is
+-- iterator function. On each iteration it returns UUID as a key,
+-- member object as a value.
+--
+local function swim_pairs_next(ctx)
+ if ctx.swim.ptr == nil then
+ return swim_error_deleted()
+ end
+ local iterator = ctx.iterator
+ local m = capi.swim_iterator_next(iterator)
+ if m ~= nil then
+ m = swim_member_wrap(m)
+ return m:uuid(), m
+ end
+ capi.swim_iterator_close(ffi.gc(iterator, nil))
+ ctx.iterator = nil
+end
+
+--
+-- Pairs() to use in 'for' cycles.
+--
+local function swim_pairs(s)
+ local ptr = swim_check_instance(s, 'swim:pairs')
+ local iterator = capi.swim_iterator_open(ptr)
+ if iterator == nil then
+ return nil, box.error.last()
+ end
+ ffi.gc(iterator, capi.swim_iterator_close)
+ return swim_pairs_next, {swim = s, iterator = iterator}, nil
+end
+
--
-- Normal metatable of a configured SWIM instance.
--
@@ -574,6 +607,7 @@ local swim_mt = {
member_by_uuid = swim_member_by_uuid,
set_payload_raw = swim_set_payload_raw,
set_payload = swim_set_payload,
+ pairs = swim_pairs,
},
__serialize = swim_serialize
}
diff --git a/test/swim/swim.result b/test/swim/swim.result
index 4cf5c7f90..d0838af48 100644
--- a/test/swim/swim.result
+++ b/test/swim/swim.result
@@ -728,6 +728,84 @@ s1:delete()
s2:delete()
---
...
+--
+-- Iterators.
+--
+function iterate() local t = {} for k, v in s:pairs() do table.insert(t, {k, v}) end return t end
+---
+...
+s = swim.new()
+---
+...
+iterate()
+---
+- error: '[string "function iterate() local t = {} for k, v in s..."]:1: attempt to
+ call method ''pairs'' (a nil value)'
+...
+s:cfg({uuid = uuid(1), uri = uri(), gc_mode = 'off'})
+---
+- true
+...
+s.pairs()
+---
+- error: 'builtin/swim.lua:<line>: swim:pairs: first argument is not a SWIM instance'
+...
+iterate()
+---
+- - - 00000000-0000-1000-8000-000000000001
+ - uri: 127.0.0.1:<port>
+ status: alive
+ incarnation: 1
+ uuid: 00000000-0000-1000-8000-000000000001
+ payload_size: 0
+...
+s:add_member({uuid = uuid(2), uri = uri()})
+---
+- true
+...
+iterate()
+---
+- - - 00000000-0000-1000-8000-000000000002
+ - uri: 127.0.0.1:<port>
+ status: alive
+ incarnation: 0
+ uuid: 00000000-0000-1000-8000-000000000002
+ payload_size: 0
+ - - 00000000-0000-1000-8000-000000000001
+ - uri: 127.0.0.1:<port>
+ status: alive
+ incarnation: 1
+ uuid: 00000000-0000-1000-8000-000000000001
+ payload_size: 0
+...
+s:add_member({uuid = uuid(3), uri = uri()})
+---
+- true
+...
+iterate()
+---
+- - - 00000000-0000-1000-8000-000000000001
+ - uri: 127.0.0.1:<port>
+ status: alive
+ incarnation: 1
+ uuid: 00000000-0000-1000-8000-000000000001
+ payload_size: 0
+ - - 00000000-0000-1000-8000-000000000003
+ - uri: 127.0.0.1:<port>
+ status: alive
+ incarnation: 0
+ uuid: 00000000-0000-1000-8000-000000000003
+ payload_size: 0
+ - - 00000000-0000-1000-8000-000000000002
+ - uri: 127.0.0.1:<port>
+ status: alive
+ incarnation: 0
+ uuid: 00000000-0000-1000-8000-000000000002
+ payload_size: 0
+...
+s:delete()
+---
+...
test_run:cmd("clear filter")
---
- true
diff --git a/test/swim/swim.test.lua b/test/swim/swim.test.lua
index 8e7b426fe..9f237a540 100644
--- a/test/swim/swim.test.lua
+++ b/test/swim/swim.test.lua
@@ -244,4 +244,19 @@ s1_view:incarnation()
s1:delete()
s2:delete()
+--
+-- Iterators.
+--
+function iterate() local t = {} for k, v in s:pairs() do table.insert(t, {k, v}) end return t end
+s = swim.new()
+iterate()
+s:cfg({uuid = uuid(1), uri = uri(), gc_mode = 'off'})
+s.pairs()
+iterate()
+s:add_member({uuid = uuid(2), uri = uri()})
+iterate()
+s:add_member({uuid = uuid(3), uri = uri()})
+iterate()
+s:delete()
+
test_run:cmd("clear filter")
--
2.20.1 (Apple Git-117)
More information about the Tarantool-patches
mailing list