added FileTreeHashBuilder for intelligently building single hash of file tree

This commit is contained in:
Szum123321 2022-11-22 14:16:12 +01:00
parent 2774ebd2b4
commit c816c70a6b
5 changed files with 175 additions and 3 deletions

View File

@ -0,0 +1,66 @@
/*
A simple backup mod for Fabric
Copyright (C) 2022 Szum123321
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.szum123321.textile_backup.core;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Supplier;
import java.util.zip.Checksum;
public class FileTreeHashBuilder {
private final static ThreadLocal<byte[]> buff =
ThreadLocal.withInitial(() -> new byte[Long.BYTES]);
private final Object lock = new Object();
private final Supplier<Checksum> hasherProvider;
private long hash = 0, filesProcessed = 0, filesTotalSize = 0;
public FileTreeHashBuilder(Supplier<Checksum> provider) { hasherProvider = provider; }
public void update(Path path, long newHash) throws IOException {
byte[] raw = buff.get();
var hasher = hasherProvider.get();
long size = Files.size(path);
hasher.update(ByteBuffer.wrap(raw).putLong(size).array());
hasher.update(path.toString().getBytes(StandardCharsets.UTF_8));
hasher.update(ByteBuffer.wrap(raw).putLong(hash).array());
synchronized (lock) {
//This way exact order of files processed doesn't matter.
this.hash ^= hasher.getValue();
filesProcessed++;
filesTotalSize += size;
}
}
public long getValue() {
var hasher = hasherProvider.get();
byte[] raw = buff.get();
hasher.update(ByteBuffer.wrap(raw).putLong(hash).array());
hasher.update(ByteBuffer.wrap(raw).putLong(filesProcessed).array());
hasher.update(ByteBuffer.wrap(raw).putLong(filesTotalSize).array());
return hasher.getValue();
}
}

View File

@ -1,3 +1,21 @@
/*
A simple backup mod for Fabric
Copyright (C) 2022 Szum123321
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.szum123321.textile_backup.core.create; package net.szum123321.textile_backup.core.create;
import net.szum123321.textile_backup.TextileBackup; import net.szum123321.textile_backup.TextileBackup;
@ -16,7 +34,6 @@ public record FileInputStreamSupplier(Path path, String name, CompressionStatus.
@Override @Override
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
try { try {
//TODO: put in hasher
return new HashingInputStream(Files.newInputStream(path), path, null, builder); return new HashingInputStream(Files.newInputStream(path), path, null, builder);
} catch (IOException e) { } catch (IOException e) {
builder.update(path, e); builder.update(path, e);

View File

@ -1,3 +1,21 @@
/*
A simple backup mod for Fabric
Copyright (C) 2022 Szum123321
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.szum123321.textile_backup.core.create; package net.szum123321.textile_backup.core.create;
import net.szum123321.textile_backup.core.CompressionStatus; import net.szum123321.textile_backup.core.CompressionStatus;

View File

@ -1,3 +1,21 @@
/*
A simple backup mod for Fabric
Copyright (C) 2022 Szum123321
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.szum123321.textile_backup.core.create; package net.szum123321.textile_backup.core.create;
import org.apache.commons.compress.parallel.InputStreamSupplier; import org.apache.commons.compress.parallel.InputStreamSupplier;
@ -5,10 +23,8 @@ import org.apache.commons.compress.parallel.InputStreamSupplier;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Path; import java.nio.file.Path;
public interface InputSupplier extends InputStreamSupplier { public interface InputSupplier extends InputStreamSupplier {
InputStream getInputStream() throws IOException; InputStream getInputStream() throws IOException;
Path getPath(); Path getPath();
String getName(); String getName();
} }

View File

@ -0,0 +1,55 @@
/*
A simple backup mod for Fabric
Copyright (C) 2022 Szum123321
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.szum123321.textile_backup.core.restore;
import org.jetbrains.annotations.NotNull;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.zip.Checksum;
public class HashingOutputStream extends FilterOutputStream {
private final Path path;
private final Checksum hasher;
public HashingOutputStream(OutputStream out, Path path, Checksum hasher) {
super(out);
this.path = path;
this.hasher = hasher;
}
@Override
public void write(int b) throws IOException {
super.write(b);
hasher.update(b);
}
@Override
public void write(byte[] @NotNull b, int off, int len) throws IOException {
super.write(b, off, len);
hasher.update(b, off, len);
}
@Override
public void close() throws IOException {
super.close();
}
}