1 module common.wal.storage; 2 3 4 import hunt.raft; 5 6 import hunt.util.Serialize; 7 import hunt.logging; 8 9 import core.stdc.stdio; 10 import core.stdc.string; 11 12 import std.stdio; 13 import std.json; 14 import std.experimental.allocator; 15 import std.file; 16 17 import common.wal.api; 18 19 20 struct kv 21 { 22 string key; 23 string val; 24 } 25 26 27 28 class Storage : DataStorage 29 { 30 31 32 byte[] getFileContent(string filename) 33 { 34 byte[] content; 35 if(!exists(filename)) 36 return null; 37 byte[] data = new byte[4096]; 38 auto ifs = File(filename, "rb"); 39 while(!ifs.eof()) 40 { 41 content ~= ifs.rawRead(data); 42 } 43 ifs.close(); 44 return content; 45 } 46 47 void saveFileContent(string filename ,const byte[] buffer) 48 { 49 auto ifs = File(filename , "wb"); 50 ifs.rawWrite(buffer); 51 ifs.close(); 52 } 53 54 55 56 57 bool load(string snapPath , string entryPath , string hsPath, 58 out Snapshot* snap , out HardState hs , out Entry[] entries) 59 { 60 byte[] snapData = getFileContent(snapPath); 61 if(snapData.length > 0) 62 { 63 snap = theAllocator.make!Snapshot(unserialize!Snapshot(snapData)); 64 logInfo(*snap); 65 _json = parseJSON(snap.Data); 66 } 67 68 _snappath = snapPath; 69 _entrypath = entryPath; 70 _hspath = hsPath; 71 72 byte[] hsData = getFileContent(hsPath); 73 if(hsData.length > 0) 74 { 75 hs = unserialize!HardState(hsData); 76 logInfo("load " , hs); 77 } 78 byte[] entryData = getFileContent(entryPath); 79 if(entryData.length > 0) 80 { 81 entries = unserialize!(Entry[])(entryData); 82 logInfo("load " , entries); 83 } 84 85 if(entryData.length == 0) 86 return false; 87 else 88 return true; 89 90 } 91 92 void saveSnap(Snapshot shot) 93 { 94 saveFileContent(_snappath , serialize(shot)); 95 } 96 97 void save(HardState hs , Entry[] entries) 98 { 99 if(IsEmptyHardState(hs) && entries.length == 0) 100 return; 101 102 if(!IsEmptyHardState(hs)) 103 { 104 logInfo("save " , hs); 105 saveFileContent(_hspath , serialize(hs)); 106 } 107 108 Entry[] newEntries; 109 110 if(entries.length > 0) 111 { 112 byte[] entryData = getFileContent(_entrypath); 113 if(entryData.length > 0) 114 { 115 newEntries ~= unserialize!(Entry[])(entryData); 116 } 117 newEntries ~= entries; 118 logInfo("save " , newEntries); 119 saveFileContent(_entrypath , serialize(newEntries)); 120 } 121 122 123 } 124 125 void SetValue(string key , string value) 126 { 127 _json[key] = value; 128 } 129 130 string Lookup(string key) 131 { 132 if(_json.isNull) 133 return string.init; 134 135 if(key in _json) 136 return _json[key].str(); 137 return string.init; 138 } 139 140 string getSnapData() 141 { 142 return _json.toString(); 143 } 144 145 private JSONValue _json; 146 private string _entrypath; 147 private string _snappath; 148 private string _hspath; 149 private File _entryfd; 150 151 } 152