Fix a bug in computing the size of a segment that led to utilization > 1.0.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Fri, 14 Dec 2007 19:51:41 +0000 (11:51 -0800)
committerMichael Vrable <mvrable@turin.ucsd.edu>
Fri, 14 Dec 2007 19:51:41 +0000 (11:51 -0800)
The old code for computing the size of a segment (to be stored in the
segments table) could leave off the last object to be written to the
segment.  This could cause the computed segment utilization to be greater
than 1.0, which should be impossible.  Fix the size calculation so that it
should always include all data written to the segment.  As a bonus, this
also correctly computes the size of metadata-log segments, even though the
metadata objects don't appear in the block_index table (which was
previously used for computing the segment size, but is no longer).

localdb.cc
localdb.h
store.cc
store.h

index 17337f0..50c15e9 100644 (file)
@@ -359,20 +359,19 @@ void LocalDb::UseObject(const ObjectReference& ref)
 
 void LocalDb::SetSegmentChecksum(const std::string &segment,
                                  const std::string &path,
-                                 const std::string &checksum)
+                                 const std::string &checksum,
+                                 int size)
 {
     int rc;
     sqlite3_stmt *stmt;
 
-    stmt = Prepare("update segments set path = ?, checksum = ?, "
-                   "size = (select sum(size) from block_index "
-                   "        where segmentid = ?) "
+    stmt = Prepare("update segments set path = ?, checksum = ?, size = ? "
                    "where segmentid = ?");
     sqlite3_bind_text(stmt, 1, path.c_str(), path.size(),
                       SQLITE_TRANSIENT);
     sqlite3_bind_text(stmt, 2, checksum.c_str(), checksum.size(),
                       SQLITE_TRANSIENT);
-    sqlite3_bind_int64(stmt, 3, SegmentToId(segment));
+    sqlite3_bind_int64(stmt, 3, size);
     sqlite3_bind_int64(stmt, 4, SegmentToId(segment));
 
     rc = sqlite3_step(stmt);
index 69fb330..a89923f 100644 (file)
--- a/localdb.h
+++ b/localdb.h
@@ -33,7 +33,7 @@ public:
     void UseObject(const ObjectReference& ref);
 
     void SetSegmentChecksum(const std::string &segment, const std::string &path,
-                            const std::string &checksum);
+                            const std::string &checksum, int size);
     bool GetSegmentChecksum(const std::string &segment,
                             std::string *seg_path, std::string *seg_checksum);
 private:
index a156a57..1ea2439 100644 (file)
--- a/store.cc
+++ b/store.cc
@@ -232,6 +232,7 @@ ObjectReference TarSegmentStore::write_object(const char *data, size_t len,
         segment->fullname = path + "/" + segment->basename;
         segment->file = new Tarfile(segment->fullname, segment->name);
         segment->count = 0;
+        segment->size = 0;
 
         segments[group] = segment;
     } else {
@@ -244,6 +245,7 @@ ObjectReference TarSegmentStore::write_object(const char *data, size_t len,
 
     segment->file->write_object(id, data, len);
     segment->count++;
+    segment->size += len;
 
     group_sizes[group] += len;
 
@@ -282,7 +284,8 @@ void TarSegmentStore::close_segment(const string &group)
         SHA1Checksum segment_checksum;
         if (segment_checksum.process_file(segment->fullname.c_str())) {
             string checksum = segment_checksum.checksum_str();
-            db->SetSegmentChecksum(segment->name, segment->basename, checksum);
+            db->SetSegmentChecksum(segment->name, segment->basename, checksum,
+                                   segment->size);
         }
     }
 
diff --git a/store.h b/store.h
index 956a1b5..d447031 100644 (file)
--- a/store.h
+++ b/store.h
@@ -115,6 +115,7 @@ private:
         Tarfile *file;
         std::string name;           // UUID
         int count;                  // Objects written to this segment
+        int size;                   // Combined size of objects written
         std::string basename;       // Name of segment without directory
         std::string fullname;       // Full path to stored segment
     };