jackrabbit in action five(インデックスコミット(上))
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