-
Notifications
You must be signed in to change notification settings - Fork 105
/
Copy pathEngineCheckpoint.cs
113 lines (94 loc) · 3.05 KB
/
EngineCheckpoint.cs
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
using Neo.IO;
using Neo.Persistence;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Neo.SmartContract.Testing.Storage
{
public class EngineCheckpoint
{
/// <summary>
/// Data
/// </summary>
public (byte[] key, byte[] value)[] Data { get; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="snapshot">Snapshot</param>
public EngineCheckpoint(DataCache snapshot)
{
var list = new List<(byte[], byte[])>();
foreach (var entry in snapshot.Seek(Array.Empty<byte>(), SeekDirection.Forward))
{
list.Add((entry.Key.ToArray(), entry.Value.ToArray()));
}
Data = list.ToArray();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="stream">Stream</param>
public EngineCheckpoint(Stream stream)
{
var list = new List<(byte[], byte[])>();
var buffer = new byte[sizeof(int)];
while (stream.Read(buffer) == sizeof(int))
{
var length = BinaryPrimitives.ReadInt32LittleEndian(buffer);
var key = new byte[length];
if (stream.Read(key) != length) break;
if (stream.Read(buffer) != sizeof(int)) break;
length = BinaryPrimitives.ReadInt32LittleEndian(buffer);
var data = new byte[length];
if (stream.Read(data) != length) break;
list.Add((key, data));
}
Data = list.ToArray();
}
/// <summary>
/// Restore
/// </summary>
/// <param name="snapshot">Snapshot</param>
public void Restore(DataCache snapshot)
{
// Clean snapshot
foreach (var entry in snapshot.Seek(Array.Empty<byte>(), SeekDirection.Forward).ToArray())
{
snapshot.Delete(entry.Key);
}
// Restore
foreach (var entry in Data)
{
snapshot.Add(new StorageKey(entry.key), new StorageItem(entry.value));
}
}
/// <summary>
/// To Array
/// </summary>
/// <returns>binary data</returns>
public byte[] ToArray()
{
using var ms = new MemoryStream();
Write(ms);
return ms.ToArray();
}
/// <summary>
/// Write to Stream
/// </summary>
public void Write(Stream stream)
{
var buffer = new byte[sizeof(int)];
foreach (var entry in Data)
{
BinaryPrimitives.WriteInt32LittleEndian(buffer, entry.key.Length);
stream.Write(buffer);
stream.Write(entry.key);
BinaryPrimitives.WriteInt32LittleEndian(buffer, entry.value.Length);
stream.Write(buffer);
stream.Write(entry.value);
}
}
}
}