Unified · Split
| @@ -40,7 +40,6 @@ impl std::borrow::BorrowMut<RefEdit> for Edit { · 39 unmodified lines | |||
| 40 | pub struct Transaction<'s> { | 40 | pub struct Transaction<'s> { |
| 41 | store: &'s file::Store, | 41 | store: &'s file::Store, |
| 42 | packed_transaction: Option<packed::Transaction>, | 42 | packed_transaction: Option<packed::Transaction>, |
| 43 | packed: Option<packed::Buffer>, | ||
| 44 | updates: Option<Vec<Edit>>, | 43 | updates: Option<Vec<Edit>>, |
| 45 | } | 44 | } |
| 46 | 45 | ||
| @@ -236,8 +235,9 @@ impl<'s> Transaction<'s> { · 189 unmodified lines | |||
| 236 | ) | 235 | ) |
| 237 | .map_err(Error::PreprocessingFailed)?; | 236 | .map_err(Error::PreprocessingFailed)?; |
| 238 | 237 | ||
| 239 | if let Some(packed) = self.store.packed()? { | 238 | if self.store.packed_refs_path().is_file() { |
| 240 | let mut edits_for_packed_transaction = Vec::<RefEdit>::new(); | 239 | let mut edits_for_packed_transaction = Vec::<RefEdit>::new(); |
| 240 | let mut needs_packed_refs_lookups = false; | ||
| 241 | for edit in updates.iter() { | 241 | for edit in updates.iter() { |
| 242 | let log_mode = match edit.update.change { | 242 | let log_mode = match edit.update.change { |
| 243 | Change::Update { | 243 | Change::Update { |
| @@ -257,19 +257,23 @@ impl<'s> Transaction<'s> { · 13 unmodified lines | |||
| 257 | Change::Delete { .. } => { | 257 | Change::Delete { .. } => { |
| 258 | edits_for_packed_transaction.push(edit.update.clone()); | 258 | edits_for_packed_transaction.push(edit.update.clone()); |
| 259 | } | 259 | } |
| 260 | _ => {} | 260 | _ => { |
| 261 | needs_packed_refs_lookups = true; | ||
| 262 | } | ||
| 261 | } | 263 | } |
| 262 | } | 264 | } |
| 263 | 265 | ||
| 264 | if !edits_for_packed_transaction.is_empty() { | 266 | // We create a transaction even for empty packed edits to assure nobody else can change |
| 265 | self.packed_transaction = Some( | 267 | // it while we perform checks against previous values. |
| 266 | packed | 268 | if !edits_for_packed_transaction.is_empty() || needs_packed_refs_lookups { |
| 267 | .into_transaction(lock_fail_mode) | 269 | if let Some(packed) = self.store.packed()? { |
| 268 | .map_err(Error::PackedTransactionAcquire)? | 270 | self.packed_transaction = Some( |
| 269 | .prepare(edits_for_packed_transaction)?, | 271 | packed |
| 270 | ); | 272 | .into_transaction(lock_fail_mode) |
| 271 | } else { | 273 | .map_err(Error::PackedTransactionAcquire)? |
| 272 | self.packed = Some(packed); | 274 | .prepare(edits_for_packed_transaction)?, |
| 275 | ); | ||
| 276 | } | ||
| 273 | } | 277 | } |
| 274 | } | 278 | } |
| 275 | 279 | ||
| @@ -278,10 +282,7 @@ impl<'s> Transaction<'s> { · 2 unmodified lines | |||
| 278 | if let Err(err) = Self::lock_ref_and_apply_change( | 282 | if let Err(err) = Self::lock_ref_and_apply_change( |
| 279 | self.store, | 283 | self.store, |
| 280 | lock_fail_mode, | 284 | lock_fail_mode, |
| 281 | self.packed_transaction | 285 | self.packed_transaction.as_ref().map(|t| t.buffer()), |
| 282 | .as_ref() | ||
| 283 | .map(|t| t.buffer()) | ||
| 284 | .or_else(|| self.packed.as_ref()), | ||
| 285 | change, | 286 | change, |
| 286 | ) { | 287 | ) { |
| 287 | let err = match err { | 288 | let err = match err { |
| @@ -440,10 +441,10 @@ impl<'s> Transaction<'s> { · 152 unmodified lines | |||
| 440 | } | 441 | } |
| 441 | } | 442 | } |
| 442 | } | 443 | } |
| 443 | let packed = match self.packed_transaction { | 444 | let packed = self |
| 444 | Some(transaction) => Some(transaction.commit().map_err(Error::PackedTransactionCommit)?.1), | 445 | .packed_transaction |
| 445 | None => self.packed, | 446 | .map(|t| t.commit().map(|r| r.1).map_err(Error::PackedTransactionCommit)) |
| 446 | }; | 447 | .transpose()?; |
| 447 | Ok((updates.into_iter().map(|edit| edit.update).collect(), packed)) | 448 | Ok((updates.into_iter().map(|edit| edit.update).collect(), packed)) |
| 448 | } | 449 | } |
| 449 | None => panic!("BUG: must call prepare before commit"), | 450 | None => panic!("BUG: must call prepare before commit"), |
| @@ -461,7 +462,6 @@ impl file::Store { · 11 unmodified lines | |||
| 461 | Transaction { | 462 | Transaction { |
| 462 | store: self, | 463 | store: self, |
| 463 | packed_transaction: None, | 464 | packed_transaction: None, |
| 464 | packed: None, | ||
| 465 | updates: None, | 465 | updates: None, |
| 466 | } | 466 | } |
| 467 | } | 467 | } |