Commit 58480f47 authored by Vlastislav Dohnal's avatar Vlastislav Dohnal
Browse files

Object key is set to BucketInfoObjectKey when kNN query is evaluated to...

Object key is set to BucketInfoObjectKey when kNN query is evaluated to remember the time when the object was discovered and added to the answer.
parent 619fa30d
Loading
Loading
Loading
Loading
+38 −10
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import messif.objects.util.AbstractObjectList;
import messif.objects.util.AbstractObjectIterator;
import messif.objects.LocalAbstractObject;
import messif.objects.PrecomputedDistancesFixedArrayFilter;
import messif.objects.keys.BucketInfoObjectKey;
import messif.objects.util.RankedAbstractObject;
import messif.objects.util.StreamGenericAbstractObjectIterator;
import messif.operations.AnswerType;
@@ -1945,13 +1946,18 @@ public class MTree extends Algorithm implements Serializable, SplittableAlgorith
//            kNNOper.addToAnswer(it.next());
//        int added = 0;
        String[] postState = getObjectLocators(kNNOper);
        final int[] indexesOfNew = getNewObjects(preState, postState);
        
        final int bucketID = node.getBucket().getBucketID();
        statVisitedLeaves.add();
        final long bucketAccessOrderNo = statVisitedLeaves.get();
        markAnswerObjectsWithBucketAccessNo(kNNOper, indexesOfNew, bucketID, (int)bucketAccessOrderNo);
        
        statOptimIndexObjSum.add(added * added);
        statOptimIndexObjCntPerBucket.add(node.getBucket().getBucketID(), added);
        statOptimIndexNewObjPerBucket.add(node.getBucket().getBucketID(), getNewObjects(preState, postState));
        statLeafNodeVisitedOrder.add(node.getBucket().getBucketID(), statVisitedLeaves.get());  // Set the ordinal number of accessing this bucket (statVisitedLeaves is zeroed before starting each operation)
        statDistanceToKNNCandidate.add(node.getBucket().getBucketID(), (long)(kNNOper.getAnswerDistance()*1000f));   // Distance to k-th nearest candidate
        statOptimIndexObjCntPerBucket.add(bucketID, added);
        statOptimIndexNewObjPerBucket.add(bucketID, indexesOfNew.length);
        statLeafNodeVisitedOrder.add(bucketID, bucketAccessOrderNo);  // Set the ordinal number of accessing this bucket (statVisitedLeaves is zeroed before starting each operation)
        statDistanceToKNNCandidate.add(bucketID, (long)(kNNOper.getAnswerDistance()*1000f));   // Distance to k-th nearest candidate
    }

    private String[] getObjectLocators(KNNQueryOperation kNNOper) {
@@ -1963,16 +1969,38 @@ public class MTree extends Algorithm implements Serializable, SplittableAlgorith
        return locs;
    }
    
    private int getNewObjects(String[] pre, String[] post) {
    /** @return list of indexes in the post array of locators that correspond to the newly added objects */
    private int[] getNewObjects(String[] pre, String[] post) {
        int[] idxs = new int[post.length];
        int diff = 0;
        int i = 0;
        int iPre = 0, iPost = 0;
        for (String po : post) {
            if (i < pre.length && po.equals(pre[i]))
                i++;
            else
            if (iPre < pre.length && po.equals(pre[iPre]))
                iPre++;
            else {
                idxs[diff] = iPost;
                diff++;
            }
        return diff;
            iPost++;
        }
        int[] idxsRes = new int[diff];
        if (diff > 0)
            System.arraycopy(idxs, 0, idxsRes, 0, diff);
        return idxsRes;
    }
    
    private void markAnswerObjectsWithBucketAccessNo(KNNQueryOperation kNNOper, int[] indexesOfNew, int bucketID, int bucketAccessOrderNo) {
        try {
        int i = 0, j = 0;
        for (Iterator<RankedAbstractObject> iterator = kNNOper.getAnswer(); iterator.hasNext(); i++) {
            if (i == indexesOfNew[j]) {
                j++;
                AbstractObject o = iterator.next().getObject();
                o.setObjectKey(new BucketInfoObjectKey(o.getLocatorURI(), bucketID, bucketAccessOrderNo));
            }
        }
        } catch (ClassCastException e) {    // OK, we do not set anything
        }
    }

    /**