YAACC - UPNP Client and Server
Loading...
Searching...
No Matches
de.yaacc.util.SAFCacheManager Class Reference

LRU cache for SAF (Storage Access Framework) file metadata with background preloading. More...

Collaboration diagram for de.yaacc.util.SAFCacheManager:
Collaboration graph

Classes

interface  DurationExtractor
 The two ways a duration is read from a file. More...
 

Public Member Functions

SAFMetadata getMetadata (Uri uri, String name, String providerMimeType, long fileSize)
 Get complete metadata for a SAF file (duration, MIME type, encoded ID).
 
SAFMetadata[] getMetadataBulk (List< SafMetadataRequest > requests)
 The metadata of many files at once (a Browse of a folder): the same results as getMetadata called for each one, in the same order, for the cost of one load check, a lock acquisition per {@value BULK_CHUNK} files instead of one per file and ONE write of what was new (a cold cache of N files is N new entries; the single calls schedule a write after every {@value FLUSH_MAX_CHANGES} of them, and every write rewrites the whole preferences file).
 
SafBrowseGate browseGate ()
 The gate a Browse of the SAF content opens while it is answered (SafBrowseGate#enter() / exit()); the duration preload and the background duration tasks wait (at most {@value PRELOAD_BACKOFF_MAX_MILLIS} ms each time) between two files while it is open, so a Browse does not compete with them for the provider and the processor.
 
String getOrCreateShortId (String uri)
 Get or create a short ID for a URI.
 
String getUriForShortId (String shortId)
 Get URI for a short ID.
 
String guessMimeTypeFromExtension (String filename)
 
String getDuration (Uri uri)
 Get duration from cache or extract if not cached.
 
void preloadSafDurations ()
 Preload durations for SAF files in background.
 
void trimCache ()
 Writes what waits in memory (on the I/O thread, so this returns at once).
 
void removeCachedUnder (String treeUri)
 Forgets the cached metadata (durations) of every file below a SAF tree whose permission was given up, in memory at once and in the stored state on the I/O thread.
 
void clearCache ()
 Clear all cached metadata and ID mappings.
 
void shutdown ()
 
boolean isPreloading ()
 
int getTotalFilesIndexed ()
 
int getCacheSize ()
 

Static Public Member Functions

static synchronized SAFCacheManager getInstance (Context context)
 
static void flushIfCreated (long waitMillis)
 Writes the changes that wait in memory, if the manager exists; for the exit of the app, where the timer of the I/O thread would not run any more.
 

Detailed Description

LRU cache for SAF (Storage Access Framework) file metadata with background preloading.

Caches duration, MIME type, and encoded IDs for fast browsing.

Persistence: the cache lives in its own preferences file ({@value SafCacheMigration.STORE_NAME}), not in the default preferences (every write rewrites the whole XML file, and the cache was large). Entries of the old place are moved once (SafCacheMigration). Reads are served from memory. Changes are collected in memory (SafCacheWriteBuffer) and committed in one go by the cache's own I/O thread when SafCacheFlushPolicy says so (every {@value FLUSH_MAX_CHANGES} changes or {@value FLUSH_MAX_AGE_MILLIS} ms) and at the end of a preload, with commit() - never on the main thread. The stored state is loaded on that thread too; the constructor does no I/O. A caller on the main thread that comes before the load ended gets metadata computed without the stored state and nothing is persisted for it; other threads wait for the load.

The short id maps are not stored on their own: they are rebuilt from the stored metadata entries (the short id is part of the serialized SAFMetadata), the counter is stored under {@value SafCacheMigration.ID_COUNTER_KEY}. A short id created in the last {@value FLUSH_MAX_AGE_MILLIS} ms before the process is killed is lost; flushIfCreated(long) writes the pending changes when the app exits.

Member Function Documentation

◆ flushIfCreated()

static void de.yaacc.util.SAFCacheManager.flushIfCreated ( long waitMillis)
static

Writes the changes that wait in memory, if the manager exists; for the exit of the app, where the timer of the I/O thread would not run any more.

Blocks the caller for at most waitMillis.

◆ getDuration()

String de.yaacc.util.SAFCacheManager.getDuration ( Uri uri)

Get duration from cache or extract if not cached.

Deprecated
Use getMetadata() instead

◆ getMetadata()

SAFMetadata de.yaacc.util.SAFCacheManager.getMetadata ( Uri uri,
String name,
String providerMimeType,
long fileSize )

Get complete metadata for a SAF file (duration, MIME type, encoded ID).

Returns cached data if available, otherwise builds it from the given values - without a further query to the document provider. The values come from the directory listing.

Parameters
urithe file's document uri (the cache key)
nameits display name, may be null
providerMimeTypethe mime type the provider reports for it, may be null
fileSizeits size in bytes as the provider reports it

◆ getMetadataBulk()

SAFMetadata[] de.yaacc.util.SAFCacheManager.getMetadataBulk ( List< SafMetadataRequest > requests)

The metadata of many files at once (a Browse of a folder): the same results as getMetadata called for each one, in the same order, for the cost of one load check, a lock acquisition per {@value BULK_CHUNK} files instead of one per file and ONE write of what was new (a cold cache of N files is N new entries; the single calls schedule a write after every {@value FLUSH_MAX_CHANGES} of them, and every write rewrites the whole preferences file).

Returns
one element per request, null where getMetadata would answer null (no uri)

◆ getOrCreateShortId()

String de.yaacc.util.SAFCacheManager.getOrCreateShortId ( String uri)

Get or create a short ID for a URI.

On the main thread before the stored state is loaded the id is a transient one that only this process knows ("t1", ...), see SafShortIds.

◆ getUriForShortId()

String de.yaacc.util.SAFCacheManager.getUriForShortId ( String shortId)

Get URI for a short ID.

Before the stored state is loaded, threads other than the main thread wait for it (a stored id would not be known yet), the main thread gets null.

◆ trimCache()

void de.yaacc.util.SAFCacheManager.trimCache ( )

Writes what waits in memory (on the I/O thread, so this returns at once).

The LRU of the memory is not mirrored in the stored state: an entry the LRU dropped stays stored, so the short id of a file beyond the {@value MAX_CACHE_SIZE}th still resolves after a restart (the former trim never removed anything in practice).


The documentation for this class was generated from the following file: