Class: Snapsync::TimelineSyncPolicy
- Inherits:
-
DefaultSyncPolicy
- Object
- DefaultSyncPolicy
- Snapsync::TimelineSyncPolicy
- Defined in:
- lib/snapsync/timeline_sync_policy.rb
Instance Attribute Summary collapse
-
#periods ⇒ Object
readonly
Returns the value of attribute periods.
-
#reference ⇒ Object
readonly
Returns the value of attribute reference.
-
#timeline ⇒ Object
readonly
Returns the value of attribute timeline.
Class Method Summary collapse
Instance Method Summary collapse
-
#add(period, count) ⇒ Object
Add an element to the timeline.
-
#compute_required_snapshots(target_snapshots) ⇒ Object
Given a list of snapshots, computes those that should be kept to honor the timeline constraints.
- #filter_snapshots(snapshots) ⇒ Object
-
#initialize(reference: Time.now) ⇒ TimelineSyncPolicy
constructor
A new instance of TimelineSyncPolicy.
- #parse_config(config) ⇒ Object
- #pretty_print(pp) ⇒ Object
- #to_config ⇒ Object
Constructor Details
#initialize(reference: Time.now) ⇒ TimelineSyncPolicy
Returns a new instance of TimelineSyncPolicy.
8 9 10 11 12 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 8 def initialize(reference: Time.now) @reference = reference @timeline = Array.new @periods = Array.new end |
Instance Attribute Details
#periods ⇒ Object (readonly)
Returns the value of attribute periods.
6 7 8 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 6 def periods @periods end |
#reference ⇒ Object (readonly)
Returns the value of attribute reference.
3 4 5 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 3 def reference @reference end |
#timeline ⇒ Object (readonly)
Returns the value of attribute timeline.
4 5 6 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 4 def timeline @timeline end |
Class Method Details
.from_config(config) ⇒ Object
14 15 16 17 18 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 14 def self.from_config(config) policy = new policy.parse_config(config) policy end |
Instance Method Details
#add(period, count) ⇒ Object
Add an element to the timeline
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 48 def add(period, count) beginning_of_day = reference.to_date beginning_of_week = beginning_of_day.prev_day(beginning_of_day.wday + 1) beginning_of_month = beginning_of_day.prev_day(beginning_of_day.mday - 1) beginning_of_year = beginning_of_day.prev_day(beginning_of_day.yday - 1) beginning_of_hour = beginning_of_day.to_time + (reference.hour * 3600) timeline = self.timeline.dup if period == :year count.times do timeline << beginning_of_year.to_time beginning_of_year = beginning_of_year.prev_year end elsif period == :month count.times do timeline << beginning_of_month.to_time beginning_of_month = beginning_of_month.prev_month end elsif period == :week count.times do timeline << beginning_of_week.to_time beginning_of_week = beginning_of_week.prev_day(7) end elsif period == :day count.times do timeline << beginning_of_day.to_time beginning_of_day = beginning_of_day.prev_day end elsif period == :hour count.times do |i| timeline << beginning_of_hour beginning_of_hour = beginning_of_hour - 3600 end else raise ArgumentError, "unknown period name #{period}" end periods << [period, count] @timeline = timeline.sort.uniq end |
#compute_required_snapshots(target_snapshots) ⇒ Object
Given a list of snapshots, computes those that should be kept to honor the timeline constraints
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 91 def compute_required_snapshots(target_snapshots) keep_flags = Hash.new { |h,k| h[k] = [false, []] } target_snapshots = target_snapshots.sort_by(&:num) # Mark all important snapshots as kept target_snapshots.each do |s| if s.user_data['important'] == 'yes' keep_flags[s.num][0] = true keep_flags[s.num][1] << "marked as important" end end # For each timepoint in the timeline, find the newest snapshot that # is not before the timepoint merged_timelines = (target_snapshots.to_a + timeline).sort_by do |s| s.to_time end matching_snapshots = [target_snapshots.first] merged_timelines.each do |obj| if obj.kind_of?(Snapshot) matching_snapshots[-1] = obj else s = matching_snapshots.last matching_snapshots[-1] = [s, obj] matching_snapshots << s end end matching_snapshots.pop matching_snapshots.each do |(s, timepoint)| keep_flags[s.num][0] = true keep_flags[s.num][1] << "timeline(#{timepoint})" end # Finally, guard against race conditions. Always keep all snapshots # between the last-to-keep and the last target_snapshots.reverse.each do |s| break if keep_flags[s.num][0] keep_flags[s.num][0] = true keep_flags[s.num][1] << "last snapshot" end keep_flags end |
#filter_snapshots(snapshots) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 135 def filter_snapshots(snapshots) Snapsync.debug do Snapsync.debug "Filtering snapshots according to timeline" Snapsync.debug "Snapshots: #{snapshots.map(&:num).sort.join(", ")}" timeline.each do |t| Snapsync.debug " #{t}" end break end default_policy = DefaultSyncPolicy.new snapshots = default_policy.filter_snapshots(snapshots) keep_flags = compute_required_snapshots(snapshots) snapshots.sort_by(&:num).find_all do |s| keep, reason = keep_flags.fetch(s.num, nil) if keep Snapsync.debug "Timeline: selected snapshot #{s.num} #{s.date.to_time}" reason.each do |r| Snapsync.debug " #{r}" end else Snapsync.debug "Timeline: not selected snapshot #{s.num} #{s.date.to_time}" end keep end end |
#parse_config(config) ⇒ Object
20 21 22 23 24 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 20 def parse_config(config) config.each_slice(2) do |period, count| add(period.to_sym, Integer(count)) end end |
#pretty_print(pp) ⇒ Object
30 31 32 33 34 35 36 37 38 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 30 def pretty_print(pp) pp.text "timeline policy" pp.nest(2) do pp.seplist(periods) do |pair| pp.breakable pp.text "#{pair[0]}: #{pair[1]}" end end end |
#to_config ⇒ Object
26 27 28 |
# File 'lib/snapsync/timeline_sync_policy.rb', line 26 def to_config periods.flatten end |