<commit_before>require '../lckmgr'

module DeadlockProtocol
  # A deadlock detection protocol outputs an array of mutually deadlocked
  # transaction ids, and a chosen victim.
  state do
    interface output, :deadlock, [:xidlist] => [:victim]
  end
end

module DDLNodeProtocol
  state do
    interface input, :set_coordinator, [:coordinator]
  end
end

module DDLNodeCommunicationProtocol
  state do
    channel :pipe_channel, [:@dst, :src] => [:from, :to]
  end
end

module LockMgrWaitsForGraph
  include TwoPhaseLockMgr

  state do
    scratch :waits_for, [:waiter, :waitee]
  end

  bloom :waits_for do
    # For each item in the lock queue, figure out what it is waiting for
    # by which lock is the reason it can't get the resource
    waits_for <= (queue * locks).pairs(:resource => :resource) { |q, l|
      [q.xid, l.xid]
    }
  end
end

module LocalDeadlockDetector
  include DeadlockProtocol
   
  state do
    scratch :link, [:from, :to] => []
    scratch :path, [:from, :to, :nodes] => []
    scratch :cycle, [:nodes] 

    scratch :victims, [:xid]

    interface input, :add_link, [:from, :to]
  end

  bloom :add_links do
    link <= add_link
  end

  bloom :cycle_detection do
    # Even if there are cycles, this will stop eventually because
    # cycles will insert duplicates
    # Ex. a -> b == a -> b, a -> b -> c -> d -> a == a -> b
    path <= link {|l| [l.from, l.to, l]}
    path <= (link * path).pairs(link.to => path.from) do |l,p|  
      [l.from, p.to, [l.from] | p.nodes] 
    end

    #stdio <~ path.inspected
    # A cycle means that there is some path betwen a node and itself
    # Ex. a -> a
    cycle <= path { |p| [p.nodes.sort] if p.from == p.to }
  end

  bloom :break_cycle do
    # Victim should always be the highest transaction id in the cycle
    deadlock <= cycle { |c| [c.nodes, c.first.max] }
  end
end

# Because this class includes the LocalDeadlockDetector module, once
# links are added, a deadlock will be reported via the deadlock output 
module DLLockManager
  include LocalDeadlockDetector
  include LockMgrWaitsForGraph

  bloom :send_graph do
    # Add the waits-for graph
    add_links <= waits_for
  end
end

module DDLNode
  include DDLNodeProtocol
  include DDLNodeCommunicationProtocol
  include LockMgrWaitsForGraph

  state do
    table :coordinator, [] => [:coordinator]
  end

  bloom :set_coordinator do
    coordinator <= set_coordinator 
  end
  
  bloom :send_graph do
    pipe_channel <~ (coordinator * waits_for).pairs { |c, w|
      [c.coordinator, ip_port, w.waiter, w.waitee]
    }
  end
end

# Because this class includes the LocalDeadlockDetector module, once
# links are added, a deadlock will be reported via the deadlock output 
module DDLMaster
  include DDLNodeCommunicationProtocol
  include LocalDeadlockDetector

  state do
    table :link, [:from, :to] => []
  end

  bloom :apply_graph do
    add_link <= pipe_channel { |p| [p.from, p.to] }
  end
end
<commit_msg>Commented out the link table in master - it complains that it already exists since we are including LocalDeadLockDetector in DDLMaster<commit_after>require '../lckmgr'

module DeadlockProtocol
  # A deadlock detection protocol outputs an array of mutually deadlocked
  # transaction ids, and a chosen victim.
  state do
    interface output, :deadlock, [:xidlist] => [:victim]
  end
end

module DDLNodeProtocol
  state do
    interface input, :set_coordinator, [:coordinator]
  end
end

module DDLNodeCommunicationProtocol
  state do
    channel :pipe_channel, [:@dst, :src] => [:from, :to]
  end
end

module LockMgrWaitsForGraph
  include TwoPhaseLockMgr

  state do
    scratch :waits_for, [:waiter, :waitee]
  end

  bloom :waits_for do
    # For each item in the lock queue, figure out what it is waiting for
    # by which lock is the reason it can't get the resource
    waits_for <= (queue * locks).pairs(:resource => :resource) { |q, l|
      [q.xid, l.xid]
    }
  end
end

module LocalDeadlockDetector
  include DeadlockProtocol
   
  state do
    scratch :link, [:from, :to] => []
    scratch :path, [:from, :to, :nodes] => []
    scratch :cycle, [:nodes] 

    scratch :victims, [:xid]

    interface input, :add_link, [:from, :to]
  end

  bloom :add_links do
    link <= add_link
  end

  bloom :cycle_detection do
    # Even if there are cycles, this will stop eventually because
    # cycles will insert duplicates
    # Ex. a -> b == a -> b, a -> b -> c -> d -> a == a -> b
    path <= link {|l| [l.from, l.to, l]}
    path <= (link * path).pairs(link.to => path.from) do |l,p|  
      [l.from, p.to, [l.from] | p.nodes] 
    end

    #stdio <~ path.inspected
    # A cycle means that there is some path betwen a node and itself
    # Ex. a -> a
    cycle <= path { |p| [p.nodes.sort] if p.from == p.to }
  end

  bloom :break_cycle do
    # Victim should always be the highest transaction id in the cycle
    deadlock <= cycle { |c| [c.nodes, c.first.max] }
  end
end

# Because this class includes the LocalDeadlockDetector module, once
# links are added, a deadlock will be reported via the deadlock output 
module DLLockManager
  include LocalDeadlockDetector
  include LockMgrWaitsForGraph

  bloom :send_graph do
    # Add the waits-for graph
    add_links <= waits_for
  end
end

module DDLNode
  include DDLNodeProtocol
  include DDLNodeCommunicationProtocol
  include LockMgrWaitsForGraph

  state do
    table :coordinator, [] => [:coordinator]
  end

  bloom :set_coordinator do
    coordinator <= set_coordinator 
  end
  
  bloom :send_graph do
    pipe_channel <~ (coordinator * waits_for).pairs { |c, w|
      [c.coordinator, ip_port, w.waiter, w.waitee]
    }
  end
end

# Because this class includes the LocalDeadlockDetector module, once
# links are added, a deadlock will be reported via the deadlock output 
module DDLMaster
  include DDLNodeCommunicationProtocol
  include LocalDeadlockDetector

  # state do
  #   table :link, [:from, :to] => []
  # end

  bloom :apply_graph do
    add_link <= pipe_channel { |p| [p.from, p.to] }
  end
end

{'fraction_non_alphanumeric': 0.09713243825625725, 'fraction_numerical': 0.0, 'mean_word_length': 3.147079037800687, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6461723', 'n_tokens_mistral': 2055, 'n_tokens_neox': 2011, 'n_words': 699}