Module: FastTree::Model

Extended by:
ActiveSupport::Concern
Defined in:
lib/fast_tree/model.rb

Defined Under Namespace

Modules: ClassMethods Classes: InvalidTreeStructureError

Instance Method Summary collapse

Instance Method Details

#add_child(node) ⇒ Object

Instance Methods



130
131
132
133
134
135
136
137
138
# File 'lib/fast_tree/model.rb', line 130

def add_child(node)
  # bulk update nodes by a sql query
  _update_nodes(r_ptr, r_ptr, "r_ptr >= #{r_ptr}")

  # child node's pointer
  node.l_ptr = r_ptr
  node.r_ptr = r_ptr + 1
  node.save
end

#copy_to(node) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/fast_tree/model.rb', line 150

def copy_to(node)
  subtree = self.class.find_subtree_by_root(self)

  # create empty space into which subtree embedded
  _update_nodes(node.l_ptr, node.r_ptr, "r_ptr >= #{r_ptr}", width + 1)

  bias = node.l_ptr + 1 - l_ptr
  subtree.each do |st_node|
    attributes = st_node.attributes.to_h
    attributes.delete("id")
    attributes["l_ptr"] = attributes["l_ptr"] + bias
    attributes["r_ptr"] = attributes["r_ptr"] + bias
    self.class.create(attributes)
  end
end

#create_child(attributes = {}, &block) ⇒ Object



140
141
142
143
144
145
146
147
148
# File 'lib/fast_tree/model.rb', line 140

def create_child(attributes = {}, &block)
  # bulk update nodes by a sql query
  _update_nodes(r_ptr, r_ptr, "r_ptr >= #{r_ptr}")

  # create child
  attributes[:l_ptr] = r_ptr
  attributes[:r_ptr] = r_ptr + 1
  self.class.create(attributes, &block)
end

#depthObject



166
167
168
# File 'lib/fast_tree/model.rb', line 166

def depth
  path.size - 1
end

#move_to(node) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/fast_tree/model.rb', line 170

def move_to(node)
  # NOTE:
  # copy_to and remove change node ids
  # move operation should change nothing but left and right pointers

  # bind subtree to a variable
  subtree = self.class.find_subtree_by_root(self)

  # fill (virtual) empty spaces that will be created by moving subtree
  _update_nodes(l_ptr, r_ptr, "l_ptr > #{r_ptr}", - (width + 1))

  # create empty spaces under the node
  node.reload
  _update_nodes(node.l_ptr, node.r_ptr, "l_ptr >= #{node.l_ptr} AND r_ptr <= #{node.r_ptr}", width + 1)

  # move subtree under the given node
  bias = node.l_ptr + 1 - l_ptr
  subtree.each do |st_node|
    st_node.l_ptr += bias
    st_node.r_ptr += bias
    st_node.save
  end
end

#pathObject



205
206
207
208
209
# File 'lib/fast_tree/model.rb', line 205

def path
  self.class.where(self.class.arel_table[:l_ptr].lteq(l_ptr))
            .where(self.class.arel_table[:r_ptr].gteq(r_ptr))
            .order(l_ptr: :asc)
end


211
212
213
# File 'lib/fast_tree/model.rb', line 211

def print_subtree
  self.class.print_subtree(self)
end

#removeObject



194
195
196
197
198
199
200
201
202
203
# File 'lib/fast_tree/model.rb', line 194

def remove
  # remove subtree
  n_destroyed = self.class.find_subtree_by_root(self).destroy_all

  # fill empty space
  _update_nodes(l_ptr, r_ptr, "r_ptr >= #{r_ptr}", - (width + 1))

  # return count of destroyed nodes
  n_destroyed
end

#widthObject



215
216
217
# File 'lib/fast_tree/model.rb', line 215

def width
  r_ptr - l_ptr
end