cache.v

2.0 KB · raw

1//! The file cache: a machine-local shortcut so `status` and `save` can skip2//! files whose size, mtime and ctime are unchanged. It caches the working3//! tree, never history, and is safe to drop at any time.45module storage67pub struct CacheRow {8pub:9	path     string10	size     i6411	mtime_ns i6412	ctime_ns i6413	hash     string14}1516pub fn (s &Store) load_cache() !map[string]CacheRow {17	mut rows := map[string]CacheRow{}18	mut stmt := s.db.prepare('SELECT path, size, mtime_ns, ctime_ns, hash FROM file_cache')!19	defer {20		stmt.finalize()21	}22	for stmt.step()! {23		row := CacheRow{24			path:     stmt.text(0)25			size:     stmt.int(1)26			mtime_ns: stmt.int(2)27			ctime_ns: stmt.int(3)28			hash:     stmt.text(4)29		}30		rows[row.path] = row31	}32	return rows33}3435// save_cache_rows writes a walk's rows in one transaction, without waiting for36// another writer: the cache only saves time, so while another command holds37// the lock the rows are simply not written.38pub fn (s &Store) save_cache_rows(rows []CacheRow) ! {39	if rows.len == 0 {40		return41	}42	s.db.exec('PRAGMA busy_timeout = 0')!43	defer {44		s.db.exec('PRAGMA busy_timeout = ${busy_timeout_ms}') or {}45	}46	s.db.exec('BEGIN IMMEDIATE')!47	for row in rows {48		s.save_cache(row) or {49			s.rollback()50			return err51		}52	}53	s.end()!54}5556fn (s &Store) save_cache(row CacheRow) ! {57	mut stmt := s.db.prepare('INSERT INTO file_cache (path, size, mtime_ns, ctime_ns, hash)58		VALUES (?, ?, ?, ?, ?)59		ON CONFLICT(path) DO UPDATE SET size = excluded.size, mtime_ns = excluded.mtime_ns,60			ctime_ns = excluded.ctime_ns, hash = excluded.hash')!61	defer {62		stmt.finalize()63	}64	stmt.bind_text(1, row.path)!65	stmt.bind_int(2, row.size)!66	stmt.bind_int(3, row.mtime_ns)!67	stmt.bind_int(4, row.ctime_ns)!68	stmt.bind_text(5, row.hash)!69	stmt.step()!70}7172pub fn (s &Store) drop_cache() ! {73	s.db.exec('DELETE FROM file_cache')!74}7576pub fn (s &Store) cache_count() !i64 {77	mut stmt := s.db.prepare('SELECT COUNT(*) FROM file_cache')!78	defer {79		stmt.finalize()80	}81	if !stmt.step()! {82		return 083	}84	return stmt.int(0)85}