Search in sources :

Example 6 with DiffType

use of org.sirix.diff.DiffFactory.DiffType in project sirix by sirixdb.

the class AbstractDiff method optimizedDiff.

/**
 * Optimized diff, which skips unnecessary comparsions.
 *
 * @param newRtx {@link XdmNodeReadTrx} on new revision
 * @param oldRtx {@link XdmNodeReadTrx} on old revision
 * @param depth {@link DepthCounter} container for current depths of both transaction cursors
 * @param paramFireDiff determines if a diff should be fired
 * @return kind of difference
 */
DiffType optimizedDiff(final XdmNodeReadTrx newRtx, final XdmNodeReadTrx oldRtx, final DepthCounter depth) {
    assert newRtx != null;
    assert oldRtx != null;
    assert depth != null;
    DiffType diff = DiffType.SAMEHASH;
    // Check for modifications.
    switch(newRtx.getKind()) {
        case DOCUMENT:
        case TEXT:
        case ELEMENT:
            if (newRtx.getNodeKey() != oldRtx.getNodeKey() || newRtx.getHash() != oldRtx.getHash()) {
                // Check if nodes are the same (even if subtrees may vary).
                if (checkNodes(newRtx, oldRtx)) {
                    diff = DiffType.SAME;
                    final DiffDepth diffDepth = new DiffDepth(depth.getNewDepth(), depth.getOldDepth());
                    fireDiff(diff, newRtx.getNodeKey(), oldRtx.getNodeKey(), diffDepth);
                    emitNonStructuralDiff(newRtx, oldRtx, diffDepth, diff);
                } else {
                    diff = diffAlgorithm(newRtx, oldRtx, depth);
                }
            } else {
                final DiffDepth diffDepth = new DiffDepth(depth.getNewDepth(), depth.getOldDepth());
                fireDiff(diff, newRtx.getNodeKey(), oldRtx.getNodeKey(), diffDepth);
                emitNonStructuralDiff(newRtx, oldRtx, diffDepth, diff);
            }
            break;
        default:
    }
    return diff;
}
Also used : DiffType(org.sirix.diff.DiffFactory.DiffType)

Example 7 with DiffType

use of org.sirix.diff.DiffFactory.DiffType in project sirix by sirixdb.

the class AbstractDiff method diffAlgorithm.

/**
 * Main algorithm to compute diffs between two nodes.
 *
 * @param newRtx {@link XdmNodeReadTrx} on new revision
 * @param oldRtx {@link XdmNodeReadTrx} on old revision
 * @param depth {@link DepthCounter} container for current depths of both transaction cursors
 * @return kind of diff
 */
private DiffType diffAlgorithm(final XdmNodeReadTrx newRtx, final XdmNodeReadTrx oldRtx, final DepthCounter depth) {
    assert newRtx != null;
    assert oldRtx != null;
    assert depth != null;
    DiffType diff = null;
    if (depth.getOldDepth() > depth.getNewDepth()) {
        // Check if node has been
        // deleted.
        diff = DiffType.DELETED;
        emitDiffs(diff);
    } else if (checkUpdate(newRtx, oldRtx)) {
        // Check if node has been updated.
        diff = DiffType.UPDATED;
        final DiffDepth diffDepth = new DiffDepth(depth.getNewDepth(), depth.getOldDepth());
        fireDiff(diff, newRtx.getNodeKey(), oldRtx.getNodeKey(), diffDepth);
        emitNonStructuralDiff(newRtx, oldRtx, diffDepth, diff);
    } else if (checkReplace(newRtx, oldRtx)) {
        // Check if node has been
        // replaced.
        diff = DiffType.REPLACED;
    } else {
        final long oldKey = oldRtx.getNodeKey();
        final boolean movedOld = oldRtx.moveTo(newRtx.getNodeKey()).hasMoved();
        oldRtx.moveTo(oldKey);
        final long newKey = newRtx.getNodeKey();
        final boolean movedNew = newRtx.moveTo(oldRtx.getNodeKey()).hasMoved();
        newRtx.moveTo(newKey);
        if (!movedOld) {
            diff = DiffType.INSERTED;
        } else if (!movedNew) {
            diff = DiffType.DELETED;
        } else {
            // Determine if one of the right sibling matches.
            EFoundEqualNode found = EFoundEqualNode.FALSE;
            while (oldRtx.hasRightSibling() && oldRtx.moveToRightSibling().hasMoved() && found == EFoundEqualNode.FALSE) {
                if (checkNodes(newRtx, oldRtx)) {
                    found = EFoundEqualNode.TRUE;
                    break;
                }
            }
            oldRtx.moveTo(oldKey);
            diff = found.kindOfDiff();
        }
        mDiff = diff;
        emitDiffs(diff);
    }
    assert diff != null;
    return diff;
}
Also used : DiffType(org.sirix.diff.DiffFactory.DiffType)

