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 }