All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mycore.datamodel.common.MCRMarkManager Maven / Gradle / Ivy

There is a newer version: 2024.05
Show newest version
/*
 * This file is part of ***  M y C o R e  ***
 * See http://www.mycore.de/ for details.
 *
 * MyCoRe is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * MyCoRe is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MyCoRe.  If not, see .
 */

package org.mycore.datamodel.common;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.mycore.common.events.MCREventHandler;
import org.mycore.datamodel.metadata.MCRBase;
import org.mycore.datamodel.metadata.MCRDerivate;
import org.mycore.datamodel.metadata.MCRObjectID;

/**
 * Experimental class to improve performance on delete and import operations.
 * You can mark object's as "will be deleted" or "will be imported". You can
 * use this information on {@link MCREventHandler}'s to exclude those
 * marked objects from operations which makes no sense.
 *
 * 

* Current delete behavior: *

*
    *
  1. An user delete's a parent object with 500 children.
  2. *
  3. MyCoRe tries to delete the parent, but first, it has to delete all children.
  4. *
  5. MyCoRe runs through each child and deletes it.
  6. *
  7. BUT after the deletion of ONE child, the parent object will be updated.
  8. *
  9. This results in updating the parent 500 times, before its actually deleted.
  10. *
* *

* What this class tries to solve:
* We mark the parent as "will be deleted". When a child is deleted, and the EventHandler tries * to removed the child from its parent, the parent will not be updated because its "marked as * deleted". *

* *

* Current import behavior: *

* *
    *
  1. An import is started with a bunch of hierarchic objects.
  2. *
  3. MyCoRe imports all the objects and does a "create" update.
  4. *
  5. BUT for each object created the parent is updated again (because a child was added)!
  6. *
  7. This results in unnecessary updates.
  8. *
* *

* What this class tries to solve:
* We mark all objects as "will be imported". On import, we ignore all solr index call for * those objects. After the import, we delete all marks and do an solr import for all * objects at once. *

* * TODO: check side effects * * @author Matthias Eichner */ public class MCRMarkManager { private static MCRMarkManager INSTANCE = null; public enum Operation { DELETE, IMPORT } private Map marks; private MCRMarkManager() { this.marks = new ConcurrentHashMap<>(); } /** * Returns the instance to the singleton {@link MCRMarkManager}. * * @return instance of {@link MCRMarkManager} */ public static MCRMarkManager instance() { if (INSTANCE == null) { // make it thread safe synchronized (MCRMarkManager.class) { if (INSTANCE == null) { INSTANCE = new MCRMarkManager(); } } } return INSTANCE; } /** * Marks a single object with the given operation. * * @param mcrId the mycore object identifier * @param operation the operation * @return the previous Operation associated with the mycore identifier or null */ public Operation mark(MCRObjectID mcrId, Operation operation) { return this.marks.put(mcrId, operation); } /** * Removes the current mark for the given mycore identifier. * * @param mcrId the object where the mark should be removed */ public void remove(MCRObjectID mcrId) { this.marks.remove(mcrId); } /** * Checks if the object is marked. * * @param mcrId the mcr identifier * @return true if its marked */ public boolean isMarked(MCRObjectID mcrId) { return this.marks.containsKey(mcrId); } /** * Checks if the given base object is marked. If base is an instance of MCRDerivate, this method checks also if the * linked object is marked. * * @param base the mycore object * @return true if its marked */ public boolean isMarked(MCRBase base) { if (base instanceof MCRDerivate) { MCRDerivate derivate = (MCRDerivate) base; return isMarked(derivate.getId()) || isMarked(derivate.getOwnerID()); } return isMarked(base.getId()); } /** * Checks if the object is marked for deletion. * * @param mcrId the mcr identifier * @return true if its marked for deletion */ public boolean isMarkedForDeletion(MCRObjectID mcrId) { return Operation.DELETE.equals(this.marks.get(mcrId)); } /** * Checks if the derivate or the corresponding mycore object is * marked for deletion. * * @return true if one of them is marked for deletion */ public boolean isMarkedForDeletion(MCRDerivate derivate) { return isMarkedForDeletion(derivate.getId()) || isMarkedForDeletion(derivate.getOwnerID()); } /** * Checks if the object is marked for import. * * @param mcrId the mcr identifier * @return true if its marked for import */ public boolean isMarkedForImport(MCRObjectID mcrId) { return Operation.IMPORT.equals(this.marks.get(mcrId)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy