Merge pull request #121 from bell07/performance_boost

boost performance
This commit is contained in:
bell07 2018-04-26 20:09:38 +02:00 committed by GitHub
commit 1d063c050c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 137 additions and 23 deletions

3
API.md
View File

@ -207,7 +207,8 @@ Can be used for non-data and/or system tasks. For usual data store please use th
- `bdev:get_hard_disk()` hdd store - a table with all app-related storage partitions, if hard disk capatibility exists
- `bdev:get_removable_disk()` removable data object (drive)
- `bdev:get_cloud_disk(storage_name)` - Get named cloud storage
- `bdev:sync()` - Write/store all opened and maybe changed data
- `bdev:sync()` - Write/store all opened and maybe changed data (cached)
- `bdev:sync_cloud()` - Write/store all opened and maybe changed data in cloud
### Storage methods
- `get_boot_disk()` - Check which device can be booted. possible return value is "hdd" or "removable"

View File

@ -57,6 +57,6 @@ laptop.register_app("removable", {
mtos:power_on() --reboot
end
end
mtos.bdev:sync()
laptop.mtos_cache:sync_and_free(mtos)
end,
})

View File

@ -21,8 +21,8 @@ function bdev:get_ram_disk()
end
function bdev:free_ram_disk()
self.os.meta:set_string('laptop_ram','')
self.ram_disk = nil
self.ram_disk = {}
self:sync()
end
@ -47,7 +47,7 @@ function bdev:get_removable_disk(removable_type)
function data:reload(stack)
-- self.inv unchanged
-- self.rtype unchanged (assumption
stack = stack or data.inv:get_stack("main", 1)
stack = stack or self.inv:get_stack("main", 1)
if stack then
local def = stack:get_definition()
if def and def.name ~= "" then
@ -77,8 +77,8 @@ function bdev:get_removable_disk(removable_type)
if not self.stack then
return false
end
local drop_pos = table.copy(self.bdev.os.pos)
drop_pos = { x=drop_pos.x+math.random()*2-1, y=drop_pos.y,z=drop_pos.z+math.random()*2-1 }
local p = self.bdev.os.pos
local drop_pos = { x=p.x+math.random()*2-1, y=p.y,z=p.z+math.random()*2-1 }
minetest.item_drop(self.stack, nil, drop_pos)
self.stack = nil
return true
@ -178,7 +178,10 @@ function bdev:sync()
end
self.removable_disk.inv:set_stack("main", 1, self.removable_disk.stack)
end
end
-- Save all data if used
function bdev:sync_cloud()
-- Modmeta (Cloud)
if self.cloud_disk then
for store, value in pairs(self.cloud_disk) do
@ -189,7 +192,10 @@ end
-- Get handler
function laptop.get_bdev_handler(mtos)
local bdevobj = table.copy(bdev)
local bdevobj = {}
for k,v in pairs(bdev) do
bdevobj[k] = v
end
bdevobj.os = mtos
return bdevobj
end

View File

@ -2,6 +2,7 @@
laptop.node_config = {}
local function on_construct(pos)
laptop.mtos_cache:free(pos)
local mtos = laptop.os_get(pos)
local node = minetest.get_node(pos)
local hwdef = laptop.node_config[node.name]
@ -35,7 +36,7 @@ local function on_punch(pos, node, puncher)
puncher:set_wielded_item(slot.stack)
-- reload OS
slot:reload(punch_item)
mtos.bdev:sync()
laptop.mtos_cache:sync_and_free(mtos)
for k,v in pairs(laptop.os_get(mtos.pos)) do
mtos[k] = v
end
@ -98,6 +99,7 @@ local function on_metadata_inventory_take(pos, listname, index, stack, player)
local mtos = laptop.os_get(pos)
mtos:pass_to_app("on_metadata_inventory_take", true, player, listname, index, stack)
end
local function on_timer(pos, elapsed)
local mtos = laptop.os_get(pos)
return mtos:pass_to_app("on_timer", true, nil, elapsed)
@ -105,15 +107,13 @@ end
local function after_place_node(pos, placer, itemstack, pointed_thing)
local save = minetest.deserialize(itemstack:get_meta():get_string("laptop_metadata"))
laptop.mtos_cache:free(pos)
if save then
local meta = minetest.get_meta(pos)
meta:from_table({fields = save.fields})
if save.invlist.main then
for invname, inv in pairs(save.invlist) do
meta:get_inventory():set_list(invname, inv)
end
else -- compatibility to prev. version
meta:get_inventory():set_list("main", save.invlist)
for invname, inv in pairs(save.invlist) do
meta:get_inventory():set_list(invname, inv)
end
end
itemstack:clear()
@ -122,6 +122,30 @@ end
local function after_dig_node(pos, oldnode, oldmetadata, digger)
--local function preserve_metadata(pos, oldnode, oldmetadata, drops) --TODO: if MT-0.5 stable
local save = { fields = oldmetadata.fields, invlist = {} }
local cached_mtos = laptop.mtos_cache:get(pos)
if cached_mtos then
-- Workaround, handle sync without nodemeta access
local bdev = cached_mtos.bdev
save.fields.laptop_ram = minetest.serialize(bdev.ram_disk)
save.fields.laptop_appdata = minetest.serialize(bdev.hard_disk)
if bdev.removable_disk then
local stack = bdev.removable_disk.stack
if stack then
local stackmeta = stack:get_meta()
if bdev.removable_disk.def and bdev.removable_disk.label ~= bdev.removable_disk.def.description then
stackmeta:set_string("description", bdev.removable_disk.label)
end
if bdev.removable_disk.storage then
stackmeta:set_string("os_storage", minetest.serialize(bdev.removable_disk.storage))
end
end
oldmetadata.inventory.main = oldmetadata.inventory.main or {}
oldmetadata.inventory.main[1] = stack
end
laptop.mtos_cache:free(pos)
end
if oldmetadata.inventory then
for invname, inv in pairs(oldmetadata.inventory) do
local invsave = {}
@ -131,7 +155,6 @@ local function after_dig_node(pos, oldnode, oldmetadata, digger)
end
end
end
local item_name = minetest.registered_items[oldnode.name].drop or oldnode.name
local inventory = digger:get_inventory()
local in_inv

View File

@ -64,6 +64,72 @@ laptop.supported_textcolors = {
}
-----------------------------------------------------
-- Operating System cache
-----------------------------------------------------
local mtos_cache = {
list = {},
is_running = false
}
laptop.mtos_cache = mtos_cache
function mtos_cache:get(pos)
local hash = minetest.hash_node_position(pos)
return self.list[hash]
end
function mtos_cache:set(pos, mtos)
local hash = minetest.hash_node_position(pos)
mtos.cache_first_access = mtos.cache_first_access or os.time()
mtos.cache_last_access = os.time()
self.list[hash] = mtos
self:check_free_step()
end
function mtos_cache:free(pos)
local hash = minetest.hash_node_position(pos)
self.list[hash] = nil
end
function mtos_cache:sync_and_free(mtos)
mtos.bdev:sync()
self:free(mtos.pos)
end
function mtos_cache:check_free_step()
-- do not start twice
if self.is_running then
return
end
local function check_free(mtos_cache)
local current_time
for hash, mtos in pairs(mtos_cache.list) do
current_time = current_time or os.time()
if mtos.cache_last_access + 5 <= current_time or -- 5 seconds unused
mtos.cache_first_access + 15 <= current_time then -- or 15 seconds active
self:sync_and_free(mtos)
end
end
mtos_cache.is_running = false
mtos_cache:check_free_step()
end
if next(self.list) then
self.is_running = true
minetest.after(1, check_free, self)
end
end
-- Sync all on shutdown
minetest.register_on_shutdown(function()
for hash, mtos in pairs(mtos_cache.list) do
mtos_cache:sync_and_free(mtos)
end
end)
-----------------------------------------------------
-- Operating System class
-----------------------------------------------------
@ -89,6 +155,7 @@ end
-- Power on the system and start the launcher
function os_class:power_on(new_node_name)
self.bdev:free_ram_disk()
mtos_cache:free(self.pos)
-- update current instance with reinitialized data
for k,v in pairs(laptop.os_get(self.pos)) do
self[k] = v
@ -140,10 +207,12 @@ function os_class:set_theme(theme)
end
function os_class:get_os_attr()
local os_attr = table.copy(laptop.os_version_attr.default)
if self.hwdef.os_version then
os_attr = table.copy(laptop.os_version_attr[self.hwdef.os_version])
local os_attr = {}
local os_version = self.hwdef.os_version or 'default'
for k, v in pairs(laptop.os_version_attr[os_version]) do
os_attr[k] = v
end
os_attr.tty_style = self.hwdef.tty_style or os_attr.tty_style
if self.hwdef.tty_monochrome ~= nil then
os_attr.tty_monochrome = self.hwdef.tty_monochrome
@ -210,7 +279,10 @@ function os_class:get_app(name)
if not template then
return
end
local app = setmetatable(table.copy(template), laptop.class_lib.app)
local app = setmetatable({}, laptop.class_lib.app)
for k,v in pairs(template) do
app[k] = v
end
app.name = name
app.os = self
return app
@ -279,6 +351,7 @@ function os_class:set_app(appname)
self.meta:set_string('formspec', formspec)
end
self:save()
mtos_cache:sync_and_free(self)
end
-- Handle input processing
@ -313,7 +386,8 @@ function os_class:pass_to_app(method, reshow, sender, ...)
end
function os_class:save()
self.bdev:sync()
self.bdev:sync_cloud()
mtos_cache:set(self.pos, self)
end
-- Use parameter and launch the select_file dialog
@ -336,7 +410,14 @@ end
-- Get Operating system object
-----------------------------------------------------
function laptop.os_get(pos)
local self = setmetatable({}, os_class)
-- get OS-object from cache
local self = mtos_cache:get(pos)
if self then
return self
end
-- Create new if not in cache
self = setmetatable({}, os_class)
self.__index = os_class
self.pos = pos
self.node = minetest.get_node(pos)

View File

@ -111,8 +111,11 @@ end
function laptop.get_theme(theme_name)
local self = setmetatable(table.copy(laptop.themes.default), theme_class)
theme_name = theme_name or "Freedom"
local self = setmetatable({}, theme_class)
for k, v in pairs(laptop.themes.default) do
self[k] = v
end
if theme_name and laptop.themes[theme_name] then
for k,v in pairs(laptop.themes[theme_name]) do
self[k] = v