X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;ds=sidebyside;f=localdb.cc;h=2f5af6eb4e6f4dd156373ab7ab70af3af7563be0;hb=908cfc1af3e761d3243d31a68420fb8994840721;hp=c74e27dc5459f6fbfd98f8e9fae72f89a6667629;hpb=26f68e9df784020f16bbc295342123b0eca7de9b;p=cumulus.git diff --git a/localdb.cc b/localdb.cc index c74e27d..2f5af6e 100644 --- a/localdb.cc +++ b/localdb.cc @@ -32,11 +32,13 @@ #include #include +#include #include #include "localdb.h" #include "store.h" +using std::min; using std::string; /* Helper function to prepare a statement for execution in the current @@ -376,20 +378,61 @@ void LocalDb::UseObject(const ObjectReference& ref) if (!ref.is_normal()) return; - stmt = Prepare("insert or ignore into snapshot_refs " - "select segmentid, object, size from block_index " + int64_t old_size = 0; + stmt = Prepare("select size from snapshot_refs " "where segmentid = ? and object = ?"); sqlite3_bind_int64(stmt, 1, SegmentToId(ref.get_segment())); string obj = ref.get_sequence(); sqlite3_bind_text(stmt, 2, obj.c_str(), obj.size(), SQLITE_TRANSIENT); - rc = sqlite3_step(stmt); - if (rc != SQLITE_DONE) { - fprintf(stderr, "Could not execute INSERT statement!\n"); - ReportError(rc); + if (rc == SQLITE_ROW) { + old_size = sqlite3_column_int64(stmt, 0); } + sqlite3_finalize(stmt); + int64_t block_size = 0; + stmt = Prepare("select size from block_index " + "where segmentid = ? and object = ?"); + sqlite3_bind_int64(stmt, 1, SegmentToId(ref.get_segment())); + obj = ref.get_sequence(); + sqlite3_bind_text(stmt, 2, obj.c_str(), obj.size(), SQLITE_TRANSIENT); + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { + block_size = sqlite3_column_int64(stmt, 0); + } else { + string refstr = ref.to_string(); + fprintf(stderr, "No block found in block_index for %s\n", + refstr.c_str()); + sqlite3_finalize(stmt); + return; + } sqlite3_finalize(stmt); + + int64_t new_size = old_size; + if (ref.has_range()) { + new_size += ref.get_range_length(); + new_size = min(new_size, block_size); + } else { + new_size = block_size; + } + + if (new_size != old_size) { + stmt = Prepare("insert or replace " + "into snapshot_refs(segmentid, object, size) " + "values (?, ?, ?)"); + sqlite3_bind_int64(stmt, 1, SegmentToId(ref.get_segment())); + obj = ref.get_sequence(); + sqlite3_bind_text(stmt, 2, obj.c_str(), obj.size(), SQLITE_TRANSIENT); + sqlite3_bind_int64(stmt, 3, new_size); + + rc = sqlite3_step(stmt); + if (rc != SQLITE_DONE) { + fprintf(stderr, "Could not execute INSERT statement!\n"); + ReportError(rc); + } + + sqlite3_finalize(stmt); + } } void LocalDb::UseSegment(const std::string &segment, double utilization) @@ -492,7 +535,7 @@ bool LocalDb::LoadChunkSignatures(ObjectReference ref, sqlite3_stmt *stmt; int found = false; - stmt = Prepare("select algorithm, signatures from subblock_signatures " + stmt = Prepare("select signatures, algorithm from subblock_signatures " "where blockid = (select blockid from block_index " " where segmentid = ? and object = ?)"); sqlite3_bind_int64(stmt, 1, SegmentToId(ref.get_segment()));