Skip to content

Commit 2ec7b55

Browse files
Better "isLastChild" detection algorithm
1 parent 6043d67 commit 2ec7b55

File tree

3 files changed

+29
-29
lines changed

3 files changed

+29
-29
lines changed

ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
- [x] Regroup all formatting work under single "LineFormatter"
66
- [x] Builder with options (depth symbols, emoji, child limit)
77
- [x] Unit tests, using @TempDir
8+
- [x] Better "isLastChild" detection algorithm
89
- [ ] Max depth options
9-
- [ ] Better "isLast" detection algorithm
1010
- [ ] Unify dir-in-a-row into a single entry option
1111

1212
## Other ideas

src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/visitor/ChildVisitCounter.java renamed to src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/visitor/ChildVisitRegister.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@
55
import java.nio.file.Files;
66
import java.nio.file.Path;
77
import java.util.ArrayList;
8-
import java.util.HashSet;
8+
import java.util.LinkedHashSet;
99
import java.util.List;
1010
import java.util.Set;
1111
import java.util.function.Function;
1212
import org.jspecify.annotations.NullMarked;
1313

1414
@NullMarked
15-
class ChildVisitCounter {
15+
class ChildVisitRegister {
1616

1717
private final Function<Path, Integer> childrenLimitFunction;
1818
private final List<ChildVisitCounterRecord> records;
1919

20-
public ChildVisitCounter(Function<Path, Integer> childrenLimitFunction) {
20+
public ChildVisitRegister(Function<Path, Integer> childrenLimitFunction) {
2121
this.childrenLimitFunction = childrenLimitFunction;
22-
this.records = new ArrayList<ChildVisitCounter.ChildVisitCounterRecord>();
22+
this.records = new ArrayList<ChildVisitRegister.ChildVisitCounterRecord>();
2323
}
2424

2525
public void enterNewDirectory(Path dir) {
@@ -29,8 +29,8 @@ public void enterNewDirectory(Path dir) {
2929
records.add(newRecord);
3030
}
3131

32-
private Set<Path> listChildren(Path dir) {
33-
var children = new HashSet<Path>();
32+
private LinkedHashSet<Path> listChildren(Path dir) {
33+
var children = new LinkedHashSet<Path>();
3434
try (var stream = Files.newDirectoryStream(dir)) {
3535
for (Path child : stream) {
3636
children.add(child);
@@ -48,6 +48,13 @@ public void registerChildVisitInCurrentDir(Path visited) {
4848
records.getLast().registerChildVisit(visited);
4949
}
5050

51+
public boolean isLastChildInCurrentDir(Path path) {
52+
if (records.isEmpty()) {
53+
return true;
54+
}
55+
return records.getLast().notVisited.isEmpty() || records.getLast().notVisited.getLast().equals(path);
56+
}
57+
5158
public void exitCurrentDirectory() {
5259
records.removeLast();
5360
}
@@ -67,13 +74,13 @@ public boolean hasSomeNotVisitedChildren() {
6774
private class ChildVisitCounterRecord {
6875

6976
private final int maxChildVisitCount;
70-
private Set<Path> notVisited;
71-
private Set<Path> alreadyVisited;
77+
private LinkedHashSet<Path> notVisited;
78+
private LinkedHashSet<Path> alreadyVisited;
7279

73-
ChildVisitCounterRecord(int maxChildVisitCount, Set<Path> childrenInDir) {
80+
ChildVisitCounterRecord(int maxChildVisitCount, LinkedHashSet<Path> childrenInDir) {
7481
this.maxChildVisitCount = maxChildVisitCount;
7582
this.notVisited = childrenInDir;
76-
this.alreadyVisited = new HashSet<Path>();
83+
this.alreadyVisited = new LinkedHashSet<Path>();
7784
}
7885

7986
void registerChildVisit(Path visited) {

src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/visitor/DefaultFileTreePrettyPrintVisitor.java

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import io.github.computerdaddyguy.jfiletreeprettyprinter.PrettyPrintOptions;
44
import io.github.computerdaddyguy.jfiletreeprettyprinter.visitor.renderer.LineRenderer;
5-
import java.io.File;
65
import java.io.IOException;
76
import java.nio.file.FileVisitResult;
87
import java.nio.file.Path;
@@ -17,15 +16,15 @@ class DefaultFileTreePrettyPrintVisitor implements FileTreePrettyPrintVisitor {
1716

1817
private StringBuilder buff;
1918
private Depth depth;
20-
private ChildVisitCounter counter;
19+
private ChildVisitRegister register;
2120

2221
public DefaultFileTreePrettyPrintVisitor(PrettyPrintOptions options, LineRenderer lineRenderer) {
2322
super();
2423
this.lineRenderer = lineRenderer;
2524

2625
this.buff = new StringBuilder();
2726
this.depth = new Depth();
28-
this.counter = new ChildVisitCounter(options.getChildrenLimitFunction());
27+
this.register = new ChildVisitRegister(options.getChildrenLimitFunction());
2928
}
3029

3130
@Override
@@ -36,7 +35,7 @@ public String getResult() {
3635
@Override
3736
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
3837
// COUNTER
39-
if (counter.exceedsCurrentLimit()) {
38+
if (register.exceedsCurrentLimit()) {
4039
return FileVisitResult.SKIP_SIBLINGS;
4140
}
4241

@@ -48,19 +47,19 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
4847
depth = depth.append(DepthSymbol.NON_LAST_FILE); // assume not last until proven otherwise
4948

5049
// COUNTER
51-
counter.registerChildVisitInCurrentDir(dir);
52-
counter.enterNewDirectory(dir);
50+
register.registerChildVisitInCurrentDir(dir);
51+
register.enterNewDirectory(dir);
5352

5453
return FileVisitResult.CONTINUE;
5554
}
5655

5756
@Override
5857
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
5958
// COUNTER
60-
if (counter.exceedsCurrentLimit()) {
59+
if (register.exceedsCurrentLimit()) {
6160
return FileVisitResult.SKIP_SIBLINGS;
6261
}
63-
counter.registerChildVisitInCurrentDir(file);
62+
register.registerChildVisitInCurrentDir(file);
6463

6564
// DEPTH
6665
updateDepth(file);
@@ -95,13 +94,13 @@ public FileVisitResult postVisitDirectory(Path dir, @Nullable IOException exc) t
9594
depth = depth.pop();
9695

9796
// COUNTER
98-
var limitReached = counter.hasSomeNotVisitedChildren();
97+
var limitReached = register.hasSomeNotVisitedChildren();
9998
if (limitReached) {
10099
depth = depth.append(DepthSymbol.LAST_FILE);
101-
appendNewLine(lineRenderer.renderLimitReached(depth, counter.notVisitedInCurrentDir()));
100+
appendNewLine(lineRenderer.renderLimitReached(depth, register.notVisitedInCurrentDir()));
102101
depth = depth.pop();
103102
}
104-
counter.exitCurrentDirectory();
103+
register.exitCurrentDirectory();
105104

106105
if (limitReached) {
107106
return FileVisitResult.SKIP_SIBLINGS;
@@ -114,17 +113,11 @@ private void updateDepth(Path path) {
114113
return;
115114
}
116115

117-
var isLast = isLastChild(path);
116+
var isLast = register.isLastChildInCurrentDir(path);
118117
depth = depth.pop();
119118
depth = depth.append(isLast ? DepthSymbol.LAST_FILE : DepthSymbol.NON_LAST_FILE);
120119
}
121120

122-
private boolean isLastChild(Path path) {
123-
Path parent = path.getParent();
124-
File[] siblings = parent.toFile().listFiles();
125-
return siblings != null && siblings[siblings.length - 1].toPath().equals(path);
126-
}
127-
128121
private void appendNewLine(@Nullable String str) {
129122
if (str != null) {
130123
if (buff.length() > 0) {

0 commit comments

Comments
 (0)