git.s-ol.nu mmm / 4b0c371
add ba_log entry 2019-10-26 s-ol 2 years ago
1 changed file(s) with 62 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 Besides some smaller fixes with the styling of the page, and in particular the diagrams introduced in [`2019-10-24`][2019-10-24],
1 I finally (re-)implemented children-ordering in the `fs`-store of mmmmfs
2 (the `sql` store is still missing it, but I am not currently using it either) \[[`a62f63b`][a62f63b]\]:
3 Files on the regular filesystem don't have a particular order, but in mmmfs the order of children is is guaranteed,
4 so that arranging children in a particular order becomes a meaningful tool.
5
6 To store the ordering data, a 'magic' file called `$order` is (optionally) stored in each directory in the filesystem.
7 The file lists all child fileders by name in the given order.
8 When the children of a fileder are requested (in `list_fileders_in` or `get_index`, which relies on the former),
9 all children that are mentioned in `$order` are returned in that order,
10 while all remaining children are sorted alphabetically and appended at the end of the list.
11 This way the order is guaranteed to be stable even if no `$order` file is specified,
12 or when the `$order` file has not been updated after adding new children.
13
14 Here is the commented implementation in MoonScript:
15
16 list_fileders_in: (path='') =>
17 -- create a mapping of all child-fileders
18 -- in 'entries' (name -> path)
19 entries = {}
20 for entry_name in lfs.dir @root .. path
21 continue if '.' == entry_name\sub 1, 1
22 entry_path = @root .. "#{path}/#{entry_name}"
23 if 'directory' ~= lfs.attributes entry_path, 'mode'
24 continue
25
26 entries[entry_name] = "#{path}/#{entry_name}"
27
28 -- where we will store our sorted list of children
29 sorted = {}
30
31 -- check for existance of the order file
32 order_file = @root .. "#{path}/$order"
33 if 'file' == lfs.attributes order_file, 'mode'
34 for line in io.lines order_file
35 path = assert entries[line], "entry in $order but not on disk: #{line}"
36
37 -- add all $order-entries to the sorted output in the same order they appear.
38 -- also flag these entries as already added
39 table.insert sorted, path
40 sorted[line] = true
41
42 -- find the he remaining (non-flagged) entries, sort them alphabetically
43 -- and then append them to the sorted output list
44 entries = [path for entry, path in pairs entries when not sorted[entry]]
45 table.sort entries
46 for path in *entries
47 table.insert sorted, path
48
49 -- return an iterator over the sorted output
50 coroutine.wrap ->
51 for path in *sorted
52 coroutine.yield path
53
54 The interface for reordering fileders is still missing in the code,
55 and just while writing this I realized that the current implementation is in fact buggy:
56 when a fileder that is mentioned in `$order` is deleted via the `stores.fs` API,
57 it is not removed from `$order`, causing an error the next time the fileder is listed.
58 I will probably get around to fixing both of these problems when I build the corresponding UI.
59
60 [2019-10-24]: /articles/mmmfs/ba_log/2019-10-24/
61 [a62f63b]: https://git.s-ol.nu/mmm/commit/a62f63bc00cd63a98b349a2574e3e9e14c95a441/