| 154 | // know the position (nor can we determine it) before we've done the |
| 155 | // actual appending of the data. |
| 156 | struct Snapshot |
| 157 | { |
| 158 | Snapshot(const Log::Position& position, |
| 159 | const Entry& entry, |
| 160 | size_t diffs = 0) |
| 161 | : position(position), |
| 162 | entry(entry), |
| 163 | diffs(diffs) {} |
| 164 | |
| 165 | // Returns a snapshot after having applied the specified diff. |
| 166 | Try<Snapshot> patch(const Operation::Diff& diff) const |
| 167 | { |
| 168 | if (diff.entry().name() != entry.name()) { |
| 169 | return Error("Attempted to patch the wrong snapshot"); |
| 170 | } |
| 171 | |
| 172 | Try<string> patch = svn::patch( |
| 173 | entry.value(), |
| 174 | svn::Diff(diff.entry().value())); |
| 175 | |
| 176 | if (patch.isError()) { |
| 177 | return Error(patch.error()); |
| 178 | } |
| 179 | |
| 180 | Entry entry(diff.entry()); |
| 181 | entry.set_value(patch.get()); |
| 182 | |
| 183 | return Snapshot(position, entry, diffs + 1); |
| 184 | } |
| 185 | |
| 186 | // Position in the log where this snapshot is located. NOTE: if |
| 187 | // 'diffs' is greater than 0 this still represents the location of |
| 188 | // the snapshot, not the last DIFF record in the log. |
| 189 | const Log::Position position; |
| 190 | |
| 191 | // TODO(benh): Rather than storing the entire Entry we |
| 192 | // should just store the position, name, and UUID and cache the |
| 193 | // data so we don't use too much memory. |
| 194 | const Entry entry; |
| 195 | |
| 196 | // This value represents the number of Operation::DIFFs in the |
| 197 | // underlying log that make up this "snapshot". If this snapshot |
| 198 | // is actually represented in the log this value is 0. |
| 199 | const size_t diffs; |
| 200 | }; |
| 201 | |
| 202 | // All known snapshots indexed by name. Note that 'hashmap::get' |
| 203 | // must be used instead of 'operator[]' since Snapshot doesn't have |