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