Example 8 with DiffType

use of org.sirix.diff.DiffFactory.DiffType in project sirix by sirixdb.

the class AbstractDiff method diff.

/**
 * Diff of nodes.
 *
 * @param newRtx {@link XdmNodeReadTrx} on new revision
 * @param oldRtx {@link XdmNodeReadTrx} on old revision
 * @param depth {@link DepthCounter} container for current depths of both transaction cursors
 * @param paramFireDiff determines if a diff should be fired
 * @return kind of difference
 */
DiffType diff(final XdmNodeReadTrx newRtx, final XdmNodeReadTrx oldRtx, final DepthCounter depth) {
    assert newRtx != null;
    assert oldRtx != null;
    assert depth != null;
    DiffType diff = DiffType.SAME;
    // Check for modifications.
    switch(newRtx.getKind()) {
        case DOCUMENT:
        case TEXT:
        case ELEMENT:
            if (checkNodes(newRtx, oldRtx)) {
                final DiffDepth diffDepth = new DiffDepth(depth.getNewDepth(), depth.getOldDepth());
                fireDiff(diff, newRtx.getNodeKey(), oldRtx.getNodeKey(), diffDepth);
                emitNonStructuralDiff(newRtx, oldRtx, diffDepth, diff);
            } else {
                diff = diffAlgorithm(newRtx, oldRtx, depth);
            }
            break;
        default:
    }
    return diff;
}
Also used : DiffType(org.sirix.diff.DiffFactory.DiffType)

Example 9 with DiffType

use of org.sirix.diff.DiffFactory.DiffType in project sirix by sirixdb.

the class TraverseCompareTree method createSunburstItem.

@Override
public float createSunburstItem(final Item pItem, @Nonnegative final int pDepth, @Nonnegative final int pIndex) {
    checkNotNull(pItem);
    checkArgument(pDepth >= 0, "pDepth must be positive!");
    checkArgument(pIndex >= 0, "pIndex must be >= 0!");
    // Initialize variables.
    final float angle = pItem.mAngle;
    final float parExtension = pItem.mExtension;
    final int indexToParent = pItem.mIndexToParent;
    final int descendantCount = pItem.mDescendantCount;
    final int parentDescCount = pItem.mParentDescendantCount;
    final int modificationCount = pItem.mModificationCount;
    long parentModificationCount = pItem.mParentModificationCount;
    final boolean subtract = pItem.mSubtract;
    final DiffTuple diffCont = pItem.mDiff;
    final int origDepth = pItem.mOrigDepth;
    final int nextDepth = pItem.mNextDepth;
    final int depth = pDepth;
    // Calculate extension.
    float extension = 2 * PConstants.PI;
    if (indexToParent > -1) {
        if (mItems.get(indexToParent).getSubtract()) {
            parentModificationCount -= FACTOR;
        }
        extension = (1f - mModWeight) * (parExtension * (float) descendantCount / ((float) parentDescCount - 1f)) + mModWeight * // modificationCount/parentModificationCount.
        (parExtension * (float) modificationCount / ((float) parentModificationCount - 1f));
    }
    LOGWRAPPER.debug("ITEM: " + pIndex);
    LOGWRAPPER.debug("modificationCount: " + modificationCount);
    LOGWRAPPER.debug("parentModificationCount: " + parentModificationCount);
    LOGWRAPPER.debug("descendantCount: " + descendantCount);
    LOGWRAPPER.debug("parentDescCount: " + parentDescCount);
    LOGWRAPPER.debug("indexToParent: " + indexToParent);
    LOGWRAPPER.debug("extension: " + extension);
    LOGWRAPPER.debug("depth: " + depth);
    LOGWRAPPER.debug("next Depth: " + nextDepth);
    LOGWRAPPER.debug("angle: " + angle);
    if (mPrune == Pruning.ITEMSIZE && extension < TraverseModel.ANGLE_TO_PRUNE && modificationCount <= descendantCount) {
        nodePruned();
    } else {
        // Add a sunburst item.
        if (mPrune == Pruning.DIFF && diffCont.getDiff() == DiffType.SAMEHASH) {
            mIsPruned = true;
        } else {
            mIsPruned = false;
        }
        final NodeReadTrx rtx = (diffCont.getDiff() == DiffType.DELETED || diffCont.getDiff() == DiffType.MOVEDFROM || diffCont.getDiff() == DiffType.REPLACEDOLD) ? mOldRtx : mNewRtx;
        final EStructType structKind = nextDepth > depth ? EStructType.ISINNERNODE : EStructType.ISLEAFNODE;
        // Set node relations.
        String text = "";
        NodeRelations relations = null;
        final DiffType currDiff = diffCont.getDiff();
        if (rtx.getKind() == Kind.TEXT) {
            if (currDiff == DiffType.DELETED || currDiff == DiffType.MOVEDFROM || currDiff == DiffType.REPLACEDOLD) {
                text = mOldRtx.getValue();
            } else {
                text = mNewRtx.getValue();
            }
            if (currDiff == DiffType.UPDATED || ((currDiff == DiffType.REPLACEDNEW || currDiff == DiffType.REPLACEDOLD) && mOldRtx.getKind() == mNewRtx.getKind())) {
                final String oldValue = mOldRtx.getValue();
                final String newValue = mNewRtx.getValue();
                float similarity = 1;
                // try {
                // Integer.parseInt(oldValue);
                // Integer.parseInt(newValue);
                // 
                // // TODO: Implement similarity measure on numerical data (easy!).
                // } catch (final NumberFormatException e) {
                similarity = mLevenshtein.getSimilarity(oldValue, newValue);
                // }
                relations = new NodeRelations(origDepth, depth, structKind, similarity, 0, 1, indexToParent).setSubtract(subtract);
            } else if (currDiff == DiffType.SAME || currDiff == DiffType.SAMEHASH) {
                relations = new NodeRelations(origDepth, depth, structKind, 1, 0, 1, indexToParent).setSubtract(subtract);
            } else {
                relations = new NodeRelations(origDepth, depth, structKind, 0, 0, 1, indexToParent).setSubtract(subtract);
            }
        } else {
            if (mMaxDescendantCount == 0) {
                if (mPrune == Pruning.NO) {
                    try {
                        mMaxDescendantCount = mMaxDescendantCountFuture.get().getDescendants();
                    } catch (final InterruptedException | ExecutionException e) {
                        LOGWRAPPER.error(e.getMessage(), e);
                    }
                } else {
                    mMaxDescendantCount = mAxis.getDescendantCount();
                }
            }
            relations = new NodeRelations(origDepth, depth, structKind, descendantCount, 1, mMaxDescendantCount, indexToParent).setSubtract(subtract);
        }
        // Build item.
        final SunburstItem.Builder builder = new SunburstItem.Builder(mParent, angle, extension, relations, mDb, mGUI).setNodeKey(rtx.getNodeKey()).setKind(rtx.getKind()).setDiff(diffCont.getDiff());
        if (modificationCount > descendantCount) {
            final int diffCounts = (modificationCount - descendantCount) / TraverseModel.FACTOR;
            LOGWRAPPER.debug("modCount: " + diffCounts);
            builder.setModifications(diffCounts);
        }
        if (text.isEmpty()) {
            QNm name = null;
            if (diffCont.getDiff() == DiffType.DELETED || diffCont.getDiff() == DiffType.MOVEDFROM || diffCont.getDiff() == DiffType.REPLACEDOLD) {
                name = mOldRtx.getName();
                builder.setAttributes(fillAttributes(mOldRtx));
                builder.setNamespaces(fillNamespaces(mOldRtx));
                builder.setOldKey(mOldRtx.getNodeKey());
                LOGWRAPPER.debug("name: " + name.getLocalName());
                builder.setOldQName(name);
            } else {
                name = mNewRtx.getName();
                builder.setAttributes(fillAttributes(mNewRtx));
                builder.setNamespaces(fillNamespaces(mNewRtx));
                LOGWRAPPER.debug("name: " + name.getLocalName());
                builder.setQName(name);
            }
        } else {
            LOGWRAPPER.debug("text: " + text);
            if (currDiff == DiffType.DELETED || currDiff == DiffType.MOVEDFROM || currDiff == DiffType.REPLACEDOLD) {
                builder.setOldText(text);
                builder.setOldKey(mOldRtx.getNodeKey());
            } else {
                builder.setText(text);
            }
        }
        updated(diffCont.getDiff(), builder);
        final SunburstItem item = builder.build();
        if (item.getDiff() == DiffType.MOVEDFROM) {
            LOGWRAPPER.debug("movedToIndex: " + diffCont.getIndex());
            item.setIndexMovedTo(diffCont.getIndex() - mAxis.getPrunedNodes());
        }
        mItems.add(item);
        // Set depth max.
        mNewDepthMax = Math.max(depth, mNewDepthMax);
    }
    return extension;
}
Also used : DiffTuple(org.sirix.diff.DiffTuple) NodeRelations(org.sirix.gui.view.sunburst.NodeRelations) DiffType(org.sirix.diff.DiffFactory.DiffType) QNm(org.brackit.xquery.atomic.QNm) NodeReadTrx(org.sirix.api.NodeReadTrx) SunburstItem(org.sirix.gui.view.sunburst.SunburstItem) EStructType(org.sirix.gui.view.sunburst.SunburstItem.EStructType) ExecutionException(java.util.concurrent.ExecutionException)

