<commit_before>module ZK
  # Represents a single path in zookeeper, and can perform operations from the
  # perspective of that path. Operations performed through a Znode object will
  # return Znode instances where appropriate
  #
  # A Znode instance has a path, and will cache the last-known stat object and
  # node data.
  #
  # Znodes will do optimistic locking by default, and will throw a
  # ZK::Exceptions::BadVersion error if you attempt to update a node and its
  # been changed behind your back
  #
  module Znode
    # When a node is loaded, we apply a simple heuristic to determine if it's a
    # sequential node (as there's no way of knowing except based on the name) so if the 
    # basename of the node matches <tt>/\d{10}\Z/</tt>, we set sequential? to
    # true. ephemeral? is based off of the stat object.
    #
    class Base
      include ZK::Exceptions

      VALID_MODES = [:ephemeral, :persistent, :persistent_sequential, :ephemeral_sequential].freeze
      EPHEMERAL_MODES = [:ephemeral, :ephemeral_sequential].freeze

      # the path of this znode
      attr_reader :path

      # the raw data as a string (possibly containing binary data) containted
      # at this node
      attr_accessor :raw_data

      # what mode should this znode be created as? 
      # should be :persistent or :ephemeral
      #
      # for creating sequential nodes, you must use the class method Znode::Base.create(path, data, :mode => mode) 
      attr_reader :mode

      # the current stat object for the Znode at +path+
      # will be +nil+ if this node is new 
      attr_reader :stat #:nodoc:
      

      # Should be set to a ZK::Pool instance. this will be used by all instances of Base
      # to talk to zookeeper
      def self.zk_pool
        @zk_pool
      end

      def self.zk_pool=(zkp)
        @zk_pool = zkp
      end

      # create a new Znode object and immediately attempt to persist it. 
      #
      def self.create(*args, &block)
        new(*args, &block).tap do |node|
          node.save
        end
      end

      def self.load_or_create(*args, &block)
        self.load(*args, &block)
      rescue NoNode
        self.create(*args, &block)
      end

      def self.load_or_create!(*args, &block)
        self.load(*args, &block)
      rescue NoNode
        self.create!(*args, &block)
      end

      # throws a ZnodeNotSaved exception if the created node was not saved
      def self.create!(*args, &block)
        create(*args, &block).tap do |node|
          raise ZnodeNotSaved if node.new_record?
        end
      end

      # instantiates a Znode at path and calls #reload on it to load the data and current stat
      def self.load(*args)
        new(*args).reload
      end

      # find all children under path and load them
      # returns an empty array if the path doesn't exist
      #
      # if +watch+ is true, sets a watch on the znode at +path+ that will
      # receive events related to children of +path+
      #
      def self.find_all(path, watch=false)
        zk_pool.children(path, :watch => watch).map do |base|
          self.load("#{path}/#{base}")
        end
      rescue NoNode
        []
      end

      def initialize(path, opts={})
        @stat = @raw_data = nil

        @path       = path
        @new_record = true
        @destroyed  = false

        self.mode   = opts[:mode] || :persistent

        d = opts[:raw_data] and self.raw_data = d
      end

      def new_record?
        @new_record
      end

      def destroyed?
        @destroyed
      end

      def persisted?
        !(new_record? || destroyed?)
      end

      def ephemeral?
        EPHEMERAL_MODES.include?(@mode)
      end

      def reload(watch=false)
        self.raw_data, @stat = zk.get(path, :watch => watch)
        @new_record = false
<commit_msg>make znode mode friendlier to subclasses<commit_after>module ZK
  # Represents a single path in zookeeper, and can perform operations from the
  # perspective of that path. Operations performed through a Znode object will
  # return Znode instances where appropriate
  #
  # A Znode instance has a path, and will cache the last-known stat object and
  # node data.
  #
  # Znodes will do optimistic locking by default, and will throw a
  # ZK::Exceptions::BadVersion error if you attempt to update a node and its
  # been changed behind your back
  #
  module Znode
    # When a node is loaded, we apply a simple heuristic to determine if it's a
    # sequential node (as there's no way of knowing except based on the name) so if the 
    # basename of the node matches <tt>/\d{10}\Z/</tt>, we set sequential? to
    # true. ephemeral? is based off of the stat object.
    #
    class Base
      include ZK::Exceptions

      VALID_MODES = [:ephemeral, :persistent, :persistent_sequential, :ephemeral_sequential].freeze
      EPHEMERAL_MODES = [:ephemeral, :ephemeral_sequential].freeze

      # the path of this znode
      attr_reader :path

      # the raw data as a string (possibly containing binary data) containted
      # at this node
      attr_accessor :raw_data

      # what mode should this znode be created as? 
      # should be :persistent or :ephemeral
      #
      # for creating sequential nodes, you must use the class method Znode::Base.create(path, data, :mode => mode) 
      attr_reader :mode

      # the current stat object for the Znode at +path+
      # will be +nil+ if this node is new 
      attr_reader :stat #:nodoc:
      

      # Should be set to a ZK::Pool instance. this will be used by all instances of Base
      # to talk to zookeeper
      def self.zk_pool
        @zk_pool
      end

      def self.zk_pool=(zkp)
        @zk_pool = zkp
      end

      # create a new Znode object and immediately attempt to persist it. 
      #
      def self.create(*args, &block)
        new(*args, &block).tap do |node|
          node.save
        end
      end

      def self.load_or_create(*args, &block)
        self.load(*args, &block)
      rescue NoNode
        self.create(*args, &block)
      end

      def self.load_or_create!(*args, &block)
        self.load(*args, &block)
      rescue NoNode
        self.create!(*args, &block)
      end

      # throws a ZnodeNotSaved exception if the created node was not saved
      def self.create!(*args, &block)
        create(*args, &block).tap do |node|
          raise ZnodeNotSaved if node.new_record?
        end
      end

      # instantiates a Znode at path and calls #reload on it to load the data and current stat
      def self.load(*args)
        new(*args).reload
      end

      # find all children under path and load them
      # returns an empty array if the path doesn't exist
      #
      # if +watch+ is true, sets a watch on the znode at +path+ that will
      # receive events related to children of +path+
      #
      def self.find_all(path, watch=false)
        zk_pool.children(path, :watch => watch).map do |base|
          self.load("#{path}/#{base}")
        end
      rescue NoNode
        []
      end

      def initialize(path, opts={})
        @stat = @raw_data = nil

        @path       = path
        @new_record = true
        @destroyed  = false

        self.mode   ||= opts.fetch(:mode, :persistent)

        d = opts[:raw_data] and self.raw_data = d
      end

      def new_record?
        @new_record
      end

      def destroyed?
        @destroyed
      end

      def persisted?
        !(new_record? || destroyed?)
      end

      def ephemeral?
        EPHEMERAL_MODES.include?(@mode)
      end

      def reload(watch=false)
        self.raw_data, @stat = zk.get(path, :watch => watch)
        @new_record = false

{'fraction_non_alphanumeric': 0.08102123225218184, 'fraction_numerical': 0.0005210368633580826, 'mean_word_length': 2.2018348623853212, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2798967', 'n_tokens_mistral': 2345, 'n_tokens_neox': 2239, 'n_words': 849}