Небольшая оптимизация

This commit is contained in:
Alexander Zhirov 2025-09-12 13:16:31 +03:00
parent c8d21bc3ce
commit 4f735abae7
Signed by: alexander
GPG key ID: C8D8BE544A27C511
3 changed files with 52 additions and 34 deletions

View file

@ -22,44 +22,42 @@ private:
DBLite _db; DBLite _db;
bool _zstd; bool _zstd;
ubyte[] buildContent(const ref Snapshot snapshot) size_t _minSize;
{ size_t _normalSize;
auto dataChunks = _db.getChunks(snapshot.id); size_t _maxSize;
ubyte[] content; size_t _maskS;
size_t _maskL;
foreach (chunk; dataChunks) { CDC _cdc;
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, "Оригинальный размер не соответствует ожидаемому");
content ~= bytes;
}
enforce(snapshot.fileSha256 == digest!SHA256(content), "Хеш-сумма файла не совпадает");
return content;
}
public: public:
this(string database, bool zstd = false) this(
{ string database,
bool zstd = false,
size_t minSize = 256,
size_t normalSize = 512,
size_t maxSize = 1024,
size_t maskS = 0xFF,
size_t maskL = 0x0F
) {
_db = new DBLite(database); _db = new DBLite(database);
_zstd = zstd; _zstd = zstd;
_minSize = minSize;
_normalSize = normalSize;
_maxSize = maxSize;
_maskS = maskS;
_maskL = maskL;
_cdc = new CDC(_minSize, _normalSize, _maxSize, _maskS, _maskL);
} }
size_t newSnapshot(string filePath, string label, const(ubyte)[] data) size_t newSnapshot(string filePath, const(ubyte)[] data, string label = string.init)
{ {
ubyte[32] hashSource = digest!SHA256(data); ubyte[32] hashSource = digest!SHA256(data);
// Сделать запрос в БД по filePath и сверить хеш файлов
// Если последний снимок файла соответствует текущему
if (_db.isLast(filePath, hashSource)) return 0; if (_db.isLast(filePath, hashSource)) return 0;
// Параметры для CDC вынести в отдельные настройки (продумать)
auto cdc = new CDC(256, 512, 1024, 0xFF, 0x0F);
// Разбить на фрагменты // Разбить на фрагменты
auto chunks = cdc.split(data); auto chunks = _cdc.split(data);
Snapshot snapshot; Snapshot snapshot;
@ -67,6 +65,11 @@ public:
snapshot.fileSha256 = hashSource; snapshot.fileSha256 = hashSource;
snapshot.label = label; snapshot.label = label;
snapshot.sourceLength = data.length; snapshot.sourceLength = data.length;
snapshot.algoMin = _minSize;
snapshot.algoNormal = _normalSize;
snapshot.algoMax = _maxSize;
snapshot.maskS = _maskS;
snapshot.maskL = _maskL;
_db.beginImmediate(); _db.beginImmediate();
@ -133,7 +136,22 @@ public:
ubyte[] getSnapshotData(const ref Snapshot snapshot) ubyte[] getSnapshotData(const ref Snapshot snapshot)
{ {
ubyte[] content = buildContent(snapshot); auto dataChunks = _db.getChunks(snapshot.id);
ubyte[] content;
foreach (chunk; dataChunks) {
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, "Оригинальный размер не соответствует ожидаемому");
content ~= bytes;
}
enforce(snapshot.fileSha256 == digest!SHA256(content), "Хеш-сумма файла не совпадает");
return content; return content;
} }

View file

@ -111,7 +111,7 @@ public:
}, },
snapshot.filePath, snapshot.filePath,
snapshot.fileSha256[], snapshot.fileSha256[],
snapshot.label, snapshot.label.length ? snapshot.label : null,
snapshot.sourceLength, snapshot.sourceLength,
snapshot.algoMin, snapshot.algoMin,
snapshot.algoNormal, snapshot.algoNormal,

View file

@ -7,10 +7,10 @@ import std.file : read;
void main() void main()
{ {
auto cas = new CAS("/tmp/base.db", true); auto cas = new CAS("/tmp/base.db", true);
// cas.newSnapshot("/tmp/text", "Файл для тестирования", cast(ubyte[]) read("/tmp/text")); cas.newSnapshot("/tmp/text", cast(ubyte[]) read("/tmp/text"));
import std.stdio : writeln; // import std.stdio : writeln;
writeln(cas.getSnapshotList("/tmp/text")); // writeln(cas.getSnapshotList("/tmp/text"));
writeln(cas.getVersion); // writeln(cas.getVersion);
} }