@Override public void execute() { final WordIndexContextProvider wicp = wicpReactor.getInstance(); // add new link and possibly word final NodeId contextNodeId = wicp.getWordIndexContext(); final NodeKey nodeKey = new NamedNodeKey(contextNodeId, word); // final Coordinator coordinator = coordReactor.getInstance(); final Reservation reservation = coordinator.reserve( CoordinatorUtil.makeSetOfRules(new BaseKeyRule(nodeKey)), CoordinatorUtil.makeSetOfIntents(new BaseKeyIntent(nodeKey))); try { final BeginTransactionResult btr = kernel.beginTransaction(); final NodesTransaction txn = btr.getTxn(); boolean commit = false; try { NodeId wordNodeId = txn.getNode(nodeKey); if (wordNodeId == null) { // TODO use unique datum? wordNodeId = txn.insertNode(new StringDatum(word)); txn.insertKey(nodeKey, wordNodeId, false); txn.dereference(wordNodeId); } final NodeId linkNodeId = txn.insertNode(); txn.insertLink(linkNodeId, nodeBeingIndexed, wordParentMeaningNodeId, false); txn.insertLink(linkNodeId, wordNodeId, wordMeaningNodeId, false); txn.dereference(linkNodeId); commit = true; } finally { txn.finish(commit); } } finally { reservation.release(); } }
@Override public void updateIndex( final @NonNull NodesTransaction txn, final @NonNull NodeId nodeId, final boolean deferred) { final ValidatingKernel kernel = k1Reactor.getInstance(); final Queue queue = queueReactor.getInstance(); final WordMeaning wordMeaning = wordMeaningReactor.getInstance(); final WordParentMeaning wordParentMeaning = wordParentMeaningReactor.getInstance(); final MimeTypeMeaning mimeTypeMeaning = mimeTypeMeaningReactor.getInstance(); final LocaleMeaning localeMeaning = localeMeaningReactor.getInstance(); final Coordinator coordinator = coordReactor.getInstance(); final Reservation reservation = coordinator.reserve( CoordinatorUtil.makeSetOfRules(new BaseNodeRule(nodeId)), CoordinatorUtil.makeSetOfIntents(new BaseNodeIntent(nodeId))); try { final Datum datum = txn.getDatum(nodeId); final MimeType mimeType = mimeTypeMeaning.getMimeType(txn, nodeId); final Locale locale = localeMeaning.getLocale(txn, nodeId); final List<Stemmer> stemmers = StemmerUtil.getStemmers(bundleContext, locale); WordParser parser; if (mimeType != null) { parser = getParser(mimeType.toString()); } else if (datum instanceof StringDatum) { parser = getParser("text/plain"); } else { parser = null; } if (parser == null) return; Cursor<NodeId> cursor = null; final Map<String, NodeId> oldIndexEntries = new HashMap<String, NodeId>(); final Set<NodeId> oldNodesToDelete = new HashSet<NodeId>(); try { cursor = txn.fetchSourceNodes(nodeId, wordParentMeaning.getNodeId()); for (final NodeId linkNodeId : cursor) { if (linkNodeId != null) { final NodeId wordNodeId = txn.getTarget(linkNodeId, wordMeaning.getNodeId()); if (wordNodeId != null) { final Datum wordDatum = txn.getDatum(wordNodeId); if (wordDatum instanceof StringDatum) { final String indexEntry = ((StringDatum) wordDatum).getValue(); final NodeId oldLinkNodeId = oldIndexEntries.get(indexEntry); if (oldLinkNodeId != null) { // get rid of redundant link oldNodesToDelete.add(linkNodeId); } else { oldIndexEntries.put(indexEntry, linkNodeId); } } } } } } finally { if (cursor != null) cursor.close(); } // enqueue deletes for all redundant links for (final NodeId linkNodeId : oldNodesToDelete) { if (linkNodeId != null) { final QueueOperation op = new DeleteIndexLinkOperation( kernel, nodeId, linkNodeId, wordParentMeaning.getNodeId(), wordMeaning.getNodeId()); if (deferred) { queue.add(op, 0); queue.start(); } else op.execute(); } } Reader reader; try { reader = new InputStreamReader(datum.getInputStream()); } catch (final IOException e) { // TODO log something reader = null; } if (reader == null) return; final Set<String> newStemmedWords = new HashSet<String>(); Set<String> words = new HashSet<String>(); for (final String word : parser.parse(reader)) { if (word != null) { words.add(word); } } for (final Stemmer stemmer : stemmers) { if (stemmer != null) { words = stemmer.stem(words); } } newStemmedWords.addAll(words); for (final String word : newStemmedWords) { if (word != null) { final NodeId oldLinkNodeId = oldIndexEntries.get(word); if (oldLinkNodeId != null) { oldIndexEntries.remove(word); } else { final QueueOperation op = new IndexOperation( kernel, wicpReactor, coordReactor, word, nodeId, wordParentMeaning.getNodeId(), wordMeaning.getNodeId()); queue.add(op, 0); } } } // enqueue deletes for all old word links that no longer apply for (final NodeId linkNodeId : oldIndexEntries.values()) { if (linkNodeId != null) { final QueueOperation op = new DeleteIndexLinkOperation( kernel, nodeId, linkNodeId, wordParentMeaning.getNodeId(), wordMeaning.getNodeId()); if (deferred) queue.add(op, 0); else op.execute(); } } } finally { reservation.release(); } }