This is one of those things that I find shocking.  Squeak has been around for 
15+ years, and still has no efficient way to get files matching a wildcard 
pattern (I sure couldn't find it), FFI does not (easily) support callbacks, etc.




________________________________________
From: pharo-project-boun...@lists.gforge.inria.fr 
[pharo-project-boun...@lists.gforge.inria.fr] on behalf of Nicolas Cellier 
[nicolas.cellier.aka.n...@gmail.com]
Sent: Wednesday, May 09, 2012 6:18 PM
To: Pharo Development
Subject: [Pharo-project] FileList efficiency could hardly be worse

The efficiency of FileList>>listForPattern: is something which should
deserve a bit more care.

It tries to sort the files, for example by name, but wants to display
directory first
        ^ [ :x :y | |xIsDir|
                        ((xIsDir := x isDirectory) = y isDirectory)
                                ifTrue: [   x basename <= y basename  ]
                                ifFalse: [
                                        "directories always precede files"
                                        xIsDir ]]

Alas, this isDirectory test cost you an arm:

FileReference>>isDirectory
        ^ filesystem isDirectory: path

FileSystem>>isDirectory: aResolvable
        "Resolve the argument, and answer true if the result refers
        to a directory, false if it refers to a file or doesn't exist."

        ^ store isDirectory: (self resolve: aResolvable)

FileSystemStore>>isDirectory: aPath
        aPath isRoot ifTrue: [ ^ true ].
        self
                nodeAt: aPath
                ifPresent: [ :entry | ^ self basicIsDirectory: entry ]
                ifAbsent: [ ^ false ].

DiskStore>>nodeAt: aPath ifPresent: presentBlock ifAbsent: absentBlock
        | name|
        aPath isRoot ifTrue: [ ^ presentBlock value: self rootNode ].
        "| encodedPath encodedBasename entry |
        encodedPath := Primitives encode: (self stringFromPath: aPath parent).
        encodedBasename := Primitives encode: aPath basename.
        entry := Primitives lookupDirectory: encodedPath filename: 
encodedBasename.
        ^ entry == #badDirectoryPath
                ifTrue: absentBlock
                ifFalse: [
                        entry at: 1 put: aPath basename.
                        presentBlock value: entry ]."
        name := aPath basename.
        self
                directoryAt: aPath parent
                ifAbsent: absentBlock
                nodesDo:
                        [ :entry |
                        (self filename: (entry at: 1) matches: name)
                                ifTrue: [ ^ presentBlock value: entry ] ].
        ^ absentBlock value

Arghh, it scans the whole parent directory again!
If sort is O(n log n), then we transform it into O(2 n^2 log n).

Try to browse your package-cache if you're not a chicken.
Seriously, it's unusable...

Nicolas


Reply via email to