jackrabbit in action five(インデックスコミット(上))

13292 ワード

前の記事では、インデックスの作成の一般的な流れを理解しました.前の記事では、nodeのどの情報がインデックスに追加される必要があるのか、つまりjackrabbitがdocumentを作成する方法を明確に知っています.次にjackrabbitがインデックスファイルにこれらのdocumentをどのように追加したのかを理解します.次に、インデックスの概要の最後の言葉を振り返ります.コードの主な論理はどこにありますか.DeleteNodeクラスとAddNodeクラス、そしてflushメソッドです.この言葉は、本明細書で説明する必要がある内容を十分に説明しています.それは、1 documentをindexから削除する方法2 documentをindexに配置する方法3 flushとは、この3つの内容を議論する前に、executeAndLogメソッドの役割を説明する必要があります.メソッド名から、私たちが得た情報は、1 Nodeを実行し、logのいくつかのデータを実行することです.では、ソースコードexecute AndLog(new DeleteNode(transactionId)(UUID)remove.next()を見てみましょう.まずexecuteAndLogメソッドに入ります.
private Action executeAndLog(Action a)
            throws IOException {
        a.execute(this);
        redoLog.append(a);
        // please note that flushing the redo log is only required on
        // commit, but we also want to keep track of new indexes for sure.
        // otherwise it might happen that unused index folders are orphaned
        // after a crash.
        if (a.getType() == Action.TYPE_COMMIT || a.getType() == Action.TYPE_ADD_INDEX) {
            redoLog.flush();
            // also flush indexing queue
            indexingQueue.commit();
        }
        return a;
}
 

, :1 DeleteNode execute ( Action )2 redolog(redolog , )3 redolog commit indexingqueue( index , , indexingqueue ) Action ,DeleteNode Action , , Action : Action , ahuaxuan , DeleteNode AddNode 。 Action , 3 1 document index , DeleteNode : DeleteNode Node index action。 execute , DeleteNode execute ( ahuaxuan , ):

public void execute(MultiIndex index) throws IOException {
//  deleteNode           Node,     //node uuid
            String uuidString = uuid.toString();
            // check if indexing queue is still working on
            // this node from a previous update
//  uuid document indexingqueue   
            Document doc = index.indexingQueue.removeDocument(uuidString);
            if (doc != null) {
                Util.disposeDocument(doc);
            }
            Term idTerm = new Term(FieldNames.UUID, uuidString);
            // if the document cannot be deleted from the volatile index
            // delete it from one of the persistent indexes.
//     document             ,     volatieindex document           ,      
 persistentindex ,    。
            int num = index.volatileIndex.removeDocument(idTerm);
            if (num == 0) {
                for (int i = index.indexes.size() - 1; i >= 0; i--) {
//         ,       persistentindex   
                    // only look in registered indexes
                    PersistentIndex idx = (PersistentIndex) index.indexes.get(i);
                    if (index.indexNames.contains(idx.getName())) {
                        num = idx.removeDocument(idTerm);
                        if (num > 0) {
                            return;
                        }
                    }
                }
            }
        }
 

indexingqueue node document, volatileindex ( indexfile) document, persistentindex document, :1. indexingqueue node document, indexingqueue ?Indexingqueue document extract node, node , pdf, , ,jackrabbit , , document indexingqueue 。 document , 。2. Volatileindex , , memory , , :

int removeDocument(Term idTerm) throws IOException {
        Document doc = (Document) pending.remove(idTerm.text());
        int num;
        if (doc != null) {
            Util.disposeDocument(doc);
            // pending document has been removed
            num = 1;
        } else {
            // remove document from index
            num = super.getIndexReader().deleteDocuments(idTerm);
        }
        numDocs -= num;
        return num;
}
 
このメソッドはDeleteNodeのexecuteメソッドで び されました.このメソッドから ると、volatileindexクラスにpendingキューがあり、documentが かれています.このキューが の さを えると、documentのデータがバイナリインデックスデータとしてメモリに されます.
もう1つはpendingにこのdocumentが しない 、indexreaderを び してramdirectoryで を たすdocumentを することです.
つまり、volatileはいずれもメモリを しており、documentキューがあり、キュー が10を えるとindexのバイナリデータに されてramdirectoryに されます.
ここを ると、 たちはメモリのindexデータがディスクにどのように かれているのかという をするはずです.メモリ のデータをディスクにコピーするcopyメソッドが で されます.
3.Persistentindexとは ですか.インデックスを し、インデックスを メディアに します. はlocal file systemです.そしてPersistentIndexがたくさんあるように えます. なるpersistentindexでは、 なるdirectoryが されます.この は、これらの なるfsdirectoryが の で する があることを えてくれたのではないでしょうか.2つの を って、 たちは を ることができます.
で えば、1つのdocumentは の に する があり、1つのnodeを すると、これらの はすべて する があります.
2つ の きな を てみましょう
2 documentをindexに する
DeleteNodeと じように、AddNodeの もそのexecuteメソッドにある 、それなら ってみましょう.
public void execute(MultiIndex index) throws IOException {
            if (doc == null) {
                try {
//  doc null    document,  document             。
                    doc = index.createDocument(new NodeId(uuid));
                } catch (RepositoryException e) {
                    // node does not exist anymore
                    log.debug(e.getMessage());
                }
            }
            if (doc != null) {
                index.volatileIndex.addDocuments(new Document[]{doc});
            }
        }
 
この は で に ではありませんて、 で を じられないで、ほほほ、 に わされないでください. てみましょう
volatileIndex.addDocumentsこの は、 がこの にあるためです.
void addDocuments(Document[] docs) throws IOException {
        for (int i = 0; i < docs.length; i++) {
            Document old = (Document) pending.put(docs[i].get(FieldNames.UUID), docs[i]);
//   pending  volatileindex   document    
            if (old != null) {
                Util.disposeDocument(old);
            }

//        10(bufferSize),    commitPending,         commitPending   
            if (pending.size() >= bufferSize) {
                commitPending();
            }
            numDocs++;
        }
        invalidateSharedReader();
    }
 
がcommitPendingに った 、 たちはcommitPendingを て、 から ると、commitPendingはpendingのdocumentを します.
private void commitPending() throws IOException {
        super.addDocuments((Document[]) pending.values().toArray(
                new Document[pending.size()]));
//       ,  pending   ,    pending  。
        pending.clear();
    }
 
はまだこの ではありません.では、 たちは を し け、この AbstractIndex.addDocumentsを てみましょう.この では、 たちが たいものをやっと ました.
void addDocuments(Document[] docs) throws IOException {
        final IndexWriter writer = getIndexWriter();
//     ,   docs      10,     10   
        DynamicPooledExecutor.Command commands[] =
                new DynamicPooledExecutor.Command[docs.length];

        for (int i = 0; i < docs.length; i++) {
            // check if text extractor completed its work
            final Document doc = getFinishedDocument(docs[i]);
            // create a command for inverting the document
            commands[i] = new DynamicPooledExecutor.Command() {
                public Object call() throws Exception {
                    long time = System.currentTimeMillis();
//        writer   document  ,    ,lucene    document,   index  
                    writer.addDocument(doc);
                    return new Long(System.currentTimeMillis() - time);
                }
            };
        }
//    
        DynamicPooledExecutor.Result results[] = EXECUTOR.executeAndWait(commands);
//  readOnlyReader sharedReader,     ,index     
        invalidateSharedReader();
        IOException ex = null;

//           ,          ,        log 
        for (int i = 0; i < results.length; i++) {
            if (results[i].getException() != null) {
                Throwable cause = results[i].getException().getCause();
                if (ex == null) {
                    // only throw the first exception
                    if (cause instanceof IOException) {
                        ex = (IOException) cause;
                    } else {
                        IOException e = new IOException();
                        e.initCause(cause);
                        ex = e;
                    }
                } else {
                    // all others are logged
                    log.warn("Exception while inverting document", cause);
                }
            } else {
                log.debug("Inverted document in {} ms", results[i].get());
            }
        }
        if (ex != null) {
            throw ex;
        }
    }
 
メソッドのコメントを て、AddNodeメソッドで される は、メモリにindexデータを する であることがわかりました.そしてこの は されます.
では、メモリ のindexデータをディスクに き む はありませんか. ですか.この に えるには、MultiIndex#updateメソッドに ります.
executeAndLog(new AddNode(transactionId, doc));
                    // commit volatile index if needed
                    flush |= checkVolatileCommit();
 
ここにcheckVolatileCommitがあるのを て、 から ると、Y はメモリのデータをディスクにブラシしたいので、 に ってみましょう.
private boolean checkVolatileCommit() throws IOException {
        if (volatileIndex.getNumDocuments() >= handler.getMinMergeDocs()) {
            commitVolatileIndex();
            return true;
        }
        return false;
}
 
やはり、volatileIndex.getNumDocuments()は するdocumentの を しますが、handler.getMinMergeDocs()のデフォルト は100です.つまり、メモリ のindexデータに するdocumentが100を えると、commitVolatileIndex を い、trueを します.そうしないとfalseを します.このtrueまたはfalseは に です. のflush に が かどうかを するため、flushは たちが する3 の きな です.flushということを れた は、 の に べた3つの きな を てください.では、ここまで にはメモリのデータがディスクにブラシされる があります.ahuaxuanも はそう っていましたが、jackrabbitは でした.では、 に ってみましょう(ahuaxuanの に してください):
 
private void commitVolatileIndex() throws IOException {

        // check if volatile index contains documents at all
        if (volatileIndex.getNumDocuments() > 0) {

            long time = System.currentTimeMillis();
            // create index
/*        Action    CreateIndex,         persistentindex  ,   ,          execute   ,         ,   ,           null,           persistentindex,     persistentindex       fsdiretory,    fsdirectory          ,            index directory     */
            CreateIndex create = new CreateIndex(getTransactionId(), null);
            executeAndLog(create);

            // commit volatile index
/* VolatileCommit       ,  action            index         persistentindex   ,      persistentindex name      ,          persistentindex  ,        ,ahuaxuan        ,        volatile index         persistentindex,       ramdirectory fsdirectory      */

            executeAndLog(new VolatileCommit(getTransactionId(), create.getIndexName()));

            // add new index
/*  AddIndex         ,          ?*/
            AddIndex add = new AddIndex(getTransactionId(), create.getIndexName());
            executeAndLog(add);

            // create new volatile index
/*volatileindex           ,         volatileindex ,    ,     */
            resetVolatileIndex();

            time = System.currentTimeMillis() - time;
            log.debug("Committed in-memory index in " + time + "ms.");
        }
    }
 
コードやahuaxuanの から ると、メモリのindexデータをディスクにブラシするのは なことではありません.しかし、この から、persistentindexには100 のdocumentのindexデータしか まれていないという な が られました.しかし、 いあなたはすでに がかりを ているに いありません. の で、これらのpersistentindexは は1つの が けていることを えてくれているようです.それらはindexファイルを する があります.この はAddIndexと に しています. たちはAddIndexの に し がかりを ているようです.
この を くには、AddIndexで なければなりません.
public void execute(MultiIndex index) throws IOException {
            PersistentIndex idx = index.getOrCreateIndex(indexName);
/*index.indexNames      ?        ,      persistentindex            ,      ,      ,     persistentindex             persistentindex,              persistentindex   indexNames  ,              ,           ,      indexName   merger ,      ,  merger         persistentindex    */
            if (!index.indexNames.contains(indexName)) {
                index.indexNames.addName(indexName);
                // now that the index is in the active list let the merger know about it
                index.merger.indexAdded(indexName, idx.getNumDocuments());
            }
        }
 
では、このようなmerger があることを った 、 が をしたか てみなくても し ありません.
クラスの を てください:Merges indexes in a separate deamon thread.
deamonスレッドだったのか、バックグラウンドでmerge を けているに いない. には、persistentindexに かれたときにmerger を する もあるはずだ.この の には たちが ぶべきところがたくさんあるはずだ.このような えを って、ahuaxuanはその を ろに くことにした.
にflushという についてお しします.これはインデックスコミットの3 の なプロセスです.
  To be continue