1 module neton.store.NodeExtern;
2 import std.experimental.allocator;
3 import std.algorithm.searching;
4 import neton.store.Store;
5 import std.json;
6 import hunt.logging;
7 import std.array;
8 import neton.store.Util;
9 
10 class NodeExtern
11 {
12 
13     this(string key, ulong modifiedIndex, bool recursive = false)
14     {
15         _recursive = recursive;
16         _originKey = key;
17         _key = getSafeKey(key);
18         _modifiedIndex = modifiedIndex;
19         _dir = false;
20         loadValue();
21     }
22 
23     this(string reqKey,string key, ulong modifiedIndex, bool recursive = false)
24     {
25         _recursive = recursive;
26         _originKey = reqKey;
27         _key = getSafeKey(key);
28         _modifiedIndex = modifiedIndex;
29         _dir = false;
30         loadValue();
31     }
32 
33     void opAssign(S)(auto ref S ne) if (is(S == Unqual!(typeof(this))))
34     {
35         _originKey = ne._originKey;
36         _key = ne._key;
37         _value = ne._value;
38         _dir = ne._dir;
39         _expiration = ne._expiration;
40         _ttl = ne._ttl;
41         _modifiedIndex = ne._modifiedIndex;
42         _recursive = ne._recursive;
43     }
44 
45     @property string key()
46     {
47         return _key;
48     }
49 
50     @property string originKey()
51     {
52         return _originKey;
53     }
54 
55     @property bool dir()
56     {
57         return _dir;
58     }
59 
60     @property ulong modifiedIndex()
61     {
62         return _modifiedIndex;
63     }
64 
65     void loadValue()
66     {
67         // logWarning("----begin load value - ----");
68         // scope(exit) logWarning("----load value finish ----");
69         try
70         {
71             if (_key.length == 0)
72                 return;
73             if (_recursive)
74                 _value = recurBuildNodeInfo(_key);
75             else
76             {
77                 JSONValue res;
78 
79                 JSONValue node = Store.instance().getJsonValue(_key);
80                 if (node.type != JSONType.null_)
81                 {
82                     res["key"] = _originKey;
83                     auto dir = node["dir"].str == "true" ? true : false;
84                     res["dir"] = node["dir"].str;
85                     if (!dir)
86                     {
87                         if (startsWith(_key, SERVICE_PREFIX))
88                             res["value"] = tryGetJsonFormat(node["value"].str);
89                         else if (startsWith(_key, LEASE_PREFIX[0 .. $ - 1]))
90                         {
91                             res["value"] = node["ttl"];
92                         }
93                         else
94                             res["value"] = node["value"];
95                         _value = res;
96                     }
97                     else
98                     {
99                         auto children = node["children"].str;
100                         if (children.length == 0)
101                         {
102                             res["nodes"] = "[]";
103                             _value = res;
104                         }
105                         else
106                         {
107                             JSONValue[] subs;
108                             auto segments = split(children, ";");
109                             foreach (subkey; segments)
110                             {
111                                 JSONValue sub;
112                                 auto j = Store.instance().getJsonValue(subkey);
113                                 if (j.type != JSONType.null_)
114                                 {
115                                     sub["key"] = j["key"].str;
116                                     sub["dir"] = j["dir"].str;
117                                     if (j["dir"].str == "false")
118                                     {
119                                         if (startsWith(subkey, SERVICE_PREFIX))
120                                             sub["value"] = tryGetJsonFormat(j["value"].str);
121                                         else if (startsWith(subkey, LEASE_PREFIX[0 .. $ - 1]))
122                                         {
123                                             sub["value"] = j["ttl"];
124                                         }
125                                         else
126                                             sub["value"] = j["value"];
127                                     }
128 
129                                     subs ~= sub;
130                                 }
131                             }
132                             res["nodes"] = subs;
133                             _value = res;
134                         }
135 
136                     }
137                 }
138                 else
139                 {
140                     _value = res;
141                 }
142             }
143 
144             auto node = _value;
145             if (node.type == JSONType.object && "dir" in node)
146                 _dir = node["dir"].str == "true" ? true : false;
147 
148         }
149         catch (Exception e)
150         {
151             logError("load value : ", e.msg);
152         }
153 
154     }
155 
156     JSONValue recurBuildNodeInfo(string key)
157     {
158         JSONValue res;
159         res["key"] = key;
160         JSONValue node = Store.instance().getJsonValue(key);
161         if (node.type != JSONType.null_)
162         {
163             auto dir = node["dir"].str == "true" ? true : false;
164             res["dir"] = node["dir"].str;
165             if (!dir)
166             {
167                 if (startsWith(key, SERVICE_PREFIX))
168                     res["value"] = tryGetJsonFormat(node["value"].str);
169                 else if (startsWith(key, LEASE_PREFIX[0 .. $ - 1]))
170                 {
171                     res["value"] = node["ttl"];
172                 }
173                 else
174                     res["value"] = node["value"];
175                 return res;
176             }
177             else
178             {
179                 auto children = node["children"].str;
180                 if (children.length == 0)
181                 {
182                     res["nodes"] = "[]";
183                     return res;
184                 }
185                 else
186                 {
187                     JSONValue[] subs;
188                     auto segments = split(children, ";");
189                     foreach (subkey; segments)
190                     {
191                         if (subkey.length != 0)
192                         {
193                             auto sub = recurBuildNodeInfo(subkey);
194                             subs ~= sub;
195                         }
196                     }
197                     res["nodes"] = subs;
198                     return res;
199                 }
200 
201             }
202         }
203         else
204         {
205             return res;
206         }
207     }
208 
209     @property JSONValue value()
210     {
211         return _value;
212     }
213 
214     NodeExtern Clone()
215     {
216         auto ne = theAllocator.make!NodeExtern(_originKey, _modifiedIndex);
217         ne = this;
218         return ne;
219     }
220 
221 private:
222     string _key;
223     string _originKey;
224     JSONValue _value;
225     bool _dir;
226     uint _expiration;
227     long _ttl;
228     ulong _modifiedIndex;
229     bool _recursive;
230 }