forked from dlang/cdcdb
Сжатие для БД вынесено в параметр
This commit is contained in:
parent
8a9142234e
commit
d93dc4d81b
3 changed files with 103 additions and 24 deletions
|
@ -2,49 +2,87 @@ module cdcdb.snapshot;
|
|||
|
||||
import cdcdb.dblite;
|
||||
|
||||
import zstd : uncompress;
|
||||
|
||||
import std.digest.sha : SHA256, digest, SHA256Digest;
|
||||
import std.datetime : DateTime;
|
||||
import std.exception : enforce;
|
||||
|
||||
final class Snapshot {
|
||||
final class Snapshot
|
||||
{
|
||||
private:
|
||||
DBLite _db;
|
||||
DBSnapshot _snapshot;
|
||||
public:
|
||||
this(DBLite dblite, DBSnapshot dbSnapshot) {
|
||||
this(DBLite dblite, DBSnapshot dbSnapshot)
|
||||
{
|
||||
_db = dblite;
|
||||
_snapshot = dbSnapshot;
|
||||
}
|
||||
|
||||
this(DBLite dblite, long idSnapshot) {
|
||||
this(DBLite dblite, long idSnapshot)
|
||||
{
|
||||
_db = dblite;
|
||||
_snapshot = _db.getSnapshot(idSnapshot);
|
||||
}
|
||||
|
||||
ubyte[] data() {
|
||||
auto dataChunks = _db.getChunks(_snapshot.id);
|
||||
ubyte[] data()
|
||||
{
|
||||
auto chunks = _db.getChunks(_snapshot.id);
|
||||
ubyte[] content;
|
||||
|
||||
import zstd : uncompress;
|
||||
|
||||
foreach (chunk; dataChunks) {
|
||||
foreach (chunk; chunks)
|
||||
{
|
||||
ubyte[] bytes;
|
||||
if (chunk.zstd) {
|
||||
if (chunk.zstd)
|
||||
{
|
||||
enforce(chunk.zSize == chunk.content.length, "Размер сжатого фрагмента не соответствует ожидаемому");
|
||||
bytes = cast(ubyte[]) uncompress(chunk.content);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes = chunk.content;
|
||||
}
|
||||
enforce(chunk.size == bytes.length, "Оригинальный размер не соответствует ожидаемому");
|
||||
enforce(chunk.sha256 == digest!SHA256(bytes), "Хеш-сумма фрагмента не совпадает");
|
||||
content ~= bytes;
|
||||
}
|
||||
|
||||
import std.digest.sha : SHA256, digest;
|
||||
|
||||
enforce(_snapshot.sha256 == digest!SHA256(content), "Хеш-сумма файла не совпадает");
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
bool remove() {
|
||||
void data(void delegate(const(ubyte)[]) sink)
|
||||
{
|
||||
auto chunks = _db.getChunks(_snapshot.id);
|
||||
auto fctx = new SHA256Digest();
|
||||
|
||||
foreach (chunk; chunks)
|
||||
{
|
||||
ubyte[] bytes;
|
||||
if (chunk.zstd)
|
||||
{
|
||||
enforce(chunk.zSize == chunk.content.length, "Размер сжатого фрагмента не соответствует ожидаемому");
|
||||
bytes = cast(ubyte[]) uncompress(chunk.content);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes = chunk.content;
|
||||
}
|
||||
|
||||
enforce(chunk.size == bytes.length, "Оригинальный размер не соответствует ожидаемому");
|
||||
enforce(chunk.sha256 == digest!SHA256(bytes), "Хеш-сумма фрагмента не совпадает");
|
||||
|
||||
sink(bytes);
|
||||
fctx.put(bytes);
|
||||
}
|
||||
|
||||
enforce(_snapshot.sha256 = fctx.finish(), "Хеш-сумма файла не совпадает");
|
||||
}
|
||||
|
||||
bool remove()
|
||||
{
|
||||
_db.beginImmediate();
|
||||
|
||||
bool ok;
|
||||
|
@ -65,4 +103,40 @@ public:
|
|||
|
||||
return _snapshot.id == idDeleted;
|
||||
}
|
||||
|
||||
@property long id() const nothrow @safe
|
||||
{
|
||||
return _snapshot.id;
|
||||
}
|
||||
|
||||
@property string label() const @safe
|
||||
{
|
||||
return _snapshot.label;
|
||||
}
|
||||
|
||||
@property DateTime created() const @safe
|
||||
{
|
||||
return _snapshot.createdUtc;
|
||||
}
|
||||
|
||||
@property long length() const nothrow @safe
|
||||
{
|
||||
return _snapshot.sourceLength;
|
||||
}
|
||||
|
||||
@property ubyte[32] sha256() const nothrow @safe
|
||||
{
|
||||
return _snapshot.sha256;
|
||||
}
|
||||
|
||||
@property string status() const
|
||||
{
|
||||
import std.conv : to;
|
||||
return _snapshot.status.to!string;
|
||||
}
|
||||
|
||||
@property string description() const nothrow @safe
|
||||
{
|
||||
return _snapshot.description;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,15 @@ import cdcdb.dblite;
|
|||
import cdcdb.core;
|
||||
import cdcdb.snapshot;
|
||||
|
||||
import zstd : compress, Level;
|
||||
|
||||
final class Storage
|
||||
{
|
||||
private:
|
||||
// Параметры работы с базой данных
|
||||
DBLite _db;
|
||||
bool _zstd;
|
||||
int _level;
|
||||
// Настройки CDC механизма
|
||||
CDC _cdc;
|
||||
size_t _minSize;
|
||||
|
@ -31,10 +34,11 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
this(string database, bool zstd = false, size_t busyTimeout = 3000, size_t maxRetries = 3)
|
||||
this(string database, bool zstd = false, int level = Level.base, size_t busyTimeout = 3000, size_t maxRetries = 3)
|
||||
{
|
||||
_db = new DBLite(database, busyTimeout, maxRetries);
|
||||
_zstd = zstd;
|
||||
_level = level;
|
||||
initCDC();
|
||||
}
|
||||
|
||||
|
@ -94,8 +98,6 @@ public:
|
|||
// Разбить на фрагменты
|
||||
Chunk[] chunks = _cdc.split(data);
|
||||
|
||||
import zstd : compress;
|
||||
|
||||
// Запись фрагментов в БД
|
||||
foreach (chunk; chunks)
|
||||
{
|
||||
|
@ -105,7 +107,7 @@ public:
|
|||
auto content = data[chunk.offset .. chunk.offset + chunk.size];
|
||||
|
||||
if (_zstd) {
|
||||
ubyte[] zBytes = compress(content, 22);
|
||||
ubyte[] zBytes = compress(content, _level);
|
||||
size_t zSize = zBytes.length;
|
||||
ubyte[32] zHash = digest!SHA256(zBytes);
|
||||
|
||||
|
|
17
test/app.d
17
test/app.d
|
@ -2,11 +2,14 @@ import std.stdio;
|
|||
|
||||
import cdcdb;
|
||||
|
||||
import std.file : read;
|
||||
import std.file : read, write;
|
||||
import std.stdio : File, writeln;
|
||||
import std.conv : to;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
auto storage = new Storage("/tmp/base.db", true);
|
||||
auto storage = new Storage("/tmp/base.db", true, 22);
|
||||
storage.newSnapshot("/tmp/text", cast(ubyte[]) read("/tmp/text"));
|
||||
|
||||
// if (snapshot !is null) {
|
||||
|
@ -14,11 +17,11 @@ void main()
|
|||
// snapshot.remove();
|
||||
// }
|
||||
|
||||
import std.stdio : writeln;
|
||||
|
||||
foreach (snapshot; storage.getSnapshots()) {
|
||||
writeln(cast(string) snapshot.data);
|
||||
auto file = File("/tmp/restore" ~ snapshot.id.to!string, "wb");
|
||||
snapshot.data((const(ubyte)[] content) {
|
||||
file.rawWrite(content);
|
||||
});
|
||||
file.close();
|
||||
}
|
||||
|
||||
// writeln(cas.getVersion);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue