int rc;
/* Summarize the snapshot_refs table into segments_used. */
- sqlite3_stmt *stmt = Prepare("insert into segments_used "
- "select ? as snapshotid, segmentid, "
- "cast(used as real) / size as utilization "
- "from "
- "(select segmentid, sum(size) as used "
- "from snapshot_refs group by segmentid) "
- "join segments using (segmentid)");
+ sqlite3_stmt *stmt = Prepare(
+ "insert or replace into segments_used "
+ "select ? as snapshotid, segmentid, max(utilization) from ("
+ " select segmentid, cast(used as real) / size as utilization "
+ " from "
+ " (select segmentid, sum(size) as used from snapshot_refs "
+ " group by segmentid) "
+ " join segments using (segmentid) "
+ " union "
+ " select segmentid, utilization from segments_used "
+ " where snapshotid = ? "
+ ") group by segmentid"
+ );
sqlite3_bind_int64(stmt, 1, snapshotid);
+ sqlite3_bind_int64(stmt, 2, snapshotid);
rc = sqlite3_step(stmt);
if (rc != SQLITE_OK && rc != SQLITE_DONE) {
ReportError(rc);
}
sqlite3_finalize(stmt);
+
+ if (age != 0.0) {
+ stmt = Prepare("update segments set mtime = max(mtime, ?) "
+ "where segmentid = ?");
+ sqlite3_bind_double(stmt, 1, age);
+ sqlite3_bind_int64(stmt, 2, SegmentToId(ref.get_segment()));
+ rc = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+ }
}
ObjectReference LocalDb::FindObject(const string &checksum, int64_t size)
sqlite3_finalize(stmt);
}
+void LocalDb::UseSegment(const std::string &segment, double utilization)
+{
+ int rc;
+ sqlite3_stmt *stmt;
+
+ stmt = Prepare("insert or replace "
+ "into segments_used(snapshotid, segmentid, utilization) "
+ "values (?, ?, ?)");
+ sqlite3_bind_int64(stmt, 1, snapshotid);
+ sqlite3_bind_int64(stmt, 2, SegmentToId(segment));
+ sqlite3_bind_double(stmt, 3, utilization);
+
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_DONE) {
+ fprintf(stderr, "Could not insert segment use record!\n");
+ ReportError(rc);
+ }
+
+ sqlite3_finalize(stmt);
+}
+
void LocalDb::SetSegmentChecksum(const std::string &segment,
const std::string &path,
const std::string &checksum,
int rc;
sqlite3_stmt *stmt;
- stmt = Prepare("update segments set path = ?, checksum = ?, size = ? "
+ stmt = Prepare("update segments set path = ?, checksum = ?, size = ?, "
+ "mtime = coalesce(mtime, julianday('now')) "
"where segmentid = ?");
sqlite3_bind_text(stmt, 1, path.c_str(), path.size(),
SQLITE_TRANSIENT);
#include <map>
#include "metadata.h"
+#include "localdb.h"
#include "ref.h"
#include "store.h"
#include "util.h"
bool flag_full_metadata = false;
/* TODO: Move to header file */
+extern LocalDb *db;
void add_segment(const string& segment);
/* Like strcmp, but sorts in the order that files will be visited in the
i != items.end(); ++i) {
// If indirectly referencing any other metadata logs, be sure those
// segments are properly referenced.
- if (i->reused)
+ if (i->reused) {
add_segment(i->ref.get_segment());
+ db->UseSegment(i->ref.get_segment(), 1.0);
+ }
// Write out an indirect reference to any previous objects which could
// be reused
ObjectReference ref = meta->get_ref();
metadata_root << "@" << ref.to_string() << "\n";
add_segment(ref.get_segment());
+ db->UseSegment(ref.get_segment(), 1.0);
delete meta;
root->write(store);
root->checksum();
add_segment(root->get_ref().get_segment());
+ db->UseSegment(root->get_ref().get_segment(), 1.0);
ObjectReference ref = root->get_ref();
delete root;