|
430 | 430 | ;;; `:needs-hydration?`, replace it with the first hydrated instance; repeat this process until we have spliced all
|
431 | 431 | ;;; the hydrated instances back in.
|
432 | 432 |
|
433 |
| -(defn- merge-hydrated-instances |
434 |
| - "Merge the annotated instances as returned by [[annotate-instances]] and the hydrated instances as returned |
435 |
| - by [[hydrate-annotated-instances]] back into a single un-annotated sequence. |
436 |
| -
|
437 |
| - (merge-hydrated-instances |
438 |
| - [{:needs-hydration? false, :instance {:x 1, :y 1}} |
439 |
| - {:needs-hydration? false, :instance {:x 2, :y 2}} |
440 |
| - {:needs-hydration? true, :instance {:x 3}} |
441 |
| - {:needs-hydration? true, :instance {:x 4}} |
442 |
| - {:needs-hydration? false, :instance {:x 5, :y 5}} |
443 |
| - {:needs-hydration? true, :instance {:x 6}}] |
444 |
| - [{:x 3, :y 3} {:x 4, :y 4} {:x 6, :y 6}]) |
445 |
| - => |
446 |
| - [{:x 1, :y 1} |
447 |
| - {:x 2, :y 2} |
448 |
| - {:x 3, :y 3} |
449 |
| - {:x 4, :y 4} |
450 |
| - {:x 5, :y 5} |
451 |
| - {:x 6, :y 6}]" |
452 |
| - [annotated-instances hydrated-instances] |
453 |
| - (loop [acc [], annotated-instances annotated-instances, hydrated-instances hydrated-instances] |
454 |
| - (if (empty? hydrated-instances) |
455 |
| - (concat acc (map :instance annotated-instances)) |
456 |
| - (let [[not-hydrated [_needed-hydration & more]] (split-with (complement :needs-hydration?) annotated-instances)] |
457 |
| - (recur (vec (concat acc (map :instance not-hydrated) [(first hydrated-instances)])) |
458 |
| - more |
459 |
| - (rest hydrated-instances)))))) |
460 |
| - |
461 |
| -(defn- annotate-instances [model k instances] |
462 |
| - (for [instance instances] |
463 |
| - {:needs-hydration? (needs-hydration? model k instance) |
464 |
| - :instance instance})) |
465 |
| - |
466 |
| -(defn- hydrate-annotated-instances [model k annotated-instances] |
467 |
| - (when-let [instances-that-need-hydration (not-empty (map :instance (filter :needs-hydration? annotated-instances)))] |
468 |
| - (batched-hydrate model k instances-that-need-hydration))) |
| 433 | +(defn- index-instances-needing-hydration |
| 434 | + "Given a list of instances, return a list of the same length and order where each element is a tuple `[i instance]`. |
| 435 | + For instances that need hydration, `i` represents the serial number of instances needing hydration. For instances that |
| 436 | + don't need hydration, `i` is nil." |
| 437 | + [model k instances] |
| 438 | + (let [idx (volatile! -1)] |
| 439 | + (mapv (fn [instance] |
| 440 | + [(when (needs-hydration? model k instance) |
| 441 | + (vswap! idx inc)) |
| 442 | + instance]) |
| 443 | + instances))) |
469 | 444 |
|
470 | 445 | (m/defmethod hydrate-with-strategy ::multimethod-batched
|
471 | 446 | [model _strategy k instances]
|
472 |
| - (let [annotated-instances (annotate-instances model k instances) |
473 |
| - hydrated-instances (hydrate-annotated-instances model k annotated-instances)] |
474 |
| - (merge-hydrated-instances annotated-instances hydrated-instances))) |
| 447 | + (let [indexed (index-instances-needing-hydration model k instances) |
| 448 | + instances-to-hydrate (not-empty (map second (filter first indexed))) ;; Important: keep doesn't work here. |
| 449 | + hydrated-instances (when instances-to-hydrate |
| 450 | + (vec (batched-hydrate model k instances-to-hydrate)))] |
| 451 | + (mapv (fn [[i unhydrated-instance]] |
| 452 | + (if i |
| 453 | + (nth hydrated-instances i) |
| 454 | + unhydrated-instance)) |
| 455 | + indexed))) |
475 | 456 |
|
476 | 457 |
|
477 | 458 | ;;; Method-Based Simple Hydration (using impls of [[simple-hydrate]])
|
|
0 commit comments