Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

no comment

  • Loading branch information...
commit 061399bcebe943a26ca4c272f684782df1b266ca 1 parent 8ac9b68
@seki authored
Showing with 156 additions and 0 deletions.
  1. +156 −0 drip.txt
View
156 drip.txt
@@ -589,6 +589,62 @@ Dripはストレージに関する一連の習作の経験から、「作りす
@rootで検索対象となるディレクトリを指定しますが、ファイル数が多いと実験に時間が非常にかかるので、少ないディレクトリを選んでください。500ファイル程度が実験しやすいのではないかと思います。
+>|ruby|
+require 'pp'
+require 'my_drip'
+require 'monitor'
+
+class Crowler
+ include MonitorMixin
+
+ def initialize
+ super()
+ @root = File.expand_path('~/develop/git-repo/')
+ @drip = MyDrip
+ k, = @drip.head(1, 'rbcrowl-begin')[0]
+ @fence = k || 0
+ end
+
+ def last_mtime(fname)
+ k, v, = @drip.head(1, 'rbcrowl-fname=' + fname)[0]
+ (v && k > @fence) ? v[1] : Time.at(1)
+ end
+
+ def do_crowl
+ synchronize do
+ ary = []
+ Dir.chdir(@root)
+ Dir.glob('**/*.rb').each do |fname|
+ mtime = File.mtime(fname)
+ next if last_mtime(fname) >= mtime
+ @drip.write([fname, mtime, File.read(fname)],
+ 'rbcrowl', 'rbcrowl-fname=' + fname)
+ ary << fname
+ end
+ @drip.write(ary, 'rbcrowl-footprint')
+ ary
+ end
+ end
+
+ def quit
+ synchronize do
+ exit(0)
+ end
+ end
+end
+
+crowler = Crowler.new
+Thread.new do
+ while true
+ pp crowler.do_crowl
+ sleep 60
+ end
+end
+
+gets
+crowler.quit
+||<
+
***インデクサ
@@ -598,6 +654,101 @@ Dripはストレージに関する一連の習作の経験から、「作りす
インデクサは起動されるとスレッドを生成してサブスレッドでDripからのread_tagと索引づけを行います。メインスレッドではユーザーからの入力を待ち、入力されるとその単語を探して検索結果を印字します。起動してすぐはまだ索引が完全でないので、急いでなんども検索すると索引対象が増えていく様子を見られるかもしれません。
+>|ruby|
+require 'nkf'
+require 'rbtree'
+require 'my_drip'
+require 'monitor'
+require 'pp'
+
+class Indexer
+ def initialize(cursor=0)
+ @drip = MyDrip
+ @dict = Dict.new
+ k, = @drip.head(1, 'rbcrowl-begin')[0]
+ @fence = k || 0
+ @cursor = [cursor, @fence].max
+ end
+ attr_reader :dict
+
+ def prev_version(cursor, fname)
+ k, v = @drip.older(cursor, 'rbcrowl-fname=' + fname)
+ (v && k > @fence) ? v : nil
+ end
+
+ def each_document
+ while true
+ ary = @drip.read_tag(@cursor, 'rbcrowl', 10, 1)
+ ary.each do |k, v|
+ prev = prev_version(k, v[0])
+ yield(v, prev)
+ @cursor = k
+ end
+ end
+ end
+
+ def update_dict
+ each_document do |cur, prev|
+ @dict.delete(*prev) if prev
+ @dict.push(*cur)
+ end
+ end
+end
+
+class Dict
+ include MonitorMixin
+ def initialize
+ super()
+ @tree = RBTree.new
+ end
+
+ def query(word)
+ synchronize do
+ @tree.bound([word, 0, ''], [word + "\0", 0, '']).collect {|k, v| k[2]}
+ end
+ end
+
+ def delete(fname, mtime, src)
+ synchronize do
+ each_tree_key(fname, mtime, src) do |key|
+ @tree.delete(key)
+ end
+ end
+ end
+
+ def push(fname, mtime, src)
+ synchronize do
+ each_tree_key(fname, mtime, src) do |key|
+ @tree[key] = true
+ end
+ end
+ end
+
+ def intern(word)
+ k, v = @tree.lower_bound([word, 0, ''])
+ return k[0] if k && k[0] == word
+ word
+ end
+
+ def each_tree_key(fname, mtime, src)
+ NKF.nkf('-w', src).scan(/\w+/m).uniq.each do |word|
+ yield([intern(word), mtime.to_i, fname])
+ end
+ end
+end
+
+indexer ||= Indexer.new(0)
+Thread.new do
+ indexer.update_dict
+end
+
+while line = gets
+ ary = indexer.dict.query(line.chomp)
+ pp ary
+ pp ary.size
+end
+||<
+
***フェンスと足跡
@@ -605,6 +756,11 @@ Dripはストレージに関する一連の習作の経験から、「作りす
そこでこのアプリケーションの始まりの点を閉めすオブジェクトを導入することに。'rbcrowl-begin'というタグを持つオブジェクトがあるときは、それよりも旧い情報を無視することで、それ以前のオブジェクトに影響されずに実験できます。@fenceはクロウラ、インデクサのどちらでも使っているので読んでみて下さい。
具体的にはolderやheadの際にそのキーをチェックして、@fenceよりも旧かったら無視することにします。
+>||
+=> MyDrip.write('fence', 'rbcrowl-begin')
+>> 1313573767321913
+||<
+
インデクサが索引を二次記憶に書くようになると、プロセスの寿命と索引の寿命が異なるようになります。このような状況にはしばしば出会うと思います。このとき、インデクサが処理を進めたポイントに足跡となるオブジェクトを残すことで、次回の起動に備えることができます。先のフェンスは無効となるポイントを示しましたが、この場合の足跡はまだ処理していないポイントを示すことになります。
Please sign in to comment.
Something went wrong with that request. Please try again.