-
Notifications
You must be signed in to change notification settings - Fork 0
/
ideas
147 lines (118 loc) · 6.13 KB
/
ideas
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
Path selection patterns ( /root/*/access) which can be sources for "virtual trees"
What we shold handle?
-virtual or surrogate trees (trees or value, calculated on-the-fly without any storage)
-caching and memoization of virtual trees
-linking values to each other and linking fragments of trees which mimics concept of mounts in filesystem
-transactional changes with comments (mimics special tables in SQL DBs we can store transactions in the same configuration tree)
-handle comments as a part of configuration
-scripting of handlers for virtual trees or variables
-access control (possibly would be useful to store attributes with the same interface of configuration as MySQL does)
Look at XPath and XQuery!
Library datamodel regarding basic types follows strictly typed languages:
there is following decimal types scheme:
{ signed | unsigned } int[ 8 | 16 | 32 | 64 ]
there are floating point type:
float | double
there are bitfield type:
bits[ num ] // num == 1 - boolean value
complex types simulated via special things:
node dictionary adapters:
hash, - any regular datatype
patricia, - strings (default)
array, - child node names in such node is numbers only
{ sorted | unsorted } list -
pluggable datatype system
config schemas with comments and type definition. variables are allowed. for example:
plugin {
name = string;
config = subtree( ../plugins/$${./name} )
}
here is ./name should be string or convertable to string parameter
$$ means that expansion will be performed during config tree building
instead of schema itself tree building stage
${./name} - insert mentioned node value into position at first stage
$${./name} - the same but at the sacond stage.
$[n]{./name} - at the n-th stage
Plugin for variable expansion.
data scheme is config itself
What does scheme allow to do? Automatic type conversion from original or
genuine tree. For example, string "white" for color will be converted into
1-element blob with element length == 4(bytes)
Tool for test configuration. Again, we need the module for configuration versioning!
Probably, we should have ability to backup and store succesful configurations of system
in our advanced versioning plugin. Yep, something similar to restore points in
EvilXP/NT/2000/3000/10000
Run-time configuration editing with mentioned toolbox. Adding/deleting in runtime. Not
sure about how exactly application should be notified about config change.
Module mounter - mount different part of tree to new position.
Module lazy builder - ping underlaid sub-tree module only when accessed
Module cacher - cache config into provided sub-tree of global namespace
Module engine::shm - stores result into shared memory segments; may be useful with cacher
Don't forget about config-selection globbing with XPath like expressions. We should have
an ability to build virtual subtree from real one with help of XPath-like expression.
Idea of "layers" of configuration. Actually, tree might be represented as 3d construction
where Z-coordinate is responsible for concrete layer of configuration. Layers are combined
according to their priority to d[it out resulting configuration tree.
Example of layers:
-hardware - configuration tree for particular hardware platform
-system - conf tree for particular OS installation
-user - conf tree related to loggged-in user.
...
Application can have self-defined configuration layers.
Layers are being applied as series of pathes. Resulting tree might obtain
on of its values from one level and another value from another. Values can
interfere with each other. I think word priority in this area would be
sufficient but I'm not sure. Separate plugin should be provided for such
kind of feature.
Allow in scheme plugin units of measurement.
Plugin-calculator which allows to perform calculations during config read. Kind
of setter-getter virtual variable.
We should discuss cyclic graph problem in the case of dependency in tree's
members computation.
Implement elementary caching inside graph node itself. Therefore, implement
virtual methods table pointer to enable pluggable behavior.
Snippets:
/**
* backw_path should be treated as: name_in_parent/name_of_parent_at_gparent
*/
extern cfg_node_t cfg_node_pred( cfg_node_t cur,
const char* backw_path
);
extern cfg_iter_t cfg_iterator_pred( cfg_node_t parent );
typedef int ( *get_pred_m )();
typedef int ( *get_iter_pred_m )();
typedef int ( *add_pred_m )( node_t *node, blob_t *name, node_t *pred );
typedef int ( *del_pred_m )();
#define CLASS_HAS_GET_ITER_PRED 2
#define CLASS_HAS_GET_PRED 8
#define CLASS_HAS_ADD_PRED 32
#define CLASS_HAS_DEL_PRED 128
I have encountered following problems:
What if:
Configuration of plugin contains plugin mount points itself:
How storage plugin will work in this case:
1) At first, we create node from the current parent;
2) Then, we assign value to this node;
3) Then, we dive deeper to assign childrens to this node;
***4) Then, we add node to his parent***
At the last stage plugin "plugger" does its work and parse name, formed in
special syntax:
#<node_name>:<plugin_name>[=><plugin_name>]
From this point, plugger initiates loading of mentioned plugin and passing
created node to it as a configuration tree. (If several plugins names will
be passed then tree, generated from the previous will be used as
configuration tree for the next)
OK. Now, lets imagine that the same process will be performed at really
any point at the mentioned configuration tree. So, we will have nodes,
created as a result of plugin mounting in the mentioned plugin
configuration. For example, plugin configration (which is tree itself) can
contain hardlinks, softlinks, mounting binary configuration and so on.
Everything would be OK if hardlinks catch its reffered nodes at the first
pass. But, sometimes, they won't.
OK. Let's start from this point. "Plugger" calls plugin node constructor
which returns NULL. What does plugger need to track this situation?
At first, it needs a reference to the parent, reference to configuration
node, reference to the plugin, and string pointer with node name packed
into single structure. OK. It did it. What next? Then we push them to
the FIFO. At the next evaluation cycle we just evaluate mentioned points
again