@Override public final synchronized void addRemoveStatements(Collection<Statement> added,Collection<Statement> removed) throws IOException {
  MapOfListMaps<Resource,String,Statement> rsAdded=new MapOfListMaps<Resource,String,Statement>();
  MapOfListMaps<Resource,String,Statement> rsRemoved=new MapOfListMaps<Resource,String,Statement>();
  HashSet<Resource> resources=new HashSet<Resource>();
  for (  Statement s : added) {
    rsAdded.add(s.getSubject(),SearchFields.getContextID(s.getContext()),s);
    resources.add(s.getSubject());
  }
  for (  Statement s : removed) {
    rsRemoved.add(s.getSubject(),SearchFields.getContextID(s.getContext()),s);
    resources.add(s.getSubject());
  }
  logger.debug("Removing " + removed.size() + " statements, adding "+ added.size()+ " statements");
  BulkUpdater updater=newBulkUpdate();
  for (  Resource resource : resources) {
    Map<String,List<Statement>> stmtsToRemove=rsRemoved.get(resource);
    Map<String,List<Statement>> stmtsToAdd=rsAdded.get(resource);
    Set<String> contextsToUpdate=new HashSet<String>(stmtsToAdd.keySet());
    contextsToUpdate.addAll(stmtsToRemove.keySet());
    Map<String,SearchDocument> docsByContext=new HashMap<String,SearchDocument>();
    String resourceId=SearchFields.getResourceID(resource);
    Iterable<? extends SearchDocument> documents=getDocuments(resourceId);
    for (    SearchDocument doc : documents) {
      docsByContext.put(doc.getContext(),doc);
    }
    for (    String contextId : contextsToUpdate) {
      String id=SearchFields.formIdString(resourceId,contextId);
      SearchDocument document=docsByContext.get(contextId);
      if (document == null) {
        document=newDocument(id,resourceId,contextId);
        List<Statement> list=stmtsToAdd.get(contextId);
        if (list != null) {
          for (          Statement s : list) {
            addProperty(s,document);
          }
        }
        updater.add(document);
        if (stmtsToRemove.containsKey(contextId))         logger.info("Statements are marked to be removed that should not be in the store, for resource {} and context {}. Nothing done.",resource,contextId);
      }
 else {
        Map<String,Set<String>> removedOfResource=null;
{
          List<Statement> removedStatements=stmtsToRemove.get(contextId);
          if (removedStatements != null && !removedStatements.isEmpty()) {
            removedOfResource=new HashMap<String,Set<String>>();
            for (            Statement r : removedStatements) {
              String val=SearchFields.getLiteralPropertyValueAsString(r);
              if (val != null) {
                String field=SearchFields.getPropertyField(r.getPredicate());
                Set<String> removedValues=removedOfResource.get(field);
                if (removedValues == null) {
                  removedValues=new HashSet<String>();
                  removedOfResource.put(field,removedValues);
                }
                removedValues.add(val);
              }
            }
          }
        }
        SearchDocument newDocument=newDocument(id,resourceId,contextId);
        boolean mutated=copyDocument(newDocument,document,removedOfResource);
{
          List<Statement> addedToResource=stmtsToAdd.get(contextId);
          String val;
          if (addedToResource != null && !addedToResource.isEmpty()) {
            PropertyCache propertyCache=new PropertyCache(newDocument);
            for (            Statement s : addedToResource) {
              val=SearchFields.getLiteralPropertyValueAsString(s);
              if (val != null) {
                String field=SearchFields.getPropertyField(s.getPredicate());
                if (!propertyCache.hasProperty(field,val)) {
                  addProperty(s,newDocument);
                  mutated=true;
                }
              }
            }
          }
        }
        int nrProperties=countPropertyValues(newDocument);
        if (nrProperties > 0) {
          if (mutated) {
            updater.update(newDocument);
          }
        }
 else {
          updater.delete(document);
        }
      }
    }
  }
  updater.end();
}

@ Override public final synchronized void addRemoveStatements ( Collection < Statement > added , Collection < Statement > removed ) throws IOException { MapOfListMaps < Resource , String , Statement > rsAdded = new MapOfListMaps < Resource , String , Statement > ( ) ; MapOfListMaps < Resource , String , Statement > rsRemoved = new MapOfListMaps < Resource , String , Statement > ( ) ; HashSet < Resource > resources = new HashSet < Resource > ( ) ; for ( Statement s : added ) { rsAdded . add ( s . getSubject ( ) , SearchFields . getContextID ( s . getContext ( ) ) , s ) ; resources . add ( s . getSubject ( ) ) ; } for ( Statement s : removed ) { rsRemoved . add ( s . getSubject ( ) , SearchFields . getContextID ( s . getContext ( ) ) , s ) ; resources . add ( s . getSubject ( ) ) ; } logger . debug ( "Removing " + removed . size ( ) + " statements, adding " + added . size ( ) + " statements" ) ; BulkUpdater updater = newBulkUpdate ( ) ; for ( Resource resource : resources ) { Map < String , List < Statement > > stmtsToRemove = rsRemoved . get ( resource ) ; Map < String , List < Statement > > stmtsToAdd = rsAdded . get ( resource ) ; Set < String > contextsToUpdate = new HashSet < String > ( stmtsToAdd . keySet ( ) ) ; contextsToUpdate . addAll ( stmtsToRemove . keySet ( ) ) ; Map < String , SearchDocument > docsByContext = new HashMap < String , SearchDocument > ( ) ; String resourceId = SearchFields . getResourceID ( resource ) ; Iterable < ? extends SearchDocument > documents = getDocuments ( resourceId ) ; for ( SearchDocument doc : documents ) { docsByContext . put ( doc . getContext ( ) , doc ) ; } for ( String contextId : contextsToUpdate ) { String id = SearchFields . formIdString ( resourceId , contextId ) ; SearchDocument document = docsByContext . get ( contextId ) ; if ( document == null ) { document = newDocument ( id , resourceId , contextId ) ; List < Statement > list = stmtsToAdd . get ( contextId ) ; if ( list != null ) { for ( Statement s : list ) { addProperty ( s , document ) ; } } updater . add ( document ) ; if ( stmtsToRemove . containsKey ( contextId ) ) logger . info ( "Statements are marked to be removed that should not be in the store, for resource {} and context {}. Nothing done." , resource , contextId ) ; } else { Map < String , Set < String > > removedOfResource = null ; { List < Statement > removedStatements = stmtsToRemove . get ( contextId ) ; if ( removedStatements != null && ! removedStatements . isEmpty ( ) ) { removedOfResource = new HashMap < String , Set < String > > ( ) ; for ( Statement r : removedStatements ) { String val = SearchFields . getLiteralPropertyValueAsString ( r ) ; if ( val != null ) { String field = SearchFields . getPropertyField ( r . getPredicate ( ) ) ; Set < String > removedValues = removedOfResource . get ( field ) ; if ( removedValues == null ) { removedValues = new HashSet < String > ( ) ; removedOfResource . put ( field , removedValues ) ; } removedValues . add ( val ) ; } } } } SearchDocument newDocument = newDocument ( id , resourceId , contextId ) ; boolean mutated = copyDocument ( newDocument , document , removedOfResource ) ; { List < Statement > addedToResource = stmtsToAdd . get ( contextId ) ; String val ; if ( addedToResource != null && ! addedToResource . isEmpty ( ) ) { PropertyCache propertyCache = new PropertyCache ( newDocument ) ; for ( Statement s : addedToResource ) { val = SearchFields . getLiteralPropertyValueAsString ( s ) ; if ( val != null ) { String field = SearchFields . getPropertyField ( s . getPredicate ( ) ) ; if ( ! propertyCache . hasProperty ( field , val ) ) { addProperty ( s , newDocument ) ; mutated = true ; } } } } } int nrProperties = countPropertyValues ( newDocument ) ; if ( nrProperties > 0 ) { if ( mutated ) { updater . update ( newDocument ) ; } } else { updater . delete ( document ) ; } } } } updater . end ( ) ; }
add many statements at the same time , remove many statements at the same time . ordering by resource has to be done inside this method . the passed added / removed sets are disjunct , no statement can be in both
