diff options
Diffstat (limited to 'acf/transaction/backend.lua')
-rw-r--r-- | acf/transaction/backend.lua | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/acf/transaction/backend.lua b/acf/transaction/backend.lua new file mode 100644 index 0000000..5b8c53f --- /dev/null +++ b/acf/transaction/backend.lua @@ -0,0 +1,48 @@ +--[[ +Copyright (c) 2012 Kaarle Ritvanen +See LICENSE file for license details +--]] + +module(..., package.seeall) + +-- TODO each transaction backend (i.e. persistence manager or +-- transaction proper) should be implemented as a thread or have its +-- internal state stored in shared storage (with appropriate locking) + + +local generation = 0 +function gen_number() + generation = generation + 1 + return generation +end + + +TransactionBackend = require('acf.object').class() + +function TransactionBackend:init() self.mod_time = {} end + +function TransactionBackend:get_if_older(path, timestamp) + local value, ts = self:get(path) + if ts > timestamp then error('Concurrent modification: '..path) end + return value, ts +end + +function TransactionBackend:set(path, t, value) + self:set_multiple{{path, t, value}} +end + +function TransactionBackend:set_multiple(mods) + -- TODO delegate to PM backends? + local timestamp = gen_number() + for _, mod in ipairs(mods) do + self.mod_time[mod[1]] = timestamp + end +end + +-- TODO should be atomic, mutex with set_multiple +function TransactionBackend:comp_and_setm(accessed, mods) + for path, timestamp in pairs(accessed) do + self:get_if_older(path, timestamp) + end + self:set_multiple(mods) +end |