Class: Msgthr::Container

Inherits:
Object
  • Object
show all
Defined in:
lib/msgthr/container.rb

Overview

An internal container class, this is exposed for Msgthr#order! and Msgthr#walk_thread APIs. They should should not be initialized in your own code.

One container object will exist for every message you call Msgthr#add! on, so there can potentially be many of these objects for large sets of messages.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mid) ⇒ Container

:nodoc:



35
36
37
38
39
40
# File 'lib/msgthr/container.rb', line 35

def initialize(mid) # :nodoc:
  @mid = mid
  @children = {} # becomes an Array after order!
  @parent = nil
  @msg = nil # opaque pointer supplied by user
end

Instance Attribute Details

#childrenObject

You probably do not need to use this. It is only safe to access this after Msgthr#order! This contains an Array of Msgthr::Container objects which have the parent field pointing to us



26
27
28
# File 'lib/msgthr/container.rb', line 26

def children
  @children
end

#midObject (readonly)

Unique message identifier, typically the Message-Id header for mail and news messages. This may be any hashable object, Integer values are allowed and will not be coerced to string values.



16
17
18
# File 'lib/msgthr/container.rb', line 16

def mid
  @mid
end

#msgObject

Opaque data pointer, may be used by the user for any purpose. This is nil to denote missing (aka “ghost”) messages.



20
21
22
# File 'lib/msgthr/container.rb', line 20

def msg
  @msg
end

#parentObject

You probably do not need to use this; and you should only use this after Msgthr#order! This points to the parent of the message if one exists, and nil if a message has no parent. This will only be accurate once all messages are added to a Msgthr set via Msgthr#add



33
34
35
# File 'lib/msgthr/container.rb', line 33

def parent
  @parent
end

Instance Method Details

#add_child(child) ⇒ Object

:nodoc:



55
56
57
58
59
60
61
62
63
64
# File 'lib/msgthr/container.rb', line 55

def add_child(child) # :nodoc:
  raise 'cannot become child of self' if child == self
  cid = child.mid

  # reparenting:
  parent = child.parent and parent.children.delete(cid)

  @children[cid] = child
  child.parent = self
end

#has_descendent(child) ⇒ Object

:nodoc:



66
67
68
69
70
71
72
73
# File 'lib/msgthr/container.rb', line 66

def has_descendent(child) # :nodoc:
  seen = Hash.new(0)
  while child
    return true if self == child || (seen[child] += 1) != 0
    child = child.parent
  end
  false
end

#order!Object

only called by Msgthr#order!



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/msgthr/container.rb', line 76

def order! # :nodoc:
  seen = { @mid => true }
  q = [ self ]
  while cur = q.shift
    c = []
    cur.children.each do |cmid, cont|
      next if seen[cmid]
      c << cont
      seen[cmid] = true
    end.clear
    yield(c) if c.size > 1
    cur.children = c
    q.concat(c)
  end
end

#topmostObject

Returns the topmost message container with an opaque message pointer in it. This may be nil if no message is available. This is preferable to using the container yielded by Msgthr#order! directly when handling incomplete message sets.



46
47
48
49
50
51
52
53
# File 'lib/msgthr/container.rb', line 46

def topmost
  q = [ self ]
  while cont = q.shift
    return cont if cont.msg
    q.concat(cont.children.values)
  end
  nil
end