[FEATURE] HashedDir filterAndAdd

This commit is contained in:
Gravita 2021-11-18 16:15:56 +07:00
parent 86b891e30a
commit 54c4604885
2 changed files with 56 additions and 1 deletions

View file

@ -10,10 +10,12 @@
import java.io.IOException; import java.io.IOException;
import java.nio.file.FileVisitResult; import java.nio.file.FileVisitResult;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor; import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.function.Predicate;
public final class HashedDir extends HashedEntry { public final class HashedDir extends HashedEntry {
@LauncherNetworkAPI @LauncherNetworkAPI
@ -63,6 +65,60 @@ public Diff compare(HashedDir other, FileNameMatcher matcher) {
return new Diff(mismatch, extra); return new Diff(mismatch, extra);
} }
public HashedDir filter(Predicate<Path> filter) {
return filterAndAdd(new HashedDir(), filter);
}
public HashedDir filterAndAdd(HashedDir result, Predicate<Path> filter) {
Queue<HashedEntryAndPath> queue = new ArrayDeque<>();
Path path = Paths.get("");
queue.add(new HashedEntryAndPath(path, this, result));
while(!queue.isEmpty()) {
HashedEntryAndPath entry = queue.poll();
if(!filter.test(entry.path)) {
continue;
}
if(entry.entry.getType() == Type.DIR) {
HashedDir dir = (HashedDir) entry.entry;
for(Map.Entry<String, HashedEntry> e : dir.map.entrySet()) {
String key = e.getKey();
HashedEntry value = e.getValue();
if(entry.sideEntry.getType() == Type.FILE) {
throw new IllegalArgumentException(String.format("Filter path: %s failed: expected DIR, found FILE ", entry.path));
}
HashedDir sideDir = (HashedDir) entry.sideEntry;
HashedEntry sideEntry = sideDir.getEntry(key);
if(sideEntry == null) {
if(value.getType() == Type.DIR) {
sideEntry = new HashedDir();
queue.add(new HashedEntryAndPath(entry.path.resolve(key), value, sideEntry));
} else if(value.getType() == Type.FILE) {
sideEntry = value;
}
sideDir.map.put(key, sideEntry);
} else if(sideEntry.getType() == Type.DIR) {
queue.add(new HashedEntryAndPath(entry.path.resolve(key), value, sideEntry));
}
}
}
}
return result;
}
private static class HashedEntryAndPath {
public final HashedEntry entry;
public final HashedEntry sideEntry;
public final Path path;
public HashedEntryAndPath(Path path, HashedEntry entry, HashedEntry sideEntry) {
this.entry = entry;
this.path = path;
this.sideEntry = sideEntry;
}
}
public void remove(String name) { public void remove(String name) {
map.remove(name); map.remove(name);
} }

View file

@ -16,7 +16,6 @@ public abstract class HashedEntry extends StreamObject {
public abstract long size(); public abstract long size();
public enum Type implements EnumSerializer.Itf { public enum Type implements EnumSerializer.Itf {
DIR(1), FILE(2); DIR(1), FILE(2);
private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class); private static final EnumSerializer<Type> SERIALIZER = new EnumSerializer<>(Type.class);