Home of the Squeezebox™ & Transporter® network music players.
Page 1 of 2 12 LastLast
Results 1 to 10 of 17
  1. #1
    Senior Member
    Join Date
    May 2005
    Location
    UK
    Posts
    832

    SimpleLibraryViews plugin update increases library build time by a factor of 10

    Hi all,

    I've updated my SimpleLibraryViews plugin to allow for the library definition file to work for a directory and all of its subdirectories. I believe I'm caching the files existence such that there should only be one trip to the filesystem for each check in a directory.

    However, it appears that the build time has increased by a factor of around 10 (on my LMS it's gone from < 10 seconds to about 90 seconds). Another tester has seen a similar increase, from about 30 seconds to over 10 minutes.

    Anyone care to take a look at the library code to see if I've done anything stupid? The code in question starts here:

    https://github.com/adhawkins/SimpleL...Plugin.pm#L149

    I'm calling the following LMS functions within the loop. Do any of them involve a trip to the filesystem, which may explain it?

    • Slim::Music::Info::isFileURL
    • Slim::Utils::Misc::pathFromFileURL
    • Slim::Utils::Misc::inMediaFolder


    Appreciate any advice you more knowledgeable people might be able to offer!

    Andy

  2. #2
    Senior Member
    Join Date
    May 2005
    Location
    UK
    Posts
    832
    A quick look through the code (my Perl is rusty!) suggests that inMediaFolder is calling down into pathFromFileURL, which does involve a trip to the filesystem, but this result should be cached. If my use of 'inMediaFolder' OK as I rise up the directory tree, to make sure I don't leave the defined media folders?

    I'm tempted to take this check out and just allow it to go right up to the root to see if it has any beneficial effect on the build time.

    Andy

  3. #3
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    20,724

    SimpleLibraryViews plugin update increases librarybuild time by a factor of 10

    > However, it appears that the build time has increased by a factor of
    > around 10 (on my LMS it's gone from < 10 seconds to about 90 seconds).
    > Another tester has seen a similar increase, from about 30 seconds to
    > over 10 minutes.


    Can you say what change causes the issue? Maybe you can go back in git
    history to see what commit changed behaviour?

    From a first quick look I was wondering whether it wouldn't be more
    efficient to search for your your simple-library-views-* files, then map
    these to the tracks, rather than the opposite?


  4. #4
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    20,724

    SimpleLibraryViews plugin update increases librarybuild time by a factor of 10

    > Can you say what change causes the issue? Maybe you can go back in git
    > history to see what commit changed behaviour?


    I believe that even if you don't hit the filesystem, you're going to
    test the same folders over and over again: if none of your files is
    found, you'd walk up the folder hierarchy. And you'd do this over and
    over again. Sure, by checking the cache (which could become pretty big
    in a large collection) you cut short. But still, you do this several times.

    > From a first quick look I was wondering whether it wouldn't be more
    > efficient to search for your your simple-library-views-* files, then map
    > these to the tracks, rather than the opposite?


    I'd definitely recommend using File::Next or File::Find to get a list of
    library names with the folders they use. Then query the DB based on the
    folder. As you'd be able to insert based on the url that could be a
    pretty efficient SQL query. Something like

    INSERT OR IGNORE INTO library_track (library, track)
    SELECT ?, tracks.id
    FROM tracks
    WHERE url like ?
    AND content_type NOT IN ("cpl", "src", "ssp", "dir")

    where arguments are the library ID and the "file://path/to/folder%"
    (haven't tested this, but I assume you get the point).

    Oh, and you got quite a few "libary" instead of "library" in your readme
    :-).

  5. #5
    Senior Member
    Join Date
    May 2005
    Location
    UK
    Posts
    832
    Quote Originally Posted by mherger View Post
    I'd definitely recommend using File::Next or File::Find to get a list of
    library names with the folders they use. Then query the DB based on the
    folder. As you'd be able to insert based on the url that could be a
    pretty efficient SQL query. Something like

    INSERT OR IGNORE INTO library_track (library, track)
    SELECT ?, tracks.id
    FROM tracks
    WHERE url like ?
    AND content_type NOT IN ("cpl", "src", "ssp", "dir")

    where arguments are the library ID and the "file://path/to/folder%"
    (haven't tested this, but I assume you get the point).
    So you're saying I should use File::Next to search for '.simple-library-views-<libname>' files. Then for each one of these it finds, call the query you quote passing in file://dirname(fullpath-to-slv-file)/. Will your query handle if (for example) they have library files in both:

    • /var/spool/music/A/Andy/
    • /var/spool/music/A/Andy/Album 1


    This would find the same track ID twice, would the query handle that?

    Quote Originally Posted by mherger View Post
    Oh, and you got quite a few "libary" instead of "library" in your readme
    :-).
    Whoops! Nobody has spotted that since I first published the plugin something like 6 years ago!

    Andy

  6. #6
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    20,724

    SimpleLibraryViews plugin update increases librarybuild time by a factor of 10

    > So you're saying I should use File::Next to search for
    > '.simple-library-views-<libname>' files. Then for each one of these it
    > finds, call the query you quote passing in
    > file://dirname(fullpath-to-slv-file)/.


    Only the path, not including the file name, of course. But basically
    yes, this.

    > Will your query handle if (for
    > example) they have library files in both:
    >
    > - /var/spool/music/A/Andy/
    > - /var/spool/music/A/Andy/Album 1


    As the first one would include the second one anyway you should filter
    out sub-folders of folders already included. This would prevent
    redundant processing. But the result otherwise should be the same, as
    the query does "INSERT OR IGNORE" - ignore a command if the resulting
    record already exists.

  7. #7
    Babelfish's Best Boy mherger's Avatar
    Join Date
    Apr 2005
    Location
    Switzerland
    Posts
    20,724

    SimpleLibraryViews plugin update increases librarybuild time by a factor of 10

    >> So you're saying I should use File::Next to search for
    >> '.simple-library-views-<libname>' files. Then for each one of these it
    >> finds, call the query you quote passing in
    >> file://dirname(fullpath-to-slv-file)/.

    >
    > Only the path, not including the file name, of course. But basically
    > yes, this.


    That said: it would always be good to understand where you're loosing
    time before re-implementing everything :-). Did you ever try to measure
    time for the various parts in your code and compare with the older version?

  8. #8
    Senior Member
    Join Date
    May 2005
    Location
    UK
    Posts
    832
    Ok, I've made those changes as suggested. Code is a lot simpler, and also much faster. My original 7 second library build time is now about 15 seconds (compared to 90 seconds for the first attempt at the 'recursive' implementation).

    One question, to go through all the libraries I'm iterating over the result of 'Slim::Utils::Misc::getAudioDirs()'. Is that the right thing to do?

    Thanks for the assistance, much appreciated as usual.

    Andy

  9. #9
    Senior Member
    Join Date
    May 2005
    Location
    UK
    Posts
    832
    Quote Originally Posted by mherger View Post
    As the first one would include the second one anyway you should filter
    out sub-folders of folders already included. This would prevent
    redundant processing. But the result otherwise should be the same, as
    the query does "INSERT OR IGNORE" - ignore a command if the resulting
    record already exists.
    Any suggestions on how to do this filtering? Perl is far from my first language!

    Andy

  10. #10
    Senior Member
    Join Date
    May 2005
    Location
    UK
    Posts
    832
    Also, I've had a request to make the recursive behaviour configurable. Given the way the scanning code works, is there any way I could achieve this? The SQL SELECT statement that finds the tracks would need to only accept ones that are in a directory that has a matching file. I guess I could make the select / insert a two stage process, select all the files that match, then go through these and only accept ones that are in the actual directory?

    Andy

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •