Commit 03be6a78 authored by David Novak's avatar David Novak
Browse files

* delete operation now returns the list of not-deleted objects

* fixed a bug in delete operation (if two objects with the very same PPP were to be deleted, only the latter was actually deleted)
parent 1ea17b77
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@

    <groupId>mindex</groupId>
    <artifactId>ppp-codes</artifactId>
    <version>1.3.2-DEVEL</version>
    <version>1.3.4-DEVEL</version>
    <packaging>jar</packaging>

    <name>ppp-codes</name>
+2 −2
Original line number Diff line number Diff line
@@ -104,9 +104,9 @@ public class PPPCodeInitializer extends MIndexStdInitializer {
    public LocalAbstractObject initPP(LocalAbstractObject object) throws AlgorithmMethodException {
        // fallback for the variant with internal ID-object refinement storage
        if (object.getObjectKey() instanceof IntegerKey) {
            return new PPPCodeObject(DiskStorageMemoryIntIndex.getIntegerID(object), getObjectPPP(object));
            return new PPPCodeObject(object.getObjectKey(), DiskStorageMemoryIntIndex.getIntegerID(object), getObjectPPP(object));
        }
        return new PPPCodeObject(convertor.getIntLocator(object.getLocatorURI()), getObjectPPP(object));
        return new PPPCodeObject(object.getObjectKey(), convertor.getIntLocator(object.getLocatorURI()), getObjectPPP(object));
    }
    
}
+55 −13
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -32,7 +33,6 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import messif.algorithms.AlgorithmMethodException;
import messif.objects.util.AbstractObjectIterator;
import messif.operations.QueryOperation;
@@ -204,6 +204,9 @@ public class PPPCodeLeafCell extends VoronoiLeafCell<PPPCodeObject> implements M
                calculateBranching(objectsToInsert, myLevel), myLevel);
        
        int retVal = (data != null) ? data.length : (maxCapacity / INIT_SIZE_COEF);
        if (retVal <= 0) {
            return bytesToCarry;
        }
        while (retVal < bytesToCarry) {
            retVal = (int) (retVal * ARRAY_INCREMENT_COEF);
            if ((retVal > maxCapacity) && (myLevel < mIndex.getMaxLevel())) {
@@ -461,6 +464,8 @@ public class PPPCodeLeafCell extends VoronoiLeafCell<PPPCodeObject> implements M
                mIndex.getMaxLevel() - thisLevel, calculator, thisLevel);
    }    
    
    // **************     Handling of delete operation      *********************** //
    
    /**
     * Deletes given object from this leaf according to locator (ID).
     * @param objects to be deleted
@@ -470,17 +475,9 @@ public class PPPCodeLeafCell extends VoronoiLeafCell<PPPCodeObject> implements M
     * @throws AlgorithmMethodException 
     */
    @Override
    public synchronized int deleteObjects(List<PPPCodeObject> objects, int deleteLimit, boolean checkLocator) throws AlgorithmMethodException {
        Map<ShortArray,Set<Integer>> locatorsToDelete = new HashMap<>(objects.size());
        // the sent object can theoretically contain more than one locator
        for (PPPCodeObject object : objects) {
            Set<Integer> hashSet = new HashSet<>(objects.size());
            for (int loc : object.getLocators()) {
                hashSet.add(loc);
            }
            locatorsToDelete.put(new ShortArray(
                    Arrays.copyOfRange(object.getPppForReading(), getLevel(), object.getPPPLength())), hashSet);
        }
    public synchronized Collection<PPPCodeObject> deleteObjects(List<PPPCodeObject> objects, int deleteLimit, boolean checkLocator) throws AlgorithmMethodException {
        // create a map between the PPPs and sets of locators to be deleted for each of the PPP
        Map<ShortArray,Set<Integer>> locatorsToDelete = initPPPLocatorMap(objects);

        int actuallyDeleted = 0;
        boolean allDeleted = false;
@@ -493,7 +490,30 @@ public class PPPCodeLeafCell extends VoronoiLeafCell<PPPCodeObject> implements M
            }            
        }
        objectCount -= actuallyDeleted;
        return actuallyDeleted;
        
        return findNotDeletedObjects(locatorsToDelete, objects);
    }

    /**
     * Initializes and returns a map of {@link ShortArray}-encoded PPPs with respective
     *  integer-encoded IDs for given objects.
     */
    private Map<ShortArray, Set<Integer>> initPPPLocatorMap(List<PPPCodeObject> objects) {
        Map<ShortArray,Set<Integer>> locatorsToDelete = new HashMap<>(objects.size());
        // the sent object can theoretically contain more than one locator
        for (PPPCodeObject object : objects) {
            ShortArray pppArray = new ShortArray(Arrays.copyOfRange(object.getPppForReading(),
                    getLevel(), object.getPPPLength()));
            Set<Integer> locators = locatorsToDelete.get(pppArray);
            if (locators == null) {
                locators = new HashSet<>(objects.size());
                locatorsToDelete.put(pppArray, locators);
            }
            for (int loc : object.getLocators()) {
                locators.add(loc);
            }
        }
        return locatorsToDelete;
    }

    private int findAndMarkForDelete(Map<ShortArray, Set<Integer>> locatorsToDelete) throws IllegalArgumentException {
@@ -556,6 +576,28 @@ public class PPPCodeLeafCell extends VoronoiLeafCell<PPPCodeObject> implements M
        }
    }
    
    /** 
     * Given a list map of not-deleted PPPs+IDs, this method finds corresponding PPPCOdeObjects from
     *  within the given list.
     */
    private Collection<PPPCodeObject> findNotDeletedObjects(Map<ShortArray, Set<Integer>> locatorsToDelete, List<PPPCodeObject> objects) {
        if (locatorsToDelete.isEmpty()) {
            return Collections.emptyList();
        }
        // return the not deleted objects
        Collection<PPPCodeObject> notDeleted = new ArrayList<>();
        for (Set<Integer> notDeletedIDs : locatorsToDelete.values()) {
            for (PPPCodeObject obj : objects) {
                for (int id : obj.getLocators()) {
                    if (notDeletedIDs.contains(id)) {
                        notDeleted.add(obj);
                        break;
                    }
                }
            }
        }
        return notDeleted;
    }
    
    /**
     * Filters out the deleted locators out from given object with locators. 
+13 −14
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.util.Arrays;
import messif.objects.LocalAbstractObject;
import messif.objects.keys.AbstractObjectKey;

/**
 * This object represents a single pivot permutation prefix of an object according to
@@ -43,20 +44,6 @@ public class PPPCodeObject extends LocalAbstractObject {
    
    // ***************** Constructors *****************//
    
