summaryrefslogtreecommitdiffstats
path: root/acf/transaction/backend.lua
diff options
context:
space:
mode:
Diffstat (limited to 'acf/transaction/backend.lua')
-rw-r--r--acf/transaction/backend.lua48
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