test_class.file: oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/ValueMapTest.java
test_class.identifier: ValueMapTest
test_case.body: @Test
      public void mergeSorted1() throws Exception {
          MemoryDocumentStore store = new MemoryDocumentStore();
          
          Revision r1 = new Revision(1, 0, 1); // prev2
          Revision r2 = new Revision(2, 0, 1); // prev2
          Revision r3 = new Revision(3, 0, 1); // root
          Revision r4 = new Revision(4, 0, 1); // prev2
          Revision r5 = new Revision(5, 0, 1); // prev1
          Revision r6 = new Revision(6, 0, 1); // root
          Revision r7 = new Revision(7, 0, 1); // prev1
  
          Range range1 = new Range(r7, r5, 0);
          Range range2 = new Range(r4, r1, 0);
          
          String prevId1 = Utils.getPreviousIdFor(ROOT, range1.high, 0);
          UpdateOp prevOp1 = new UpdateOp(prevId1, true);
          NodeDocument.setRevision(prevOp1, r5, "c");
          NodeDocument.setRevision(prevOp1, r7, "c");
  
          String prevId2 = Utils.getPreviousIdFor(ROOT, range2.high, 0);
          UpdateOp prevOp2 = new UpdateOp(prevId2, true);
          NodeDocument.setRevision(prevOp2, r1, "c");
          NodeDocument.setRevision(prevOp2, r2, "c");
          NodeDocument.setRevision(prevOp2, r4, "c");
  
          String rootId = Utils.getIdFromPath("/");
          UpdateOp op = new UpdateOp(rootId, true);
          NodeDocument.setRevision(op, r3, "c");
          NodeDocument.setRevision(op, r6, "c");
          NodeDocument.setPrevious(op, range1);
          NodeDocument.setPrevious(op, range2);
          
          store.create(NODES, Lists.newArrayList(op, prevOp1, prevOp2));
          
          NodeDocument doc = store.find(NODES, rootId);
          Iterators.size(doc.getValueMap(NodeDocument.REVISIONS).entrySet().iterator());
      }
test_case.class_method_signature: ValueMapTest.mergeSorted1()
test_case.full_signature: @Test public void mergeSorted1()
test_case.identifier: mergeSorted1
test_case.invocations: getPreviousIdFor setRevision setRevision getPreviousIdFor setRevision setRevision setRevision getIdFromPath setRevision setRevision setPrevious setPrevious create newArrayList find size iterator entrySet getValueMap
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void mergeSorted1()
focal_class.declarator: EMPTY = Collections.unmodifiableSortedMap(
              new TreeMap<Revision, String>(StableRevisionComparator.REVERSE))
focal_class.modifier: static final
focal_class.original_string: static final SortedMap<Revision, String> EMPTY = Collections.unmodifiableSortedMap(
              new TreeMap<Revision, String>(StableRevisionComparator.REVERSE));
focal_class.type: SortedMap<Revision, String>
focal_class.var_name: EMPTY
focal_class.file: oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/ValueMap.java
focal_class.identifier: ValueMap
focal_class.class_method_signature: ValueMap.create(@NotNull final NodeDocument doc,
                                          @NotNull final String property)
focal_class.full_signature: @NotNull static Map<Revision, String> create(@NotNull final NodeDocument doc,
                                          @NotNull final String property)
focal_class.identifier: create
focal_class.modifiers: @NotNull static
focal_class.parameters: (@NotNull final NodeDocument doc,
                                          @NotNull final String property)
focal_class.return: Map<Revision, String>
focal_class.signature: Map<Revision, String> create(@NotNull final NodeDocument doc,
                                          @NotNull final String property)
focal_method.body: @NotNull
      static Map<Revision, String> create(@NotNull final NodeDocument doc,
                                          @NotNull final String property) {
          final SortedMap<Revision, String> map = doc.getLocalMap(property);
          if (doc.getPreviousRanges().isEmpty()) {
              return map;
          }
          final Set<Map.Entry<Revision, String>> entrySet
                  = new AbstractSet<Map.Entry<Revision, String>>() {
  
              @Override
              @NotNull
              public Iterator<Map.Entry<Revision, String>> iterator() {
  
                  final Comparator<? super Revision> c = map.comparator();
                  final Iterator<NodeDocument> docs;
                  if (map.isEmpty()) {
                      docs = doc.getPreviousDocs(property, null).iterator();
                  } else {
                      // merge sort local map into maps of previous documents
                      List<Iterator<NodeDocument>> iterators = 
                              new ArrayList<Iterator<NodeDocument>>(2);
                      iterators.add(Iterators.singletonIterator(doc));
                      iterators.add(doc.getPreviousDocs(property, null).iterator());                            
                      docs = Iterators.mergeSorted(iterators, new Comparator<NodeDocument>() {
                                  @Override
                                  public int compare(NodeDocument o1,
                                                     NodeDocument o2) {
                                      Revision r1 = getFirstRevision(o1);
                                      Revision r2 = getFirstRevision(o2);
                                      return c.compare(r1, r2);
                                  }
                              
                                  private Revision getFirstRevision(NodeDocument d) {
                                      Map<Revision, String> values;
                                      if (Objects.equal(d.getId(), doc.getId())) {
                                          // return local map for main document
                                          values = d.getLocalMap(property);
                                      } else {
                                          values = d.getValueMap(property);
                                      }
                                      return values.keySet().iterator().next();
                                  }
                          
                              });
                  }
  
                  return new MergeSortedIterators<Map.Entry<Revision, String>>(
                          new Comparator<Map.Entry<Revision, String>>() {
                              @Override
                              public int compare(Map.Entry<Revision, String> o1,
                                                 Map.Entry<Revision, String> o2) {
                                  return c.compare(o1.getKey(), o2.getKey());
                              }
                          }
                  ) {
                      @Override
                      public Iterator<Map.Entry<Revision, String>> nextIterator() {
                          NodeDocument d = docs.hasNext() ? docs.next() : null;
                          if (d == null) {
                              return null;
                          }
                          Map<Revision, String> values;
                          if (Objects.equal(d.getId(), doc.getId())) {
                              // return local map for main document
                              values = d.getLocalMap(property);
                          } else {
                              values = d.getValueMap(property);
                          }
                          return values.entrySet().iterator();
                      }
  
                      @Override
                      public String description() {
                          return "Revisioned values for property " + doc.getId() + "/" + property + ":";
                      }
                  };
              }
  
              @Override
              public int size() {
                  int size = map.size();
                  for (NodeDocument prev : doc.getPreviousDocs(property, null)) {
                      size += prev.getValueMap(property).size();
                  }
                  return size;
              }
          };
  
          return new AbstractMap<Revision, String>() {
  
              private final Map<Revision, String> map = doc.getLocalMap(property);
  
              @Override
              @NotNull
              public Set<Entry<Revision, String>> entrySet() {
                  return entrySet;
              }
  
              @Override
              public String get(Object key) {
                  Revision r = (Revision) key;
                  // first check values map of this document
                  if (map.containsKey(r)) {
                      return map.get(r);
                  }
                  for (NodeDocument prev : doc.getPreviousDocs(property, r)) {
                      String value = prev.getValueMap(property).get(r);
                      if (value != null) {
                          return value;
                      }
                  }
                  // not found or null
                  return null;
              }
  
              @Override
              public boolean containsKey(Object key) {
                  // check local map first
                  if (map.containsKey(key)) {
                      return true;
                  }
                  Revision r = (Revision) key;
                  for (NodeDocument prev : doc.getPreviousDocs(property, r)) {
                      if (prev.getValueMap(property).containsKey(key)) {
                          return true;
                      }
                  }
                  return false;
              }
          };
      }
focal_method.class_method_signature: ValueMap.create(@NotNull final NodeDocument doc,
                                          @NotNull final String property)
focal_method.full_signature: @NotNull static Map<Revision, String> create(@NotNull final NodeDocument doc,
                                          @NotNull final String property)
focal_method.identifier: create
focal_method.invocations: getLocalMap isEmpty getPreviousRanges comparator isEmpty iterator getPreviousDocs add singletonIterator add iterator getPreviousDocs mergeSorted getFirstRevision getFirstRevision compare equal getId getId getLocalMap getValueMap next iterator keySet compare getKey getKey hasNext next equal getId getId getLocalMap getValueMap iterator entrySet getId size getPreviousDocs size getValueMap getLocalMap containsKey get getPreviousDocs get getValueMap containsKey getPreviousDocs containsKey getValueMap
focal_method.modifiers: @NotNull static
focal_method.parameters: (@NotNull final NodeDocument doc,
                                          @NotNull final String property)
focal_method.return: Map<Revision, String>
focal_method.signature: Map<Revision, String> create(@NotNull final NodeDocument doc,
                                          @NotNull final String property)