1
0
mirror of https://github.com/20kdc/OC-KittenOS.git synced 2024-11-23 10:58:06 +11:00

Magic to decrease app-claw memory usage (Another R2 candidate)

This commit is contained in:
20kdc 2018-04-28 21:27:45 +01:00
parent 5fda45b663
commit 5ae3a6019d
4 changed files with 162 additions and 54 deletions

View File

@ -8,9 +8,10 @@ local event = require("event")(neo)
local neoux, err = require("neoux") local neoux, err = require("neoux")
if not neoux then error(err) end if not neoux then error(err) end
neoux = neoux(event, neo) neoux = neoux(event, neo)
local claw = require("claw")() local claw = require("app-claw-core")()
local clawcsi = require("app-claw-csi")
local source = "http://20kdc.duckdns.org/neo/" local source = "http://20kdc.duckdns.org/neo/DEV/"
local disks = neo.requireAccess("c.filesystem", "searching disks for packages") local disks = neo.requireAccess("c.filesystem", "searching disks for packages")
local primaryDisk = disks.primary local primaryDisk = disks.primary
local primaryINet = neo.requestAccess("c.internet") local primaryINet = neo.requestAccess("c.internet")
@ -101,7 +102,7 @@ end
-- Beginning Of The App (well, the actual one) -- Beginning Of The App (well, the actual one)
local genCurrent, genPrimary, genPackage, primaryWindow local genCurrent, genPrimary, genPackage, primaryWindow
local windows = 1 local running = true
-- primary -- primary
local primarySearchTx = "" local primarySearchTx = ""
@ -134,7 +135,7 @@ local function primaryWindowRegenCore()
local gen, gens = genCurrent() local gen, gens = genCurrent()
return 25, 12, "claw", neoux.tcwindow(25, 12, gen, function (w) return 25, 12, "claw", neoux.tcwindow(25, 12, gen, function (w)
w.close() w.close()
windows = windows - 1 running = false
end, 0xFF8F00, 0, gens) end, 0xFF8F00, 0, gens)
end end
local function primaryWindowRegen() local function primaryWindowRegen()
@ -153,7 +154,7 @@ for pass = 1, 3 do
nam = v.address nam = v.address
end end
if nam then if nam then
local ok, r = claw.addSource(nam, fsSrc(v), (not v.isReadOnly()) and fsDst(v)) local ok, r = clawcsi(claw, nam, fsSrc(v), (not v.isReadOnly()) and fsDst(v))
if not ok and nam == "local" then if not ok and nam == "local" then
claw.unlock() claw.unlock()
error(r) error(r)
@ -162,10 +163,15 @@ for pass = 1, 3 do
end end
end end
-- No longer needed
disks = nil
if primaryINet then if primaryINet then
checked(claw.addSource, "inet", download) checked(clawcsi, claw, "inet", download)
end end
clawcsi = nil
primaryList = claw.getList() primaryList = claw.getList()
-- Sections -- Sections
@ -197,6 +203,14 @@ function genPrimary()
if ent then if ent then
local enttx = describe(ent) local enttx = describe(ent)
table.insert(elems, neoux.tcbutton(1, i + 1, unicode.safeTextFormat(enttx), function (w) table.insert(elems, neoux.tcbutton(1, i + 1, unicode.safeTextFormat(enttx), function (w)
-- FREE UP MEMORY NOW
elems = {}
w.reset(25, 12, "claw", function (ev)
if ev == "close" then
w.close()
running = false
end
end)
packageId = ent packageId = ent
genCurrent = genPackage genCurrent = genPackage
primaryWindowRegen() primaryWindowRegen()
@ -302,10 +316,9 @@ function genPackage()
primaryWindowRegen() primaryWindowRegen()
end) end)
} }
local srcs = claw.getSources() for k, v in ipairs(claw.sourceList) do
for k, v in ipairs(srcs) do
local lI = claw.getInfo(packageId, v[1]) local lI = claw.getInfo(packageId, v[1])
local row = 12 + k - #srcs local row = 12 + k - #(claw.sourceList)
local pfx = " " local pfx = " "
if lI then if lI then
pfx = "v" .. string.format("%04i", lI.v) .. " " pfx = "v" .. string.format("%04i", lI.v) .. " "
@ -327,7 +340,7 @@ end
genCurrent = genPrimary genCurrent = genPrimary
primaryWindow = neoux.create(primaryWindowRegenCore()) primaryWindow = neoux.create(primaryWindowRegenCore())
while windows > 0 do while running do
event.pull() event.pull()
end end
claw.unlock() claw.unlock()

View File

@ -174,7 +174,8 @@ return {
}, },
files = { files = {
"apps/app-claw.lua", "apps/app-claw.lua",
"libs/claw.lua" "libs/app-claw-core.lua",
"libs/app-claw-csi.lua"
}, },
}, },
["neo-meta"] = { ["neo-meta"] = {

View File

@ -1,9 +1,15 @@
-- This is released into the public domain. -- This is released into the public domain.
-- No warranty is provided, implied or otherwise. -- No warranty is provided, implied or otherwise.
-- claw: assistant to app-claw -- app-claw-core: assistant to app-claw
-- should only ever be one app-claw at a time -- should only ever be one app-claw at a time
-- USING THIS LIBRARY OUTSIDE OF APP-CLAW IS A BAD IDEA.
-- SO DON'T DO IT.
-- Also serves to provide a mutex.
local lock = false local lock = false
return function () return function ()
if lock then if lock then
error("libclaw safety lock in use") error("libclaw safety lock in use")
@ -12,6 +18,7 @@ return function ()
local sourceList = {} local sourceList = {}
local sources = {} local sources = {}
-- 1 2 3 4 5 6 -- 1 2 3 4 5 6
-- source ents: src dst index
-- dst entries: writeFile(fn), mkdir(fn), exists(fn), isDirectory(fn), remove(fn), rename(fna, fnb) -- dst entries: writeFile(fn), mkdir(fn), exists(fn), isDirectory(fn), remove(fn), rename(fna, fnb)
-- writeFile(fn) -> function (data/nil to close) -- writeFile(fn) -> function (data/nil to close)
local function saveInfo(dn) local function saveInfo(dn)
@ -25,21 +32,78 @@ return function ()
if not _ then return false, r end if not _ then return false, r end
return true return true
end end
local remove, installTo local remove, installTo, expandCSI, compressCSI
local function expandS(v)
return v:sub(2, v:byte(1) + 1), v:sub(v:byte(1) + 2)
end
local function expandT(v)
local t = {}
local n = v:byte(1)
v = v:sub(2)
for i = 1, n do
t[i], v = expandS(v)
end
return t, v
end
local function compressT(x)
local b = string.char(#x)
for _, v in ipairs(x) do
b = b .. string.char(#v) .. v
end
return b
end
local function expandCSI(v)
local t = {}
local k
k, v = expandS(v)
t.desc, v = expandS(v)
t.v = (v:byte(1) * 256) + v:byte(2)
v = v:sub(3)
t.dirs, v = expandT(v)
t.files, v = expandT(v)
t.deps, v = expandT(v)
return k, t, v
end
local function compressCSI(k, v)
local nifo = string.char(#k) .. k
nifo = nifo .. string.char(math.min(255, #v.desc)) .. v.desc:sub(1, 255)
nifo = nifo .. string.char(math.floor(v.v / 256), v.v % 256)
nifo = nifo .. compressT(v.dirs)
nifo = nifo .. compressT(v.files)
nifo = nifo .. compressT(v.deps)
return nifo
end
local function findPkg(idx, pkg, del)
del = del and ""
idx = sources[idx][3]
while #idx > 0 do
local k, d
k, d, idx = expandCSI(idx)
if del then
if k == pkg then
return d, del .. idx
end
del = del .. compressCSI(k, d)
else
if k == pkg then return d end
end
end
end
-- NOTE: Functions in this must return something due to the checked-call wrapper, -- NOTE: Functions in this must return something due to the checked-call wrapper,
-- but should all use error() for consistency. -- but should all use error() for consistency.
-- Operations -- Operations
installTo = function (dstName, pkg, srcName, checked, yielder) installTo = function (dstName, pkg, srcName, checked, yielder)
local installed = {pkg}
local errs = {} local errs = {}
if srcName == dstName then if srcName == dstName then
error("Invalid API use") error("Invalid API use")
end end
-- preliminary checks -- preliminary checks
local srcPkg = findPkg(srcName, pkg, false)
assert(srcPkg)
if checked then if checked then
for _, v in ipairs(sources[srcName][3][pkg].deps) do for _, v in ipairs(srcPkg.deps) do
if not sources[dstName][3][v] then if not findPkg(dstName, v) then
if not sources[srcName][3][v] then if not findPkg(srcName, v) then
table.insert(errs, pkg .. " depends on " .. v .. "\n") table.insert(errs, pkg .. " depends on " .. v .. "\n")
elseif #errs == 0 then elseif #errs == 0 then
installTo(dstName, v, srcName, checked, yielder) installTo(dstName, v, srcName, checked, yielder)
@ -51,12 +115,14 @@ return function ()
end end
-- Files from previous versions to get rid of -- Files from previous versions to get rid of
local ignFiles = {} local ignFiles = {}
if sources[dstName][3][pkg] then local oldDst = findPkg(dstName, pkg)
for _, v in ipairs(sources[dstName][3][pkg].files) do if oldDst then
for _, v in ipairs(oldDst.files) do
ignFiles[v] = true ignFiles[v] = true
end end
end end
for _, v in ipairs(sources[srcName][3][pkg].files) do oldDst = nil
for _, v in ipairs(srcPkg.files) do
if not ignFiles[v] then if not ignFiles[v] then
if sources[dstName][2][3](v) then if sources[dstName][2][3](v) then
table.insert(errs, v .. " already exists (corrupt system?)") table.insert(errs, v .. " already exists (corrupt system?)")
@ -66,13 +132,13 @@ return function ()
if #errs > 0 then if #errs > 0 then
error(table.concat(errs)) error(table.concat(errs))
end end
for _, v in ipairs(sources[srcName][3][pkg].dirs) do for _, v in ipairs(srcPkg.dirs) do
sources[dstName][2][2](v) sources[dstName][2][2](v)
if not sources[dstName][2][4](v) then if not sources[dstName][2][4](v) then
error("Unable to create directory " .. v) error("Unable to create directory " .. v)
end end
end end
for _, v in ipairs(sources[srcName][3][pkg].files) do for _, v in ipairs(srcPkg.files) do
local tmpOut, r, ok = sources[dstName][2][1](v .. ".claw-tmp") local tmpOut, r, ok = sources[dstName][2][1](v .. ".claw-tmp")
ok = tmpOut ok = tmpOut
if ok then if ok then
@ -82,31 +148,40 @@ return function ()
yielder() yielder()
else else
-- Cleanup... -- Cleanup...
for _, v in ipairs(sources[srcName][3][pkg].files) do for _, v in ipairs(srcPkg.files) do
sources[dstName][2][5](v .. ".claw-tmp") sources[dstName][2][5](v .. ".claw-tmp")
end end
error(r) error(r)
end end
end end
-- PAST THIS POINT, ERRORS CORRUPT! -- PAST THIS POINT, ERRORS CORRUPT!
sources[dstName][3][pkg] = nil -- Remove package from DB
local oldDst2, oldDst3 = findPkg(dstName, pkg, true)
sources[dstName][3] = oldDst3 or sources[dstName][3]
oldDst2, oldDst3 = nil
saveInfo(dstName) saveInfo(dstName)
-- Delete old files
for k, _ in pairs(ignFiles) do for k, _ in pairs(ignFiles) do
yielder() yielder()
sources[dstName][2][5](k) sources[dstName][2][5](k)
end end
for _, v in ipairs(sources[srcName][3][pkg].files) do -- Create new files
for _, v in ipairs(srcPkg.files) do
yielder() yielder()
sources[dstName][2][6](v .. ".claw-tmp", v) sources[dstName][2][6](v .. ".claw-tmp", v)
end end
sources[dstName][3][pkg] = sources[srcName][3][pkg] -- Insert into DB
sources[dstName][3] = sources[dstName][3] .. compressCSI(pkg, srcPkg)
saveInfo(dstName) saveInfo(dstName)
return true return true
end end
remove = function (dstName, pkg, checked) remove = function (dstName, pkg, checked)
if checked then if checked then
local errs = {} local errs = {}
for dpsName, dpsV in pairs(sources[dstName][3]) do local buf = sources[dstName][3]
while #buf > 0 do
local dpsName, dpsV
dpsName, dpsV, buf = expandCSI(buf)
for _, v in ipairs(dpsV.deps) do for _, v in ipairs(dpsV.deps) do
if v == pkg then if v == pkg then
table.insert(errs, dpsName .. " depends on " .. pkg .. "\n") table.insert(errs, dpsName .. " depends on " .. pkg .. "\n")
@ -117,10 +192,12 @@ return function ()
return nil, table.concat(errs) return nil, table.concat(errs)
end end
end end
for _, v in ipairs(sources[dstName][3][pkg].files) do local dstPkg, nbuf = findPkg(dstName, pkg, true)
assert(dstPkg, "Package wasn't installed")
for _, v in ipairs(dstPkg.files) do
sources[dstName][2][5](v) sources[dstName][2][5](v)
end end
sources[dstName][3][pkg] = nil sources[dstName][3] = nbuf
saveInfo(dstName) saveInfo(dstName)
return true return true
end end
@ -128,50 +205,39 @@ return function ()
-- Gets the latest info, or if given a source just gives that source's info. -- Gets the latest info, or if given a source just gives that source's info.
-- Do not modify output. -- Do not modify output.
getInfo = function (pkg, source, oldest) getInfo = function (pkg, source, oldest)
if source then return sources[source][3][pkg] end if source then return findPkg(source, pkg) end
local bestI = { local bestI = {
v = -1, v = -1,
desc = "An unknown package.", desc = "An unknown package.",
deps = {} deps = {}
} }
if oldest then bestI.v = 10000 end if oldest then bestI.v = 10000 end
for _, v in pairs(sources) do for k, v in pairs(sources) do
if v[3][pkg] then local pkgv = findPkg(k, pkg)
if ((not oldest) and (v[3][pkg].v > bestI.v)) or (oldest and (v[3][pkg].v > bestI.v)) then if pkgv then
bestI = v[3][pkg] if ((not oldest) and (pkgv.v > bestI.v)) or (oldest and (pkgv.v > bestI.v)) then
bestI = pkgv
end end
end end
end end
return bestI return bestI
end, end,
-- Provides an ordered list of sources, with writable. sources = sources,
-- Do not modify output. sourceList = sourceList,
getSources = function ()
return sourceList
end,
-- NOTE: If a source is writable, it's added anyway despite any problems.
addSource = function (name, src, dst)
local ifo = ""
local ifok, e = src("data/app-claw/local.lua", function (t)
ifo = ifo .. (t or "")
return true
end)
e = e or "local.lua parse error"
ifo = ifok and require("serial").deserialize(ifo)
if not (dst or ifo) then return false, e end
table.insert(sourceList, {name, not not dst})
sources[name] = {src, dst, ifo or {}}
return not not ifo, e
end,
remove = remove, remove = remove,
installTo = installTo, installTo = installTo,
expandCSI = expandCSI,
compressCSI = compressCSI,
-- Gets a total list of packages, as a table of strings. You can modify output. -- Gets a total list of packages, as a table of strings. You can modify output.
getList = function () getList = function ()
local n = {} local n = {}
local seen = {} local seen = {}
for k, v in pairs(sources) do for k, v in pairs(sources) do
for kb, vb in pairs(v[3]) do local p3 = v[3]
while #p3 > 0 do
local kb, _, nx = expandCSI(p3)
p3 = nx
if not seen[kb] then if not seen[kb] then
seen[kb] = true seen[kb] = true
table.insert(n, kb) table.insert(n, kb)

View File

@ -0,0 +1,28 @@
-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- app-claw-csi: addSource function
-- USING THIS LIBRARY OUTSIDE OF APP-CLAW IS A BAD IDEA.
-- SO DON'T DO IT.
-- NOTE: If a source is writable, it's added anyway despite any problems.
return function (claw, name, src, dst)
local ifo = ""
local ifok, e = src("data/app-claw/local.lua", function (t)
ifo = ifo .. (t or "")
return true
end)
e = e or "local.lua parse error"
ifo = ifok and require("serial").deserialize(ifo)
if not (dst or ifo) then return false, e end
table.insert(claw.sourceList, {name, not not dst})
local nifo = ifo or ""
if type(nifo) == "table" then
nifo = ""
for k, v in pairs(ifo) do
nifo = nifo .. claw.compressCSI(k, v)
end
end
claw.sources[name] = {src, dst, nifo}
return not not ifo, e
end