11import argparse
22from collections import OrderedDict
3- from datetime import datetime
3+ from datetime import datetime , timedelta
44import logging
55from operator import attrgetter
66import os
@@ -100,11 +100,17 @@ def quarterly_3monthly_period_func(a):
100100)
101101
102102
103+ # Datetime cannot represent times than datetime.min, so a day is added to allow for time zone offset.
104+ DATETIME_MIN_WITH_ZONE = (datetime .min + timedelta (days = 1 )).astimezone ()
105+
106+
103107def prune_split (archives , rule , n_or_interval , base_timestamp , kept_because = None ):
104108 if isinstance (n_or_interval , int ):
105- n , interval = n_or_interval , None
109+ # If no interval, assume given interval is "infinite"
110+ n , earliest_timestamp = n_or_interval , DATETIME_MIN_WITH_ZONE
106111 else :
107- n , interval = None , n_or_interval
112+ # If no n, assume given n is "infinite"
113+ n , earliest_timestamp = - 1 , base_timestamp - n_or_interval
108114
109115 last = None
110116 keep = []
@@ -116,17 +122,17 @@ def prune_split(archives, rule, n_or_interval, base_timestamp, kept_because=None
116122
117123 a = None
118124 for a in sorted (archives , key = attrgetter ("ts" ), reverse = True ):
125+ if a .ts < earliest_timestamp or len (keep ) == n :
126+ break
119127 period = period_func (a )
120128 if period != last :
121129 last = period
122- if a .id not in kept_because and ( interval is None or a . ts >= base_timestamp - interval ) :
130+ if a .id not in kept_because :
123131 keep .append (a )
124132 kept_because [a .id ] = (rule , len (keep ))
125- if len (keep ) == n :
126- break
127133
128134 # Keep oldest archive if we didn't reach the target retention count
129- if a is not None and ( n is not None and len (keep ) < n ) and a .id not in kept_because :
135+ if a is not None and len (keep ) < n and a .id not in kept_because :
130136 keep .append (a )
131137 kept_because [a .id ] = (rule + "[oldest]" , len (keep ))
132138
0 commit comments