Skip to content

Instantly share code, notes, and snippets.

@kazupon
Created May 29, 2012 00:57
Show Gist options
  • Save kazupon/2821950 to your computer and use it in GitHub Desktop.
Save kazupon/2821950 to your computer and use it in GitHub Desktop.
-- global variables
kt = __kyototycoon__
db = kt.db
function toboolean (v)
return (type(v) == 'string' and v == 'true') or (type(v) == 'number' and v ~= 0) or (type(v) == 'boolean' and v)
end
function usage (outmap)
local buf = {}
table.insert(buf, 'usage:')
table.insert(buf, ' ktremotemgr script test pattern order rnd [true|false] etc [true|false] rnum [num]')
table.insert(buf, ' ktremotemgr script test pattern wicked it [num] rnum [num]')
table.insert(buf, '')
outmap.message = table.concat(buf, '\n')
return kt.RVSUCCESS
end
-- perform formatted output
function printf (format, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
if type(a) ~= 'number' then a = tostring(a) end
if type(b) ~= 'number' then b = tostring(b) end
if type(c) ~= 'number' then c = tostring(c) end
if type(d) ~= 'number' then d = tostring(d) end
if type(e) ~= 'number' then e = tostring(e) end
if type(f) ~= 'number' then f = tostring(f) end
if type(g) ~= 'number' then g = tostring(g) end
if type(h) ~= 'number' then h = tostring(h) end
if type(i) ~= 'number' then i = tostring(i) end
if type(j) ~= 'number' then j = tostring(j) end
if type(k) ~= 'number' then k = tostring(k) end
if type(l) ~= 'number' then l = tostring(l) end
if type(m) ~= 'number' then m = tostring(m) end
if type(n) ~= 'number' then n = tostring(n) end
if type(o) ~= 'number' then o = tostring(o) end
if type(p) ~= 'number' then p = tostring(p) end
kt.log('debug', string.format(format, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p))
end
-- print the error message of the database
function dberrprint (db, func)
local err = db:error()
printf('%s: %s: %s: %s', func, err:code(), err:name(), err:message())
end
-- print members of a database
function dbmetaprint (db, verbose)
if verbose then
local status = db:status()
if status then
for key, value in pairs(status) do
printf('%s: %s', key, value)
end
end
else
printf('count: %d', db:count())
printf('size: %d', db:size())
end
end
-- main routine
function main (inmap, outmap)
local pattern = inmap.pattern
if not pattern then return usage(outmap) end
local rv
if pattern == 'order' then
rv = runorder(inmap, outmap)
elseif pattern == 'wicked' then
rv = runwicked(inmap, outmap)
else
return usage(outmap)
end
collectgarbage('collect')
return rv
end
-- parse arguments of order command
function runorder (inmap, outmap)
local rnum = inmap.rnum and tonumber(inmap.rnum) or 0
local rnd = inmap.rnd and toboolean(inmap.rnd) or false
local etc = inmap.etc and toboolean(inmap.etc) or false
printf('runorder: rnum=%s, rnd=%s, etc=%s', rnum, rnd, etc)
if rnum < 1 then return usage(outmap) end
return procorder(rnum, rnd, etc, outmap)
end
-- parse arguments of wicked command
function runwicked (inmap, outmap)
local rnum = inmap.rnum and tonumber(inmap.rnum) or 0
local itnum = inmap.it and tonumber(inmap.it) or 0
printf('runwicked: rnum=%s, itnum=%s', rnum, itnum)
if rnum < 1 then return usage(outmap) end
return procwicked(rnum, itnum, outmap)
end
-- perform write command
function procorder (rnum, rnd, etc, outmap)
printf('<In-order Test> rnum=%s rnd=%s etc=%s', rnum, rnd, etc)
local err = false
local stime = kt.time()
for i = 1, rnum do
if err then break end
local key = string.format('%08d', rnd and math.random(rnum) or i)
if not db:set(key, key) then
dberrprint(db, "DB::set")
err = true
end
end
etime = kt.time()
dbmetaprint(db, false)
printf('time: %.3f', etime - stime)
if etc then
printf('adding records:')
stime = kt.time()
for i = 1, rnum do
if err then break end
local key = string.format('%08d', rnd and math.random(rnum) or i)
if not db:add(key, key) and db:error():code() ~= kt.Error.DUPREC then
dberrprint(db, 'DB::add')
err = true
end
end
etime = kt.time()
dbmetaprint(db, false)
printf('time: %.3f', etime - stime)
end
if etc then
printf('appending records:')
stime = kt.time()
for i = 1, rnum do
if err then break end
local key = string.format('%08d', rnd and math.random(rnum) or i)
if not db:append(key, key) then
dberrprint(db, 'DB::append')
err = true
end
end
etime = kt.time()
dbmetaprint(db, false)
printf('time: %.3f', etime - stime)
end
if etc then
printf('accepting visitors:')
stime = kt.time()
local cnt = 0
local function visit(key, value)
cnt = cnt + 1
local rv = kt.Visitor.NOP
if rnd then
local num = math.random(7)
if num == 1 then
rv = tostring(cnt)
elseif num == 2 then
rv = kt.Visitor.REMOVE
end
end
return rv
end
for i = 1, rnum do
if err then break end
local key = string.format('%08d', rnd and math.random(rnum) or i)
if not db:accept(key, visit, rnd) then
dberrprint(db, 'DB::append')
err = true
end
end
etime = kt.time()
dbmetaprint(db, false)
printf('time: %.3f', etime - stime)
end
printf('getting records:')
stime = kt.time()
for i = 1, rnum do
if err then break end
local key = string.format('%08d', rnd and math.random(rnum) or i)
if not db:get(key) and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'DB::get')
err = true
end
end
etime = kt.time()
dbmetaprint(db, false)
printf('time: %.3f', etime - stime)
if etc then
printf('traversing the database by the inner iterator:')
stime = kt.time()
local cnt = 0
local function visit(key, value)
cnt = cnt + 1
local rv = kt.Visitor.NOP
if rnd then
local num = math.random(7)
if num == 1 then
rv = tostring(cnt) .. tostring(cnt)
elseif num == 2 then
rv = kt.Visitor.REMOVE
end
end
return rv
end
if not db:iterate(visit, rnd) then
dberrprint(db, 'DB::iterate')
err = true
end
if rnd then printf('(end)') end
etime = kt.time()
dbmetaprint(db, false)
printf('time: %.3f', etime - stime)
end
if etc then
printf('traversing the database by the outer cursor:')
stime = kt.time()
local cnt = 0
local function visit(key, value)
cnt = cnt + 1
local rv = kt.Visitor.NOP
if rnd then
local num = math.random(7)
if num == 1 then
rv = tostring(cnt) .. tostring(cnt)
elseif num == 2 then
rv = kt.Visitor.REMOVE
end
end
return rv
end
local cur = db:cursor()
if not cur:jump() and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::jump')
err = true
end
while cur:accept(visit, rnd, false) do
if not cur:step() and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::step')
err = true
end
end
if db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::accept')
err = true
end
if not rnd or math.random(2) == 1 then cur:disable() end
if rnd then printf('(end)') end
etime = kt.time()
dbmetaprint(db, false)
printf('time: %.3f', etime - stime)
end
printf('removing records:')
stime = kt.time()
for i = 1, rnum do
if err then break end
local key = string.format('%08d', rnd and math.random(rnum) or i)
if not db:remove(key) and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'DB::remove')
err = true
end
end
etime = kt.time()
dbmetaprint(db, true)
printf('time: %.3f', etime - stime)
printf('%s', err and 'error' or 'ok')
return err and 1 or kt.RVSUCCESS
end
-- perform wicked command
function procwicked(rnum, itnum, outmap)
printf('<Wicked Test> rnum=%s itnum=%s', rnum, itnum)
local VisitorImpl = {}
function VisitorImpl:new(rnd)
local obj = {}
obj.cnt = 0
obj.rnd = rnd
function obj:visit_full(key, value)
self.cnt = self.cnt + 1
local rv = kt.Visitor.NOP
if self.rnd then
local num = math.random(7)
if num == 1 then
rv = self.cnt
elseif num == 2 then
rv = kt.Visitor.REMOVE
end
end
return rv
end
function obj:visit_empty(key)
return self:visit_full(key, key)
end
local base = kt.Visitor:new()
setmetatable(obj, { __index = base })
return obj
end
local err = false
for itcnt = 1, itnum do
if itnum > 1 then printf('iteration %d:', itcnt) end
local stime = kt.time()
local cur = db:cursor()
for i = 1, rnum do
if err then break end
local tran = math.random(100) == 1
if tran and not db:begin_transaction(math.random(rnum) == 1) then
dberrprint(db, 'DB::begin_transaction')
tran = false
err = true
end
local key = string.format('%08d', math.random(rnum))
local cmd = math.random(12)
if cmd == 1 then
if not db:set(key, key) then
dberrprint(db, 'DB::set')
err = true
end
elseif cmd == 2 then
if not db:add(key, key) and db:error():code() ~= kt.Error.DUPREC then
dberrprint(db, 'DB::add')
err = true
end
elseif cmd == 3 then
if not db:replace(key, key) and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'DB::replace')
err = true
end
elseif cmd == 4 then
if not db:append(key, key) then
dberrprint(db, 'DB::append')
err = true
end
elseif cmd == 5 then
if math.random(2) == 1 then
local num = math.random(10)
if not db:increment(key, num) and db:error():code() ~= kt.Error.LOGIC then
dberrprint(db, 'DB::increment')
err = true
end
else
local num = math.random() * 10
if not db:increment_double(key, num) and db:error():code() ~= kt.Error.LOGIC then
dberrprint(db, 'DB::increment_double')
err = true
end
end
elseif cmd == 6 then
if not db:cas(key, key, key) and db:error():code() ~= kt.Error.LOGIC then
dberrprint(db, 'DB::cas')
err = true
end
elseif cmd == 7 then
if not db:remove(key) and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'DB::remove')
err = true
end
elseif cmd == 8 then
local visitor = VisitorImpl:new(1)
if not db:accept(key, visitor, true) then
dberrprint(db, 'DB::accept')
err = true
end
elseif cmd == 9 then
if math.random(10) == 1 then
if math.random(4) == 1 then
if not cur:jump_back() and db:error():code() ~= kt.Error.NOIMPL and
db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::jump_back')
err = true
end
else
if not cur:jump() and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::jump')
err = true
end
end
else
cmd = math.random(6)
if cmd == 1 then
if not cur:get_key() and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::get_key')
err = true
end
elseif cmd == 2 then
if not cur:get_value() and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::get_value')
err = true
end
elseif cmd == 3 then
if not cur:get() and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::get')
err = true
end
elseif cmd == 4 then
if not cur:remove() and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::remove')
err = true
end
else
local visitor = VisitorImpl:new(1)
if not cur:accept(visitor, true, math.random(2) == 1) and
db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::accept')
err = true
end
end
end
if math.random(2) == 1 then
if not cur:step() and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'Cursor::step')
err = true
end
end
if math.random(rnum / 50 + 1) == 1 then
prefix = string.sub(key, 1, -2)
if not db:match_prefix(prefix, math.random(10)) then
dberrprint(db, 'DB::match_prefix')
err = true
end
end
if math.random(rnum / 50 + 1) == 1 then
regex = string.sub(key, 1, -2)
if not db:match_regex(regex, math.random(10)) and
db:error():code() ~= kt.Error.LOGIC then
dberrprint(db, 'DB::match_regex')
err = true
end
end
if math.random(rnum / 50 + 1) == 1 then
origin = string.sub(key, 1, -2)
if not db:match_similar(origin, 3, math.random(2) == 0, math.random(10)) then
dberrprint(db, 'DB::match_similar')
err = true
end
end
else
if not db:get(key) and db:error():code() ~= kt.Error.NOREC then
dberrprint(db, 'DB::get')
err = true
end
end
if tran and not db:end_transaction(math.random(10) > 1) then
dberrprint(db, 'DB::end_transaction')
err = true
end
end
cur:disable()
dbmetaprint(db, itcnt == itnum)
end
printf('%s', err and 'error' or 'ok')
return err and 1 or kt.RVSUCCESS
end
-- procedure
function test (inmap, outmap)
math.randomseed(kt.time() * 1000)
local stime = kt.time()
local rv = main(inmap, outmap)
local etime = kt.time()
printf('proc time: %s', (etime - stime))
return rv
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment