summaryrefslogtreecommitdiff
path: root/script/lazy-cacher.lua
blob: e39cceff27910c0da7646fc5a9fbc305c289e105 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
local fs = require 'bee.filesystem'

---@param path string
---@param errorHandle? fun(string)
---@return table?
return function (path, errorHandle)
    fs.create_directories(fs.path(path):parent_path())
    local f, err = io.open(path, 'a+b')
    if not f then
        if errorHandle then
            errorHandle(err)
        end
        return nil
    end
    local size, err = f:seek('end')
    if not size then
        if errorHandle then
            errorHandle(err)
        end
        return nil
    end
    local map = {}
    return {
        writter = function(id, code)
            local offset, err = f:seek('end')
            if not offset then
                if errorHandle then
                    errorHandle(err)
                end
                return false
            end
            if not code then
                map[id] = nil
                return true
            end
            if #code > 1000000 then
                return false
            end
            local suc, err = f:write(code)
            if not suc then
                if errorHandle then
                    errorHandle(err)
                end
                return false
            end
            map[id] = offset * 1000000 + #code
            return true
        end,
        reader = function(id)
            if not map[id] then
                return nil
            end
            local offset = map[id] // 1000000
            local len    = map[id] %  1000000
            local _, err = f:seek('set', offset)
            if err then
                if errorHandle then
                    errorHandle(err)
                end
                return nil
            end
            local code = f:read(len)
            return code
        end,
        dispose = function ()
            f:close()
            fs.remove(fs.path(path))
        end,
    }
end