PsychOSPackages/rtfs/lib/fs/rtfs/init.lua

70 lines
1.9 KiB
Lua

local fs = fs or require "filesystem"
local component = require "component"
local computer = require "computer"
local cache = (package.loaded["fs.rtfs"] or {}).cache or {hitsR=0, hitsW=0, missesR=0, missesW=0}
local proxy = {}
local rtfs = {proxy=proxy, cache=cache}
local sbformat = ">c4I2I8c18" -- "rtfs" magic, version, index size in entries, label. label length subject to change.
rtfs.cacheSize = computer.totalMemory() // 1024 // 16
-- data mangling functions
function rtfs.fnormalize(s)
return table.concat(fs.segments(s),"/")
end
function proxy:log(message,level)
syslog(message,level or syslog.debug,"rtfs:"..self.label)
end
-- just for ease-of-use
function rtfs.getProxy(addr)
if type(addr) == "string" then
return component.proxy(component.get(addr,"partition") or component.get(addr) or addr)
end
return addr
end
-- cache stuff
local function cacheClean()
while #cache > rtfs.cacheSize do
table.remove(cache, 1)
end
end
function proxy:cachedRead(s)
for k,v in ipairs(cache) do
if v[1] == self.d.address and v[2] == s then
rtfs.cache.hitsR = rtfs.cache.hitsR + 1
return v[3]
end
end
cache[#cache + 1] = {self.d.address, s, self.d.readSector(s)}
rtfs.cache.missesR = rtfs.cache.missesR + 1
cacheClean()
return cache[#cache][3]
end
function proxy:cachedWrite(s,d)
for k,v in ipairs(cache) do
if v[1] == self.d.address and v[2] == s then
table.remove(cache, k)
end
end
cache[#cache + 1] = {self.d.address, s, d}
cacheClean()
return self.d.writeSector(s,d)
end
function rtfs.mount(a)
local d = rtfs.getProxy(a)
local magic, version = string.unpack(sbformat, d.readSector(1))
assert(magic == "rtfs","not an rtfs filesystem")
local w, l = pcall(require, string.format("fs.rtfs.v%i", version))
if w then return l.mount(a) end
error("incompatible rtfs version")
end
function rtfs.format(a,l)
return require("fs.rtfs.v1").format(a,l)
end
return rtfs