Module: Association::Index

Defined in:
lib/rbbt/association/index.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#source_fieldObject

Returns the value of attribute source_field.



99
100
101
# File 'lib/rbbt/association/index.rb', line 99

def source_field
  @source_field
end

#target_fieldObject

Returns the value of attribute target_field.



99
100
101
# File 'lib/rbbt/association/index.rb', line 99

def target_field
  @target_field
end

#undirectedObject

Returns the value of attribute undirected.



99
100
101
# File 'lib/rbbt/association/index.rb', line 99

def undirected
  @undirected
end

Class Method Details

.setup(repo) ⇒ Object



104
105
106
107
108
109
# File 'lib/rbbt/association/index.rb', line 104

def self.setup(repo)
  repo.extend Association::Index
  repo.parse_key_field
  repo.unnamed = true
  repo
end

Instance Method Details

#match(entity) ⇒ Object



149
150
151
152
153
# File 'lib/rbbt/association/index.rb', line 149

def match(entity)
  return entity.inject([]){|acc,e| acc.concat match(e); acc } if Array === entity
  return [] if entity.nil?
  prefix(entity + "~")
end

#matches(entities) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/rbbt/association/index.rb', line 155

def matches(entities)
  entities.inject(nil) do |acc,e| 
    m = match(e); 
    if acc.nil? or acc.empty?
      acc = m
    else
      acc.concat m
    end
    acc
  end
end

#parse_key_fieldObject



100
101
102
# File 'lib/rbbt/association/index.rb', line 100

def parse_key_field
  @source_field, @target_field, @undirected = key_field.split("~")
end

#reverseObject



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/rbbt/association/index.rb', line 111

def reverse
  @reverse ||= begin
                 if self.respond_to? :persistence_path
                   persistence_path = self.persistence_path
                   persistence_path = persistence_path.find if Path === persistence_path
                   reverse_filename = persistence_path + '.reverse'
                 else
                   raise "Can only reverse a TokyoCabinet::BDB dataset at the time"
                 end

                 self.read if self.respond_to? :read

                 if File.exists?(reverse_filename)
                   new = Persist.open_tokyocabinet(reverse_filename, false, serializer, TokyoCabinet::BDB)
                   new
                 else
                   FileUtils.mkdir_p File.dirname(reverse_filename) unless File.exists?(File.basename(reverse_filename))
                   new = Persist.open_tokyocabinet(reverse_filename, true, serializer, TokyoCabinet::BDB)
                   new.write
                   through do |key, value|
                     new_key = key.split("~").reverse.join("~")
                     new[new_key] = value
                   end
                   annotate(new)
                   new.key_field = key_field.split("~").values_at(1,0,2).compact * "~"
                   new.read
                 end

                 new.unnamed = true

                 Association::Index.setup new

                 new.undirected = undirected

                 new
               end
end

#subset(source, target) ⇒ Object

{{{ Subset



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/rbbt/association/index.rb', line 189

def subset(source, target)
  return [] if source.nil? or target.nil? or source.empty? or target.empty?

  if source == :all or source == "all"
    if target == :all or target == "all"
      return keys
    else
      matches = reverse.subset(target, source)
      return matches.collect{|m| r = m.partition "~"; r.reverse*"" }
    end
  end

  matches = source.uniq.inject([]){|acc,e| 
    if block_given?
      acc.concat(match(e))
    else
      acc.concat(match(e))
    end
  }

  return matches if target == :all or target == "all"

  target_matches = {}

  matches.each{|code| 
    s,sep,t = code.partition "~"
    next if undirected and t > s 
    target_matches[t] ||= []
    target_matches[t] << code
  }

  target_matches.values_at(*target.uniq).flatten.compact
end

#to_matrix(value_field = nil, &block) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/rbbt/association/index.rb', line 167

def to_matrix(value_field = nil, &block)
  value_field = fields.first if value_field.nil? and fields.length == 1
  value_pos = identify_field value_field if value_field and String === value_field
  key_field = source_field

  tsv = if value_pos
          AssociationItem.incidence self.keys, key_field do |key|
            if block_given? 
              yield self[key][value_pos]
            else
              self[key][value_pos]
            end
          end
        elsif block_given?
          AssociationItem.incidence self.keys, key_field, &block
        else
          AssociationItem.incidence self.keys, key_field 
        end
end