| 701 | |
| 702 | |
| 703 | bool ReplicaProcess::persist(const Action& action) |
| 704 | { |
| 705 | Try<Nothing> persisted = storage->persist(action); |
| 706 | |
| 707 | if (persisted.isError()) { |
| 708 | LOG(ERROR) << "Error writing to log: " << persisted.error(); |
| 709 | return false; |
| 710 | } |
| 711 | |
| 712 | VLOG(1) << "Persisted action " << action.type() |
| 713 | << " at position " << action.position(); |
| 714 | |
| 715 | // No longer a hole here (if there even was one). |
| 716 | holes -= action.position(); |
| 717 | |
| 718 | // Update unlearned positions and deal with truncation actions. |
| 719 | if (action.has_learned() && action.learned()) { |
| 720 | unlearned -= action.position(); |
| 721 | |
| 722 | if (action.has_type() && action.type() == Action::TRUNCATE) { |
| 723 | // No longer consider truncated positions as holes (so that a |
| 724 | // coordinator doesn't try and fill them). |
| 725 | holes -= (Bound<uint64_t>::open(0), |
| 726 | Bound<uint64_t>::open(action.truncate().to())); |
| 727 | |
| 728 | // No longer consider truncated positions as unlearned (so that |
| 729 | // a coordinator doesn't try and fill them). |
| 730 | unlearned -= (Bound<uint64_t>::open(0), |
| 731 | Bound<uint64_t>::open(action.truncate().to())); |
| 732 | |
| 733 | // And update the beginning position. |
| 734 | begin = std::max(begin, action.truncate().to()); |
| 735 | } else if (action.has_type() && action.type() == Action::NOP && |
| 736 | action.nop().has_tombstone() && action.nop().tombstone()) { |
| 737 | // No longer consider truncated positions as holes (so that a |
| 738 | // coordinator doesn't try and fill them). |
| 739 | holes -= (Bound<uint64_t>::open(0), |
| 740 | Bound<uint64_t>::open(action.position())); |
| 741 | |
| 742 | // No longer consider truncated positions as unlearned (so that |
| 743 | // a coordinator doesn't try and fill them). |
| 744 | unlearned -= (Bound<uint64_t>::open(0), |
| 745 | Bound<uint64_t>::open(action.position())); |
| 746 | |
| 747 | // And update the beginning position. There must exist at least |
| 748 | // 1 position (TRUNCATE) in the log after the tombstone. |
| 749 | begin = std::max(begin, action.position() + 1); |
| 750 | } |
| 751 | } else { |
| 752 | // We just introduced an unlearned position. |
| 753 | unlearned += action.position(); |
| 754 | } |
| 755 | |
| 756 | // Update holes if we just wrote many positions past the last end. |
| 757 | if (action.position() > end) { |
| 758 | holes += (Bound<uint64_t>::open(end), |
| 759 | Bound<uint64_t>::open(action.position())); |
| 760 | } |