« get me outta code hell

Cache flattened playlist - http-music - Command-line music player + utils (not a server!)
about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2017-09-05 21:20:02 -0300
committerFlorrie <towerofnix@gmail.com>2017-09-05 21:20:02 -0300
commita724b26d5435db7647941f4f62e6ca3a12a63b06 (patch)
tree5f9d31cd8c47f58fb4c71c3b1aa627bf0b11ef00
parent81110492590b1aab8daac30803d2dd93bd8ece15 (diff)
Cache flattened playlist
-rw-r--r--src/pickers2.js25
-rw-r--r--todo.txt1
2 files changed, 21 insertions, 5 deletions
diff --git a/src/pickers2.js b/src/pickers2.js
index f1b53eb..f07cd91 100644
--- a/src/pickers2.js
+++ b/src/pickers2.js
@@ -187,6 +187,8 @@ function sortFlattenGrouplike(grouplike, sort, seed) {
   }
 }
 
+const flattenedCache = Symbol('Cache of flattened')
+
 function generalPicker(playlist, lastTrack, options) {
   const { sort, loop } = options
 
@@ -204,11 +206,22 @@ function generalPicker(playlist, lastTrack, options) {
     throw new Error(`Invalid loop mode: ${loop}`)
   }
 
-  const flattened = sortFlattenGrouplike(playlist, sort, options.seed)
-  if (typeof options.seed === 'undefined') {
-    options.seed = flattened.newSeed
+  // Regenerating the flattened list is really time-expensive, so we make sure
+  // to cache the result of the operation (in the 'options' property, which is
+  // used to store "state"-specific data for the picker).
+  let flattened
+  if (options.hasOwnProperty(flattenedCache)) {
+    flattened = options[flattenedCache]
+  } else {
+    flattened = sortFlattenGrouplike(playlist, sort, options.seed)
+
+    if (typeof options.seed === 'undefined') {
+      options.seed = flattened.newSeed
+    }
+    delete flattened.newSeed
+
+    options[flattenedCache] = flattened
   }
-  delete flattened.newSeed
 
   const index = flattened.items.indexOf(lastTrack)
 
@@ -225,9 +238,11 @@ function generalPicker(playlist, lastTrack, options) {
       // Deletes the random number generation seed then starts over. Assigning
       // a new RNG seed makes it so we get a new shuffle the next time, and
       // clearing the lastTrack value makes generalPicker thinks we're
-      // starting over.
+      // starting over. We also need to destroy the flattenedCache, or else it
+      // won't actually recalculate the list.
       const newSeed = seedRandom(options.seed)()
       options.seed = newSeed
+      delete options[flattenedCache]
       return generalPicker(playlist, null, options)
     }
 
diff --git a/todo.txt b/todo.txt
index 5cde299..65c2281 100644
--- a/todo.txt
+++ b/todo.txt
@@ -339,3 +339,4 @@ TODO: Now that we're using seeded randomness, generating the entire timeline
       every time we want to call the picker is definitely really slow. There
       should be some way to make it faster. (Maybe store the playlist on the
       mutable options object?).
+      (Done!)