dinks/bucket_maker

View on GitHub
lib/bucket_maker/models/bucketable.rb

Summary

Maintainability
A
1 hr
Test Coverage
require 'bucket_maker/series_maker'

module BucketMaker
  module Models
    # Module which holds the base methods for Bucketable objects
    #
    module Bucketable

      # Used to test if this object has been grouped under a certain group
      #
      # @param series_name [String] Name of the Series
      # @param bucket_name [String] Name of the Bucket
      # @param group_name [String] Name of the Group
      # @param force [Boolean] To force the object into the group_name
      # @return [Boolean] if the given group_name is the same after randomization of groups
      #
      def in_bucket?(series_name, bucket_name, group_name, force=false)
        # Get the singleton Series Maker
        series_maker = BucketMaker::SeriesMaker.instance

        # Check if the parameters are valid
        if series_maker.bucketable?(self, series_name, bucket_name, group_name)
          # The Key is generated by the Series Maker
          series_key = series_maker.key_for_series(self, series_name, bucket_name)

          # Get the Group if created before from Persisted Storage
          saved_group = group_for_key(series_key)

          # If its a forced operation then set the Group to the parameter given
          if force
            set_group_for_key(series_key, group_name) if saved_group != group_name.to_s
            # Always return true for set
            true
          else
            # Lazy Load ??
            # If there is no Group then its lazy load/create time !
            unless saved_group
              # Get the random group for this instance
              saved_group = series_maker.bucketize(series_name, bucket_name)
              # Set the Group in Persisted Storage
              set_group_for_key(series_key, saved_group)
            end

            # return if its the same bucket as requested
            saved_group == group_name.to_s
          end
        else
          # return false if invalid parameters
          false
        end
      end

      # Used to test if this object has not been grouped under a certain group
      #
      # @param series_name [String] Name of the Series
      # @param bucket_name [String] Name of the Bucket
      # @param group_name [String] Name of the Group
      # @return [Boolean] if the given group_name is the not the same after randomization of groups
      #
      def not_in_bucket?(series_name, bucket_name, group_name)
        !in_bucket?(series_name, bucket_name, group_name)
      end

      # Force object into the group_name under bucket under series
      #
      # @param series_name [String] Name of the Series
      # @param bucket_name [String] Name of the Bucket
      # @param group_name [String] Name of the Group
      # @return [Boolean] Always true because forcing is ok by us
      #
      def force_to_bucket!(series_name, bucket_name, group_name)
        # Forcefully place inside the bucket
        in_bucket?(series_name, bucket_name, group_name, true)
      end

      # Iteratively group object into buckets
      #
      # @return [Boolean] true if all the operations are successfull
      def bucketize!
        # Take each series and bucket
        BucketMaker::SeriesMaker.instance.for_each_series_with_bucketable do |series_maker, series_name, bucket_name|
          # Randomize
          group_name = series_maker.bucketize(series_name, bucket_name)
          # Get the series key
          series_key = series_maker.key_for_series(self, series_name, bucket_name)
          # Set the key
          set_group_for_key(series_key, group_name)
          true
        end
      end

      # Group object for series_name and bucket_name
      #
      # @param series_name [String] Name of the Series
      # @param bucket_name [String] Name of the Bucket
      # @return [Boolean] true if the operation is successfull
      def bucketize_for_series_and_bucket!(series_name, bucket_name)
        # Get the singleton Series Maker
        series_maker = BucketMaker::SeriesMaker.instance
        if series_maker.has_bucket_in_series?(series_name, bucket_name)
          # Randomize
          group_name = series_maker.bucketize(series_name, bucket_name)
          # Get the series key
          series_key = series_maker.key_for_series(self, series_name, bucket_name)
          # Set the key
          set_group_for_key(series_key, group_name)
          true
        else
          false
        end
      end

      # Get the value from persistent store for a key
      #
      # @param series_key [String] Series Key
      # @return [String] should return the group_name
      #
      def group_for_key(series_key)
        raise NotImplementedError, "Implement group_for_key"
      end

      # Set the value to a persistent store for a series and group
      #
      # @param series_key [String] Series Key
      # @param group_name [String] Name of the Group
      #
      def set_group_for_key(series_key, group_name)
        raise NotImplementedError, "Implement set_group_for_key"
      end

      private :group_for_key, :set_group_for_key

    end
  end
end