Module: Familia::Features::Quantization::ClassMethods

Included in:
Familia::Features::Quantization
Defined in:
lib/familia/features/quantization.rb

Instance Method Summary collapse

Instance Method Details

#in_bucket?(timestamp, quantum, bucket_time) ⇒ Boolean

Check if a timestamp falls within a quantized bucket

Examples:

Check if event falls in hourly bucket

event_time = Time.parse('2023-01-01 14:37:42')
bucket_time = Time.parse('2023-01-01 14:00:00')
User.in_bucket?(event_time, 1.hour, bucket_time)  # => true

Parameters:

  • timestamp (Time, Integer)

    The timestamp to check

  • quantum (Numeric)

    The quantum interval

  • bucket_time (Time, Integer)

    The bucket reference time

Returns:

  • (Boolean)

    true if timestamp falls in the bucket



342
343
344
345
346
347
348
349
# File 'lib/familia/features/quantization.rb', line 342

def in_bucket?(timestamp, quantum, bucket_time)
  timestamp = timestamp.to_i if timestamp.respond_to?(:to_i)
  bucket_time = bucket_time.to_i if bucket_time.respond_to?(:to_i)
  bucket_start = qstamp(quantum, time: Time.at(bucket_time))
  bucket_end = bucket_start + quantum - 1

  timestamp >= bucket_start && timestamp <= bucket_end
end

#qstamp(quantum = nil, pattern: nil, time: nil) ⇒ Integer, String

Generates a quantized timestamp based on the given parameters

This method rounds the current time to the nearest quantum and optionally formats it according to the given pattern. It’s useful for creating time-based buckets or keys with reduced granularity.

Examples:

Generate hourly bucket timestamp

User.qstamp(1.hour)  # => 1672531200 (rounded to hour boundary)

Generate formatted timestamp

User.qstamp(1.hour, pattern: '%Y%m%d%H')  # => "2023010114"

Using array syntax

User.qstamp([1.hour, '%Y%m%d%H'])  # => "2023010114"

With custom time reference

custom_time = Time.parse('2023-06-15 14:30:45')
User.qstamp(1.hour, time: custom_time)  # => 1686834000

Parameters:

  • quantum (Numeric, Array, nil) (defaults to: nil)

    The time quantum in seconds or an array of [quantum, pattern]

  • pattern (String, nil) (defaults to: nil)

    The strftime pattern to format the timestamp

  • time (Time, nil) (defaults to: nil)

    The reference time (default: current time)

Returns:

  • (Integer, String)

    A unix timestamp or formatted timestamp string

Raises:

  • (ArgumentError)

    If quantum is not positive



280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/familia/features/quantization.rb', line 280

def qstamp(quantum = nil, pattern: nil, time: nil)
  # Handle array input format: [quantum, pattern]
  if quantum.is_a?(Array)
    quantum, pattern = quantum
  end

  # Use default quantum if none specified
  # Priority: provided quantum > class default_expiration > 10.minutes fallback
  quantum ||= default_expiration || 10.minutes

  # Validate quantum value
  unless quantum.is_a?(Numeric) && quantum.positive?
    raise ArgumentError, "Quantum must be positive (#{quantum.inspect} given)"
  end

  # Delegate to Familia.qstamp for the actual calculation
  Familia.qstamp(quantum, pattern: pattern, time: time)
end

#qstamp_range(start_time, end_time, quantum, pattern: nil) ⇒ Array

Generate multiple quantized timestamps for a time range

Examples:

Generate hourly buckets for a day

start_time = Time.parse('2023-01-01 00:00:00')
end_time = Time.parse('2023-01-01 23:59:59')
User.qstamp_range(start_time, end_time, 1.hour)
# => [1672531200, 1672534800, 1672538400, ...] (24 hourly buckets)

Parameters:

  • start_time (Time)

    Start of the time range

  • end_time (Time)

    End of the time range

  • quantum (Numeric)

    Time quantum in seconds

  • pattern (String, nil) (defaults to: nil)

    Optional strftime pattern

Returns:

  • (Array)

    Array of quantized timestamps



313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/familia/features/quantization.rb', line 313

def qstamp_range(start_time, end_time, quantum, pattern: nil)
  timestamps = []
  current = qstamp(quantum, time: start_time)
  end_bucket = qstamp(quantum, time: end_time)

  while current <= end_bucket
    if pattern
      timestamps << Time.at(current).strftime(pattern)
    else
      timestamps << current
    end
    current += quantum
  end

  timestamps
end