@@ -77,6 +77,7 @@ defmodule UUIDv7.Clock do
77
77
state = % {
78
78
table: :ets . new ( __MODULE__ , ets_opts ) ,
79
79
interval_ms: interval_ms ,
80
+ timestamp_ref: :persistent_term . get ( __MODULE__ ) ,
80
81
cleanup_tick_cutoff: cleanup_tick_cutoff
81
82
}
82
83
@@ -87,7 +88,7 @@ defmodule UUIDv7.Clock do
87
88
88
89
@ impl GenServer
89
90
def handle_info ( :cleanup , state ) do
90
- cleanup ( state . cleanup_tick_cutoff )
91
+ cleanup ( state . timestamp_ref , state . cleanup_tick_cutoff )
91
92
schedule_cleanup ( state . interval_ms )
92
93
{ :noreply , state }
93
94
end
@@ -106,12 +107,16 @@ defmodule UUIDv7.Clock do
106
107
:ets . update_counter ( __MODULE__ , ts , 1 , { ts , seed } )
107
108
end
108
109
109
- # NOTE: The thing that bothers me the most about this implementation is the
110
- # cleanup and how it may (possibly?) effect performance. I need to do some
111
- # benchmarks to test if this effects `:ets.update_counter/4` at all.
112
- defp cleanup ( cutoff ) do
113
- timestamp = System . system_time ( :millisecond ) - cutoff
114
- :ets . select_delete ( __MODULE__ , [ { { :"$1" , :_ } , [ { :< , :"$1" , timestamp } ] , [ true ] } ] )
110
+ # NOTE: I still want to benchmark different cutoffs and cleanup intervals.
111
+ defp cleanup ( timestamp_ref , cutoff ) do
112
+ timestamp = System . system_time ( :millisecond )
113
+ previous_ts = :atomics . get ( timestamp_ref , 1 )
114
+
115
+ # If the last timestamp was over 10 seconds ago, then we don't bother to run the cleanup.
116
+ if timestamp - previous_ts < 10_000 do
117
+ # Cleanup all entries that are older than the cutoff.
118
+ :ets . select_delete ( __MODULE__ , [ { { :"$1" , :_ } , [ { :< , :"$1" , timestamp - cutoff } ] , [ true ] } ] )
119
+ end
115
120
end
116
121
117
122
defp schedule_cleanup ( interval_ms ) do
0 commit comments