require "memoist" module Scrivito module Backend class ContentStateNode < Struct.new(:content_state_id) extend Memoist def self.find(csid) raise InternalError unless csid new(csid) end def id content_state_id end def create_successor(successor_content_state_id, objs) successor = self.class.new(successor_content_state_id) CmsDataCache.write_content_state_node(successor.id, [id, objs]) successor end # used as special return values CACHE_MISS = Object.new NOT_FOUND = Object.new MAX_TRAVERSAL_DEPTH = 20 def obj_from_changes(id, up_to_csid, up_to_depth = MAX_TRAVERSAL_DEPTH) return NOT_FOUND if up_to_csid == content_state_id return CACHE_MISS if up_to_depth == 0 if pred = predecessor found = changed_objs.detect { |obj| obj["_id"] == id } return found || pred.obj_from_changes(id, up_to_csid, up_to_depth - 1) else CACHE_MISS end end private def predecessor self.class.find(data.first) if data end def changed_objs unless data raise InternalError, "access to changes without predecessor" end data.second end def data CmsDataCache.read_content_state_node(content_state_id) end memoize :data end end end