Skip to main content

LineageStore

Struct LineageStore 

Source
pub struct LineageStore {
    pub schema_version: u32,
    pub albums: BTreeMap<String, AlbumArt>,
    pub playlists: BTreeMap<String, PlaylistState>,
    /* private fields */
}
Expand description

The whole lineage graph, kept relational for a clean SQLite migration.

nodes and resolution_cache are BTreeMaps and edges is sorted after every update, so serialisation is deterministic.

Fields§

§schema_version: u32

On-disk schema version, so a future migration can branch on it.

§albums: BTreeMap<String, AlbumArt>

The reconciled folder-art state per album, keyed by the album’s stable root id (HARDENING H2). Additive: absent in older stores. pub so the CLI executor and reconcile can borrow it across the crate boundary.

§playlists: BTreeMap<String, PlaylistState>

The reconciled .m3u8 state per playlist, keyed by the playlist’s Suno id (the synthetic "liked" id for the liked feed). Additive: absent in older stores. pub for the same cross-crate borrow as albums.

Implementations§

Source§

impl LineageStore

Source

pub fn new() -> Self

Create an empty store at the current schema version.

Source

pub fn set_album_overrides(&mut self, overrides: BTreeMap<String, String>)

Layer this run’s manual album-name overrides onto the store.

Keyed by lineage root id, from config each run and never persisted (#[serde(skip)]). Applied wherever the album title is resolved (context_for, album_for_id, colliding_root_titles), so one call makes the path, ALBUM tag, change hash, index, and disambiguation all reflect the preferred name from one source.

Source

pub fn refresh_eligible_roots(&mut self)

Recompute the eligible-root set from the resolution cache.

The non-empty root_ids across the cache’s values — exactly what colliding_root_titles groups over. Called at the end of update and after a load (the field is not serialised).

Source

pub fn node(&self, id: &str) -> Option<&Node>

The node for id, if present.

Source

pub fn get_root(&self, id: &str) -> Option<&CacheEntry>

The cached root resolution for id, if present.

Source

pub fn context_for(&self, clip: &Clip) -> LineageContext

Build a LineageContext for clip from the durable store.

The source of truth for every file-affecting lineage decision (album folder, embedded tags, change hash), so a dropped resolution call never rewrites the library (HARDENING H3). The root comes from the monotonic cache (the clip’s own id when the store has no better answer), its title and date from that root’s archived node, so a transient miss keeps the last-known-good album (even a since-purged ancestor) and the Year tag anchors on the root’s year. The parent edge is read structurally.

Source

pub fn album_for_id(&self, id: &str) -> String

The canonical logical album title for a clip identified only by id.

The store-side counterpart of context_for(clip).album(clip.title) when no live Clip is on hand. Title and root come from the archived nodes and the monotonic cache, then the LineageContext::album rule decides whether the clip folders under its root’s album or its own title. A clip absent from the store folds to a self-root with an empty title.

Source

pub fn colliding_root_titles(&self) -> BTreeSet<String>

The set of effective album titles shared by more than one distinct root.

Two distinct roots must never share an album folder, so naming appends the short root id to the album of any clip whose album is in this set. Computed from the whole archive — every eligible root paired with its effective title (override when configured, else the node title) — so the decision is stable across runs and independent of the current batch: a --since/--limit slice showing only one of two same-titled roots still disambiguates rather than oscillating.

It iterates the same eligible-root set that effective_root_title gates overrides on, so the two can never disagree. A root with no node and no override has an empty effective title and is skipped.

Source

pub fn len(&self) -> usize

Number of nodes in the graph.

Source

pub fn is_empty(&self) -> bool

True when the graph holds no nodes.

Source

pub fn iter(&self) -> Iter<'_, String, Node>

Iterate nodes in clip-id order.

Source

pub fn update(&mut self, clips: &[Clip], resolution: &Resolution, now: &str)

Fold this run’s clips and their Resolution into the store.

Pure: it takes now (an ISO timestamp) from the caller rather than reading a clock. Upserts a node for every clip and every gap-filled ancestor (so trashed ancestors are archived), upserts an edge for every lineage_edges link, and refreshes the monotonic resolution cache. edges is left sorted so the serialised form is deterministic.

Source

pub fn archived_parents(&self) -> HashMap<String, String>

The persisted child_id -> parent_id map from the active primary edges (each clip’s ordinal-0 lineage parent), for seeding resolve_roots.

This lets a resolution walk hop through an ancestor whose clip is absent this run (an intermediate remix, or one Suno has purged) using the link captured on an earlier run, instead of self-rooting. It is resolution input only: these ids are never download candidates.

Source§

impl LineageStore

Source

pub fn owner(&self) -> Option<&Owner>

The account this library is pinned to, if any.

Source

pub fn pin_owner(&mut self, owner: Owner)

Pin this library to owner, replacing any prior pin.

Source

pub fn refresh_display_name(&mut self, display_name: &str) -> bool

Refresh the pinned owner’s display name when it has changed, returning whether it changed. A no-op when the library is not pinned.

Trait Implementations§

Source§

impl Clone for LineageStore

Source§

fn clone(&self) -> LineageStore

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for LineageStore

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for LineageStore

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for LineageStore

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for LineageStore

Equality over the durable graph only.

album_overrides and eligible_root_ids are runtime-only overlays (#[serde(skip)]): the first is layered from config each run, the second is a cache derived from resolution_cache. Neither is part of the persisted relational shape, so two stores are equal when their durable content is, regardless of the overrides in force or whether the derived set has been refreshed after a load.

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for LineageStore

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.