lib/xamplr/persister/tokyo-cabinet.rb in hutch-xamplr-1.0.2 vs lib/xamplr/persister/tokyo-cabinet.rb in hutch-xamplr-1.0.3

- old
+ new

@@ -13,21 +13,20 @@ rmsg = nil unless result then rmsg = sprintf(msg, @tc_db.errmsg(@tc_db.ecode)) STDERR.printf(rmsg) -# STDERR.printf("CODE: " + @tc_db.ecode) - puts "---------" + STDERR.puts "---------" caller(0).each do |trace| STDERR.puts(trace) end - puts "---------" + STDERR.puts "---------" end return rmsg end - $lexical_indexes = Set.new(%w{ class pid time-stamp }) unless defined?($lexical_indexes) + $lexical_indexes = Set.new(%w{ class pid time-stamp xampl_from xampl_to }) unless defined?($lexical_indexes) $numeric_indexes = Set.new unless defined?($numeric_indexes) def TokyoCabinetPersister.add_lexical_indexs(indexes) $lexical_indexes.merge(indexes) end @@ -62,10 +61,11 @@ note_errors("TC:: open error: %s\n") do @tc_db.open(@filename, TDB::OWRITER | TDB::OCREAT | TDB::OLCKNB ) #TDB::OTSYNC slows it down by almost 50 times end # Don't care if there are errors (in fact, if the index exists a failure is the expected thing) + $lexical_indexes.each do | index_name | @tc_db.setindex(index_name, TDB::ITLEXICAL | TDB::ITKEEP) end $numeric_indexes.each do | index_name | @tc_db.setindex(index_name, TDB::ITDECIMAL | TDB::ITKEEP) @@ -191,11 +191,10 @@ if hint then return results, the_hint else return results end - end def find_pids(hint=false) open_tc_db query = TableQuery.new(@tc_db) @@ -213,11 +212,10 @@ if hint then return result_keys, the_hint else return result_keys end - end def find_meta(hint=false) open_tc_db query = TableQuery.new(@tc_db) @@ -237,11 +235,44 @@ if hint then return results, the_hint else return results end + end + def find_mentions_of(xampl) + open_tc_db + + place = File.join(xampl.class.name.split("::"), xampl.get_the_index) + + query = TableQuery.new(@tc_db) + query.add_condition('xampl_to', :equals, place) + result_keys = query.search + + class_cache = {} + results = result_keys.collect do | key | + result = @tc_db[ key ] + next unless result + + mentioner = result['xampl_from'] + class_name = result['class'] + result_class = class_cache[class_name] + unless result_class then + class_name.split("::").each do | chunk | + if result_class then + result_class = result_class.const_get( chunk ) + else + result_class = Kernel.const_get( chunk ) + end + end + + class_cache[class_name] = result_class + end + + self.lookup(result_class, result['pid']) + end + return results end def do_sync_write open_tc_db @time_stamp = Time.now.to_f.to_s @@ -279,12 +310,36 @@ def write(xampl) raise XamplException.new(:no_index_so_no_persist) unless xampl.get_the_index place = File.join(xampl.class.name.split("::"), xampl.get_the_index) - data = represent(xampl) + mentions = Set.new + data = represent(xampl, mentions) + query = TableQuery.new(@tc_db) + query.add_condition('xampl_from', :equals, place) + note_errors("TC:: failed to remove from mentions, error: %s\n") do + query.searchout + end + + mentions.each do | mention | + mention_place = File.join(mention.class.name.split("::"), mention.get_the_index) + #TODO -- will repeadedly changing a persisted xampl object fragment the TC db? + + pk = @tc_db.genuid + mention_hash = { + 'xampl_from' => place, + 'class' => xampl.class.name, + 'pid' => xampl.get_the_index, + 'xampl_to' => mention_place + } + + note_errors("TC:: write error: %s\n") do + @tc_db.put(pk, mention_hash) + end + end + xampl_hash = { 'class' => xampl.class.name, 'pid' => xampl.get_the_index, 'time-stamp' => @time_stamp, 'xampl' => data @@ -423,9 +478,17 @@ if hint then return r, @query.hint else return r end + end + + # + # Performs the search and removes whatever's found + # + + def searchout + r = @query.searchout end # limits the search def setlimit(max=nil, skip=nil)