Сжатие для БД вынесено в параметр
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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue