Beispiel #1
0
 private void applyToBag(VersionedRepo rp, String cRef, DocumentBagObject dObj) {
   for (Map.Entry<String, String> d : dObj.getDocRefs().entrySet()) {
     boolean found = false;
     for (DocumentBagReference bagRef2 : shadow.getDocuments()) {
       DocumentBagObject dObj2 = rp.getObjectDatabase().getDocumentBag(bagRef2.getBagRef());
       if (dObj2.getDocRefs().containsKey(d.getKey())) {
         if (!dObj2.getDocRefs().get(d.getKey()).equals(d.getValue())) {
           // Here we have to see what we prefer - the target
           // could
           // have moved this document forward and
           // that is why they are different. OR we could have
           // moved it forward. Who wins? How do we know
           // whether
           // this document was modified here? - perhaps we add
           // the
           // commit to the BaseObject
           found = true;
           DocumentObject dob = rp.getObjectDatabase().getDocument(d.getValue());
           if (cRef.equals(dob.getCommitRef())) {
             stagedDocuments.put(d.getKey(), rp.getObjectDatabase().getDocument(d.getValue()));
           }
         }
       }
     }
     if (!found) {
       stagedDocuments.put(d.getKey(), rp.getObjectDatabase().getDocument(d.getValue()));
     }
   }
 }
Beispiel #2
0
 private void workOutCommitChanges(
     VersionedRepo rp,
     Set<DocumentBagObject> needToSave,
     Map<String, DocumentBagObject> maybeReuse,
     Set<String> refsToSave) {
   for (DocumentBagReference docRef : shadow.getDocuments()) {
     refsToSave.add(docRef.getBagRef());
     DocumentBagObject dbo = rp.getObjectDatabase().getDocumentBag(docRef.getBagRef());
     boolean changed = false;
     for (String key : stagedDocuments.keySet()) {
       if (dbo.getDocRefs().containsKey(key)) {
         // We need to be saving this back
         dbo.getDocRefs().remove(key);
         needToSave.add(dbo);
         refsToSave.remove(docRef.getBagRef());
         changed = true;
         break;
       }
     }
     for (String rem : removedDocuments) {
       if (dbo.getDocRefs().containsKey(rem)) {
         dbo.getDocRefs().remove(rem);
         refsToSave.remove(docRef.getBagRef());
         needToSave.add(dbo);
         changed = true;
       }
     }
     if (!changed) {
       if (dbo.getDocRefs().size() < capacity) {
         maybeReuse.put(docRef.getBagRef(), dbo);
         refsToSave.remove(docRef.getBagRef());
       }
     }
   }
 }
Beispiel #3
0
  /**
   * Commit the changes made on this stage to the repo, returning the reference for the TreeObject
   * we will save for this.
   *
   * @param rp
   * @param commitRef
   * @return @
   */
  public String commitStage(
      VersionedRepo rp,
      String commitRef,
      CommitCollector collector,
      Map<DocumentObject, String> savedDocRefs) {
    // We create a new tree
    TreeObject newTreeObject = new TreeObject();
    // We need to work out a new document bag structure, by removing and
    // resaving any document bags that have had
    // items removed... We then add back any documents back into the bags
    // that have room

    Set<DocumentBagObject> needToSave = new HashSet<DocumentBagObject>();
    Map<String, DocumentBagObject> maybeReuse = new HashMap<String, DocumentBagObject>();
    Set<String> refsToSave = new HashSet<String>();

    workOutCommitChanges(rp, needToSave, maybeReuse, refsToSave);
    applyNewSaves(newTreeObject, refsToSave);

    // For the ones in needToSave, we can use them to hopefully fill a gap

    Map<String, DocumentObject> combinedSet = rebalanceTree();

    for (Map.Entry<String, DocumentObject> entries : combinedSet.entrySet()) {

      // If the document is already in the savedDocRefs, we don't need to
      // save it, we should simply get the reference
      // from that
      String reference = null;
      if (savedDocRefs.containsKey(entries.getValue())) {
        reference = savedDocRefs.get(entries.getValue());
      } else {
        entries.getValue().setCommitRef(commitRef);
        reference = rp.getObjectDatabase().writeDocument(entries.getValue());
        savedDocRefs.put(entries.getValue(), reference);
      }

      collector.addDocReference(reference);
      collector.addDocName(entries.getKey());

      // Find a spot to put this reference in
      boolean done = false;

      for (DocumentBagObject d : needToSave) {
        if (d.getDocRefs().size() < capacity) {
          d.getDocRefs().put(entries.getKey(), reference);
          done = true;
          break;
        }
      }
      if (!done && maybeReuse.size() != 0) {
        Map.Entry<String, DocumentBagObject> d = maybeReuse.entrySet().iterator().next();
        d.getValue().getDocRefs().put(entries.getKey(), reference);
        needToSave.add(d.getValue());
        maybeReuse.remove(d.getKey());
        done = true;
      }
      if (!done) {
        DocumentBagObject dNew = new DocumentBagObject();
        dNew.getDocRefs().put(entries.getKey(), reference);
        needToSave.add(dNew);
      }
    }

    // Add back those we didn't use
    for (String k : maybeReuse.keySet()) {
      if (!removedDocuments.contains(k)) {
        DocumentBagReference dr = new DocumentBagReference();
        dr.setBagRef(k);
        dr.setSize(maybeReuse.get(k).getDocRefs().size());
        newTreeObject.getDocuments().add(dr);
      }
    }

    // Now we need to save the need to save

    for (DocumentBagObject d : needToSave) {
      String reference = rp.getObjectDatabase().writeDocumentBag(d);
      DocumentBagReference dr = new DocumentBagReference();
      dr.setBagRef(reference);
      dr.setSize(d.getDocRefs().size());
      newTreeObject.getDocuments().add(dr);
    }

    newTreeObject.getTrees().putAll(shadow.getTrees());
    // Add the new ones, do the trees first
    for (Map.Entry<String, StageTree> entries : stagedTrees.entrySet()) {
      collector.enterFolder(entries.getKey());
      String reference = entries.getValue().commitStage(rp, commitRef, collector, savedDocRefs);
      collector.addTreeReference(reference);
      collector.leaveFolder();
      collector.addFolderName(entries.getKey());
      newTreeObject.getTrees().put(entries.getKey(), reference);
    }
    shadow = newTreeObject;
    reset();
    return rp.getObjectDatabase().writeTree(newTreeObject);
  }