//    /**
//     * Creates new Encrypted object from existing "standard" metric object;
//     *  all filters, keys and locator are copied (not cloned!). 
//     *   TODO: copy also parameters (parametric) ? add "cloneAccessories" parameter ?
//     */
//    public PPPCodeObject(LocalAbstractObject originalObject, MIndexPP mindexPP) {
//        super(originalObject.getObjectKey());
//        this.locators = new int [] {MetricIndexes.getIntegerID(originalObject)};
//        this.ppp = new short[mindexPP.getMaxLevel()];
//        for (short i = 0; i < ppp.length; i++) {            
//            this.ppp[i] = (short) mindexPP.getPivotIndex((short) (i+1));
//        }
//    }

    /**
     * Creates new PPPCode object from given integer locator and PPP. THe past PPP is not cloned.
     * @param locator as integer
@@ -67,6 +54,18 @@ public class PPPCodeObject extends LocalAbstractObject {
        this.ppp = ppp;
    }

    /**
     * Creates new PPPCode object from given integer locator and PPP. THe past PPP is not cloned.
     * @param originalKey original key (locator) to be passed to {@link LocalAbstractObject}
     * @param locator as integer
     * @param ppp pivot permutation prefix
     */
    public PPPCodeObject(AbstractObjectKey originalKey, int locator, final short [] ppp) {
        super(originalKey);
        this.locators = new int [] {locator};
        this.ppp = ppp;
    }
    
    /**
     * Creates a single PPPCode object given a list of lists of IDs to be stored in this new object.
     * @param locatorDoubleArray list of lists of IDs to be stored in this new object
+2 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package pppcodes.index.persistent;
import java.io.IOException;
import java.io.ObjectStreamException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
@@ -120,7 +121,7 @@ public class PPPCodeLeafCellFile extends PPPCodeLeafCell {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
        @Override
        public int deleteObjects(List<PPPCodeObject> objects, int deleteLimit, boolean checkLocator) throws AlgorithmMethodException {
        public Collection<PPPCodeObject> deleteObjects(List<PPPCodeObject> objects, int deleteLimit, boolean checkLocator) throws AlgorithmMethodException {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
        @Override