Example 10 with DiffType

use of org.sirix.diff.DiffFactory.DiffType in project sirix by sirixdb.

the class Modifications method countDiffs.

/**
 * Count how many differences in the subtree exists and add descendant-or-self
 * count.
 *
 * @return number of differences and descendants
 * @throws SirixException
 *           if sirix can't close the transaction
 */
public Modification countDiffs() throws SirixException {
    int index = mIndex;
    final DiffTuple diffCont = mDiffs.get(index);
    final DiffType diff = diffCont.getDiff();
    final int rootDepth = (diff == DiffType.DELETED || diff == DiffType.MOVEDFROM || diff == DiffType.REPLACEDOLD) ? diffCont.getDepth().getOldDepth() : diffCont.getDepth().getNewDepth();
    int diffCounts = 0;
    int descendantCounts = 1;
    boolean subtract = false;
    diffCounts = incrDiffCounter(index, diffCounts);
    index++;
    if (diffCounts == 1 && index < mDiffs.size()) {
        final DiffTuple cont = mDiffs.get(index);
        final int depth = (cont.getDiff() == DiffType.DELETED || cont.getDiff() == DiffType.MOVEDFROM || cont.getDiff() == DiffType.REPLACEDOLD) ? cont.getDepth().getOldDepth() : cont.getDepth().getNewDepth();
        if (depth == rootDepth + 1) {
            // Current node is modified and has at least one child.
            subtract = true;
        }
    }
    boolean done = false;
    while (!done && index < mDiffs.size()) {
        final DiffTuple currDiffCont = mDiffs.get(index);
        final DiffType currDiff = currDiffCont.getDiff();
        final DiffDepth currDepth = currDiffCont.getDepth();
        final int depth = (currDiff == DiffType.DELETED || currDiff == DiffType.MOVEDFROM || currDiff == DiffType.REPLACEDOLD) ? currDepth.getOldDepth() : currDepth.getNewDepth();
        if (depth <= rootDepth) {
            done = true;
        }
        if (!done) {
            descendantCounts++;
            if (currDiff != DiffType.SAME && currDiff != DiffType.SAMEHASH) {
                diffCounts++;
            }
            index++;
        }
    }
    // Add a factor to add some weighting to the diffCounts.
    return new Modification(TraverseModel.FACTOR * diffCounts, descendantCounts, subtract);
}
Also used : DiffTuple(org.sirix.diff.DiffTuple) DiffType(org.sirix.diff.DiffFactory.DiffType) DiffDepth(org.sirix.diff.DiffDepth)

Aggregations

DiffType (org.sirix.diff.DiffFactory.DiffType)11 DiffTuple (org.sirix.diff.DiffTuple)7 DiffDepth (org.sirix.diff.DiffDepth)4 ExecutionException (java.util.concurrent.ExecutionException)2 DatabaseException (com.sleepycat.je.DatabaseException)1 QNm (org.brackit.xquery.atomic.QNm)1 NodeReadTrx (org.sirix.api.NodeReadTrx)1 SirixException (org.sirix.exception.SirixException)1 NodeRelations (org.sirix.gui.view.sunburst.NodeRelations)1 SunburstItem (org.sirix.gui.view.sunburst.SunburstItem)1 EStructType (org.sirix.gui.view.sunburst.SunburstItem.EStructType)1