Refactor: use ArrayDeque instead of Stack in FileTreeWalkIterator

Cleanup modifiers, replace if with when.

#KT-27251 Fixed
This commit is contained in:
Ilya Gorbunov
2018-11-16 05:33:04 +03:00
parent 52ca1803d3
commit c0a7c5cff4
@@ -10,7 +10,7 @@ package kotlin.io
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.util.Stack import java.util.ArrayDeque
/** /**
* An enumeration to describe possible walk directions. * An enumeration to describe possible walk directions.
@@ -47,12 +47,12 @@ public class FileTreeWalk private constructor(
/** Returns an iterator walking through files. */ /** Returns an iterator walking through files. */
override public fun iterator(): Iterator<File> = FileTreeWalkIterator() override fun iterator(): Iterator<File> = FileTreeWalkIterator()
/** Abstract class that encapsulates file visiting in some order, beginning from a given [root] */ /** Abstract class that encapsulates file visiting in some order, beginning from a given [root] */
private abstract class WalkState(val root: File) { private abstract class WalkState(val root: File) {
/** Call of this function proceeds to a next file for visiting and returns it */ /** Call of this function proceeds to a next file for visiting and returns it */
abstract public fun step(): File? public abstract fun step(): File?
} }
/** Abstract class that encapsulates directory visiting in some order, beginning from a given [rootDir] */ /** Abstract class that encapsulates directory visiting in some order, beginning from a given [rootDir] */
@@ -66,17 +66,14 @@ public class FileTreeWalk private constructor(
private inner class FileTreeWalkIterator : AbstractIterator<File>() { private inner class FileTreeWalkIterator : AbstractIterator<File>() {
// Stack of directory states, beginning from the start directory // Stack of directory states, beginning from the start directory
private val state = Stack<WalkState>() private val state = ArrayDeque<WalkState>()
init { init {
if (start.isDirectory) { when {
state.push(directoryState(start)) start.isDirectory -> state.push(directoryState(start))
} else if (start.isFile) { start.isFile -> state.push(SingleFileState(start))
state.push(SingleFileState(start)) else -> done()
} else {
done()
} }
} }
override fun computeNext() { override fun computeNext() {
@@ -95,14 +92,9 @@ public class FileTreeWalk private constructor(
} }
} }
tailrec private fun gotoNext(): File? { private tailrec fun gotoNext(): File? {
// Take next file from the top of the stack or return if there's nothing left
if (state.empty()) { val topState = state.peek() ?: return null
// There is nothing in the state
return null
}
// Take next file from the top of the stack
val topState = state.peek()!!
val file = topState.step() val file = topState.step()
if (file == null) { if (file == null) {
// There is nothing more on the top of the stack, go back // There is nothing more on the top of the stack, go back
@@ -133,7 +125,7 @@ public class FileTreeWalk private constructor(
private var failed = false private var failed = false
/** First all children, then root directory */ /** First all children, then root directory */
override public fun step(): File? { override fun step(): File? {
if (!failed && fileList == null) { if (!failed && fileList == null) {
if (onEnter?.invoke(root) == false) { if (onEnter?.invoke(root) == false) {
return null return null
@@ -170,7 +162,7 @@ public class FileTreeWalk private constructor(
private var fileIndex = 0 private var fileIndex = 0
/** First root directory, then all children */ /** First root directory, then all children */
override public fun step(): File? { override fun step(): File? {
if (!rootVisited) { if (!rootVisited) {
// First visit root // First visit root
if (onEnter?.invoke(root) == false) { if (onEnter?.invoke(root) == false) {