[squeak-dev] The Inbox: Files-ul.125.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Jul 3 05:46:43 UTC 2013


A new version of Files was added to project The Inbox:
http://source.squeak.org/inbox/Files-ul.125.mcz

==================== Summary ====================

Name: Files-ul.125
Author: ul
Time: 3 July 2013, 7:35:48.693 am
UUID: 5a53740b-df37-4fb1-90af-d803dbda9593
Ancestors: Files-fbs.124

FileDirectory >> #directoryTreeDo: uses BFS instead of DFS.
FileDirectory >> #statsForDirectoryTree: uses #directoryTreeDo: instead of reimplementing a BFS algorithm.

=============== Diff against Files-fbs.124 ===============

Item was changed:
  ----- Method: FileDirectory>>directoryTreeDo: (in category 'enumeration') -----
  directoryTreeDo: oneArgBlock 
  	"For each file and directory in my tree, value oneArgBlock with an OrderedCollection of the path of DirectoryEntry's leading to the current node.  The first element in the collection will be the DirectoryEntryDirectory for myself, the last is the currentNode (a DirectoryEntry)."
+ 	"Implementation details:
+ 	This is a simple BFS algorithm with additional stuff to ensure that the path to the root directory is available. The elements in the queue (aka the graph nodes) are tuples. Each tuple has 3 elements: a DirectoryEntry, the parent tuple, and the length of the path to the root. Each directory in the tree will have a corresponding tuple. Since each tuple contains a pointer to its parent directory's tuple, therefore large parts of the directory tree (not including files) will be stored in memory. Updating currentPath doesn't take more than visiting all nodes in that tree, so its total runtime cost is O(d), where d is the number of directories in the directory tree, which means that the amortized cost of keeping the path up-to-date is O(1).
+ 	The reason why we use BFS instead of DFS (which naturally has the path to the current entry from the root) is because the primitives in FilePlugin work better this way."
+ 
+ 	| queue currentPath |
+ 	currentPath := OrderedCollection with: self directoryEntry.
+ 	oneArgBlock value: currentPath.
+ 	queue := OrderedCollection with: { currentPath first. nil. 1 }.
+ 	[ queue isEmpty ] whileFalse: [
+ 		| parentTuple fixupTuple newPathLength |
+ 		parentTuple := queue removeFirst.
+ 		"Update currentPath to contain the entries to parentTuple from the root."
+ 		fixupTuple := parentTuple.
+ 		currentPath size < fixupTuple third ifTrue: [ "Next row in the tree, extend the path."
+ 			currentPath add: fixupTuple first.
+ 			fixupTuple := fixupTuple second ].
+ 		[ (currentPath at: fixupTuple third) == fixupTuple first ] whileFalse: [
+ 			currentPath at: fixupTuple third put: fixupTuple first.
+ 			fixupTuple := fixupTuple second ].
+ 		"Visit the sub-entries"
+ 		newPathLength := parentTuple third + 1.
+ 		currentPath add: nil. "Extend the path with a new slot"
+ 		parentTuple first asFileDirectory entriesDo: [ :entry |
+ 			currentPath atLast: 1 put: entry.
+ 			oneArgBlock value: currentPath.
+ 			entry isDirectory ifTrue: [ 
+ 				queue addLast: { entry. parentTuple. newPathLength } ] ].
+ 		currentPath removeLast ]!
- 	|myEntry|
- 	myEntry := OrderedCollection with: self directoryEntry.
- 	oneArgBlock value: myEntry.
- 	self 
- 		directoryTreeDo: oneArgBlock
- 		entries: myEntry!

Item was removed:
- ----- Method: FileDirectory>>directoryTreeDo:entries: (in category 'enumeration') -----
- directoryTreeDo: oneArgBlock entries: entriesCollection 
- 	"Value oneArgBlock with the path (an OrderedCollection of FileDirectory's) to each DirectoryEntry and the DirectoryEntry itself."
- 	self entries do: 
- 		[ : each | 
- 		entriesCollection add: each.
- 		oneArgBlock value: entriesCollection.
- 		each isDirectory ifTrue: 
- 			[ | subdir |
- 			subdir := each asFileDirectory.
- 			subdir 
- 				directoryTreeDo: oneArgBlock
- 				entries: entriesCollection ].
- 		entriesCollection removeLast ]!

Item was added:
+ ----- Method: FileDirectory>>entriesDo: (in category 'enumeration') -----
+ entriesDo: oneArgumentBlock
+ 	"Evaluate oneArgumentBlock with DirectoryEntry objects for the files and directories in this directory."
+ 	
+ 	^self directoryContentsFor: pathName do: oneArgumentBlock
+ !

Item was changed:
  ----- Method: FileDirectory>>statsForDirectoryTree: (in category 'enumeration') -----
  statsForDirectoryTree: rootedPathName
  	"Return the size statistics for the entire directory tree starting at the given root. The result is a three element array of the form: (<number of folders><number of files><total bytes in all files>). This method also serves as an example of how recursively enumerate a directory tree."
  	"FileDirectory default statsForDirectoryTree: '\smalltalk'"
  
+ 	| dirs files bytes |
- 	| dirs files bytes todo entries p |
  	dirs := files := bytes := 0.
+ 	(FileDirectory on: rootedPathName) directoryTreeDo: [ :path |
+ 		| entry |
+ 		entry := path last.
+ 		entry isDirectory
+ 			ifTrue: [ dirs := dirs + 1 ]
+ 			ifFalse: [
+ 				files := files + 1.
+ 				bytes := bytes + entry fileSize ] ].
+ 	^{ dirs. files. bytes }
- 	todo := OrderedCollection with: rootedPathName.
- 	[todo isEmpty] whileFalse: [
- 		p := todo removeFirst.
- 		entries := self directoryContentsFor: p.
- 		entries do: [:entry |
- 			entry isDirectory
- 				ifTrue: [
- 					todo addLast: p , self pathNameDelimiter asString , entry name.
- 					dirs := dirs + 1]
- 				ifFalse: [
- 					files := files + 1.
- 					bytes := bytes + entry fileSize]]].
- 	^ Array with: dirs with: files with: bytes
  !



More information about the Squeak-dev mailing list