discourse/migrations/lib/common/set_store/three_key_set.rb
Gerhard Schlager 53d7a756d6
DEV: Add Migrations::SetStore to work with nested sets of data (#33593)
There are concrete implementations for a simple set, a key-value store,
and nested sets with 2 or 3 keys. The API stays the same for all
implementations and the performances is more or less the same as without
the wrapper (at least with YJIT enabled).
2025-07-24 12:11:41 +02:00

70 lines
1.6 KiB
Ruby
Vendored

# frozen_string_literal: true
module Migrations::SetStore
class ThreeKeySet
include Interface
def initialize
@store = {}
end
def add(key1, key2, key3, value)
h1 = @store[key1] ||= {}
h2 = h1[key2] ||= {}
set = h2[key3] ||= Set.new
set.add(value)
self
end
def add?(key1, key2, key3, value)
h1 = @store[key1] ||= {}
h2 = h1[key2] ||= {}
set = h2[key3] ||= Set.new
!!set.add?(value)
end
def include?(key1, key2, key3, value)
h1 = @store[key1] or return false
h2 = h1[key2] or return false
set = h2[key3] or return false
set.include?(value)
end
def bulk_add(records)
current_key1 = nil
current_key2 = nil
current_key3 = nil
current_h1 = nil
current_h2 = nil
current_set = nil
records.each do |record|
key1, key2, key3, value = record
if key1 != current_key1
current_key1 = key1
current_h1 = @store[key1] ||= {}
current_key2 = key2
current_h2 = current_h1[key2] ||= {}
current_key3 = key3
current_set = current_h2[key3] ||= Set.new
elsif key2 != current_key2
current_key2 = key2
current_h2 = current_h1[key2] ||= {}
current_key3 = key3
current_set = current_h2[key3] ||= Set.new
elsif key3 != current_key3
current_key3 = key3
current_set = current_h2[key3] ||= Set.new
end
current_set.add(value)
end
nil
end
def empty?
@store.empty?
end
end
end