/**
   * two nodes, my is unmodified, their is updated and has a higher version => their version is
   * going to be the merged version
   */
  @Test
  public void nodeSimple_locallyUnmodifiedNoConflict() {
    Node n = new Node(new LatLon(0, 0));
    n.setOsmId(1, 1);
    n.setModified(false);
    n.put("key1", "value1");
    my.addPrimitive(n);

    Node n1 = new Node(new LatLon(0, 0));
    n1.setOsmId(1, 2);
    n1.setModified(false);
    n1.put("key1", "value1-new");
    n1.put("key2", "value2");
    their.addPrimitive(n1);

    DataSetMerger visitor = new DataSetMerger(my, their);
    visitor.merge();

    Node n2 = (Node) my.getPrimitiveById(1, OsmPrimitiveType.NODE);
    assertTrue(visitor.getConflicts().isEmpty());
    assertSame(n, n2); // make sure the merged node is still the original node
    assertSame(n2.getDataSet(), my);
    assertEquals(1, n2.getId());
    assertEquals(2, n2.getVersion());
    assertFalse(n2.isModified());
    assertEquals("value1-new", n2.get("key1"));
    assertEquals("value2", n2.get("key2"));

    // the merge target should not be modified
    assertFalse(n2.isModified());
  }
  /**
   * Node with same id, my is modified, their has a higher version => results in a conflict
   *
   * <p>Use case: node which is modified locally and updated by another mapper on the server
   */
  @Test
  public void nodeSimple_TagConflict() {
    Node n = new Node(new LatLon(0, 0));
    n.setOsmId(1, 1);
    n.setModified(true);
    n.put("key1", "value1");
    n.put("key2", "value2");
    my.addPrimitive(n);

    Node n1 = new Node(new LatLon(0, 0));
    n1.setOsmId(1, 2);
    n1.setModified(false);
    n1.put("key1", "value1-new");

    their.addPrimitive(n1);

    DataSetMerger visitor = new DataSetMerger(my, their);
    visitor.merge();

    Node n2 = (Node) my.getPrimitiveById(1, OsmPrimitiveType.NODE);
    assertEquals(1, visitor.getConflicts().size());
    assertSame(n, n2);
    assertNotSame(n1, n2);
    assertSame(n1.getDataSet(), their);
  }
 // no concurrent read/write is assumed
 public V put(double key, V value) {
   if (value == null) throw new NullPointerException();
   // not incrementing b's refcnt, so need not release it.
   Node b = skipListMap.findGrandPredecessor(key);
   if (b == null) b = head;
   Node n = b.next;
   if (n == null) {
     n = Node.alloc();
     n.put(key, value, this);
     n.next = null;
     b.next = n;
     return null;
   }
   Node f = n.next;
   if (f == null) { // put (key,value) into node n
     Object val = n.put(key, value, this);
     return (V) val;
   } else {
     assert f.len() > 0 && f.first() >= key;
     if (f.first() == key) {
       Object val = f.put(key, value, this);
       return (V) val;
     } else {
       Object val = n.put(key, value, this);
       return (V) val;
     }
   }
 }
  /**
   * two identical nodes, even in id and version. No confict expected.
   *
   * <p>Can happen if data is loaded in two layers and then merged from one layer on the other.
   */
  @Test
  public void nodeSimple_IdenticalNoConflict() {
    Node n = new Node(new LatLon(0, 0));
    n.setOsmId(1, 1);
    n.setModified(false);
    n.put("key1", "value1");
    my.addPrimitive(n);

    Node n1 = new Node(new LatLon(0, 0));
    n1.setOsmId(1, 1);
    n1.setModified(false);
    n1.put("key1", "value1");
    their.addPrimitive(n1);

    DataSetMerger visitor = new DataSetMerger(my, their);
    visitor.merge();

    Node n2 = (Node) my.getPrimitiveById(1, OsmPrimitiveType.NODE);
    assertTrue(visitor.getConflicts().isEmpty());
    assertNotSame(n1, n2); // make sure we have a clone
    assertEquals(1, n2.getId());
    assertEquals(1, n2.getVersion());
    assertFalse(n2.isModified());
    assertEquals("value1", n2.get("key1"));

    // merge target not modified after merging
    assertFalse(n2.isModified());
  }
Example #5
0
  /**
   * Test hasEqualSemanticAttributes on two nodes whose identical tags are added in different
   * orders.
   */
  public void testHasEqualSemanticAttributes() {
    Node n1 = new Node(1);
    n1.setCoor(new LatLon(0, 0));
    n1.put("key.1", "value.1");
    n1.put("key.2", "value.2");

    Node n2 = new Node(1);
    n2.setCoor(new LatLon(0, 0));
    n2.put("key.2", "value.2");
    n2.put("key.1", "value.1");

    assertTrue(n1.hasEqualSemanticAttributes(n2));
  }
Example #6
0
  @SuppressWarnings("unchecked")
  @Override
  public <E extends Entry<K, V>> E put(E entry) {
    if (entry.getKey() == null) {
      return updateNullEntry(entry);
    }

    if (entry.getValue() == null) {
      return remove(entry.getKey());
    }

    Object result = root.put(conf, entry);
    if (result == null) {
      this.size++;
      return null;
    }
    if (result instanceof Split) {
      Split<K, V> split = (Split<K, V>) result;
      this.root = new InnerNode<K, V>(conf, root, split.getKey(), split.getGreater());
      this.size++;
      return null;
    } else {
      return (E) result;
    }
  }
Example #7
0
  /** Remove all tags from a node */
  public void testRemoveAll() {
    Node n = new Node();

    n.put("key.1", "value.1");
    n.put("key.2", "value.2");

    n.removeAll();
    assertTrue(n.getKeys().size() == 0);
  }
  /**
   * their way has a higher version and different nodes. My way is modified.
   *
   * <p>=> merge onto my way not possible, create a conflict
   */
  @Test
  public void waySimple_DifferentNodesAndMyIsModified() {

    // -- the target dataset

    Node n1 = new Node(new LatLon(0, 0));
    n1.setOsmId(1, 1);
    my.addPrimitive(n1);

    Node n2 = new Node(new LatLon(1, 1));
    n2.setOsmId(2, 1);
    my.addPrimitive(n2);

    Way myWay = new Way();
    myWay.setOsmId(3, 1);

    myWay.addNode(n1);
    myWay.addNode(n2);
    myWay.setModified(true);
    myWay.put("key1", "value1");
    my.addPrimitive(myWay);

    // -- the source dataset

    Node n3 = new Node(new LatLon(0, 0));
    n3.setOsmId(1, 1);
    their.addPrimitive(n3);

    Node n5 = new Node(new LatLon(1, 1));
    n5.setOsmId(4, 1);
    their.addPrimitive(n5);

    Node n4 = new Node(new LatLon(2, 2));
    n4.setOsmId(2, 1);
    n4.put("key1", "value1");
    their.addPrimitive(n4);

    Way theirWay = new Way();
    theirWay.setOsmId(3, 2);

    theirWay.addNode(n3);
    theirWay.addNode(n5); // insert a node
    theirWay.addNode(n4); // this one is updated
    their.addPrimitive(theirWay);

    DataSetMerger visitor = new DataSetMerger(my, their);
    visitor.merge();

    Way merged = (Way) my.getPrimitiveById(3, OsmPrimitiveType.WAY);
    assertEquals(1, visitor.getConflicts().size());
    assertEquals(3, merged.getId());
    assertEquals(1, merged.getVersion());
    assertEquals(2, merged.getNodesCount());
    assertEquals(1, merged.getNode(0).getId());
    assertEquals(2, merged.getNode(1).getId());
    assertEquals("value1", merged.get("key1"));
  }
Example #9
0
  /** Add a tag to an empty node and test the query and get methods. */
  public void testPut() {
    Node n = new Node();
    n.put("akey", "avalue");
    assertTrue(n.get("akey").equals("avalue"));
    assertTrue(n.getKeys().size() == 1);

    assertTrue(n.keySet().size() == 1);
    assertTrue(n.keySet().contains("akey"));
  }
Example #10
0
 /** Add two tags to an empty node and test the query and get methods. */
 public void testPut2() {
   Node n = new Node();
   n.put("key.1", "value.1");
   n.put("key.2", "value.2");
   assertTrue(n.get("key.1").equals("value.1"));
   assertTrue(n.get("key.2").equals("value.2"));
   assertTrue(n.getKeys().size() == 2);
   assertTrue(n.hasKeys());
   assertTrue(n.hasKey("key.1"));
   assertTrue(n.hasKey("key.2"));
   assertTrue(!n.hasKey("nosuchkey"));
 }
Example #11
0
 private void addChild(Node<K, V> node, Node<K, V> child) {
   if (child.getType() == NodeType.LEAF) {
     LeafNode leaf = (LeafNode) child;
     for (int i = 0; i < leaf.size(); i++) {
       node.put((K) leaf.getKeys().get(i), (V) leaf.getValues().get(i));
     }
   } else if (child.getType() == NodeType.GUIDE) {
     GuideNode guide = (GuideNode) child;
     for (int i = 0; i < guide.size(); i++) {
       addChild(node, (Node<K, V>) guide.getKids().get(i));
     }
   }
 }
    // concurrent read/write access is allowed
    boolean appendNewAtomic(double key, Object value, ConcurrentDoubleOrderedListMap orderedMap) {
      synchronized (this) {
        if (isMarked()) return false;
        if (next != null) return false;

        Node n = Node.alloc();
        n.put(key, value, orderedMap);
        // assert n.len()==1;
        n.next = null;
        boolean success = casNext(null, n);
        assert success;
        return true;
      }
    }
  /**
   * their node has no assigned id (id == 0) and is semantically equal to one of my nodes with id ==
   * 0
   *
   * <p>=> merge it onto my node.
   */
  @Test
  public void nodeSimple_NoIdSemanticallyEqual() {

    Calendar cal = GregorianCalendar.getInstance();
    User myUser = User.createOsmUser(1111, "my");

    User theirUser = User.createOsmUser(222, "their");

    Node n = new Node();
    n.setCoor(new LatLon(0, 0));
    n.put("key1", "value1");
    n.setUser(myUser);
    n.setTimestamp(cal.getTime());

    my.addPrimitive(n);

    Node n1 = new Node();
    n1.setCoor(new LatLon(0, 0));
    n1.put("key1", "value1");
    cal.add(Calendar.HOUR, 1);
    Date timestamp = cal.getTime();
    n1.setTimestamp(timestamp);
    n1.setUser(theirUser);
    their.addPrimitive(n1);

    DataSetMerger visitor = new DataSetMerger(my, their);
    visitor.merge();

    Node n2 = my.getNodes().iterator().next();
    assertEquals(0, visitor.getConflicts().size());
    assertEquals("value1", n2.get("key1"));
    assertEquals(n1.getRawTimestamp(), n2.getRawTimestamp());
    assertEquals(theirUser, n2.getUser());
    assertSame(n2, n);
    assertNotSame(n2, n1);
    assertSame(n2.getDataSet(), my);
  }
Example #14
0
  @Override
  public InsertionResult put(Key key, Value value) {
    int i = keys().insertionPoint(key);
    if (i < 0) {
      i = -i;
    }
    Node node = children.resolve(i);
    InsertionResult result = node.put(key, value);

    if (getParent().isNull()) {
      return new InsertionResult(this.getNodeRef(), result.didUpdate);
    }

    return new InsertionResult(getParent(), result.didUpdate);
  }
Example #15
0
    @Override
    public Object put(Comparator comparator, Object key, Object val) {
      Node node = findNode(comparator, key);

      Object oldVal = node.put(comparator, key, val);

      if (isSplit(oldVal)) {
        Node nextNode = node.next();
        Object keyForNextNode = nextNode.firstKey();

        if (size == capacity) {
          splitBranch(comparator, keyForNextNode, nextNode);
        } else {
          insertNode(comparator, keyForNextNode, nextNode);
          oldVal = null;
        }
      }

      return oldVal;
    }
Example #16
0
  @SuppressWarnings("unchecked")
  public V put(K key, V val) {
    if (key == null || val == null) {
      throw new NullPointerException("Keys and values may not be null");
    }

    Object o = root.put(comparator, key, val);

    if (isSplit(o)) {
      Node next = root.next();
      root = Branch.newInstance(root, next, nodeSize);

      o = null;
    }

    if (null == o) {
      size++;
    }

    return (V) o;
  }
Example #17
0
  /** Remove tags from a node with two tags and test the state of the node. */
  public void testRemove() {
    Node n = new Node();
    n.put("key.1", "value.1");
    n.put("key.2", "value.2");

    n.remove("nosuchkey"); // should work
    assertTrue(n.getKeys().size() == 2); // still 2 tags ?

    n.remove("key.1");
    assertTrue(n.getKeys().size() == 1);
    assertTrue(!n.hasKey("key.1"));
    assertTrue(n.get("key.1") == null);
    assertTrue(n.hasKey("key.2"));
    assertTrue(n.get("key.2").equals("value.2"));

    n.remove("key.2");
    assertTrue(n.getKeys().size() == 0);
    assertTrue(!n.hasKey("key.1"));
    assertTrue(n.get("key.1") == null);
    assertTrue(!n.hasKey("key.2"));
    assertTrue(n.get("key.2") == null);
  }
  /**
   * my node is incomplete, their node is complete
   *
   * <p>=> merge it onto my node. My node becomes complete
   */
  @Test
  public void nodeSimple_IncompleteNode() {

    Node n = new Node(1);
    my.addPrimitive(n);

    Node n1 = new Node();
    n1.setCoor(new LatLon(0, 0));
    n1.setOsmId(1, 1);
    n1.put("key1", "value1");
    Date timestamp = new Date();
    n1.setTimestamp(timestamp);
    their.addPrimitive(n1);

    DataSetMerger visitor = new DataSetMerger(my, their);
    visitor.merge();

    Node n2 = my.getNodes().iterator().next();
    assertEquals(0, visitor.getConflicts().size());
    assertEquals("value1", n2.get("key1"));
    assertEquals(n1.getRawTimestamp(), n2.getRawTimestamp());
    assertFalse(n2.isIncomplete());
    assertSame(n2, n);
  }
    // no concurrent read/write access is assumed
    private void putReally(
        int pos, double key, Object value, ConcurrentDoubleOrderedListMap orderedMap) {
      int len = len();
      if (len + 1 <= keys.length) { // inserted in the current node
        nodeCopy(keys, vals, pos, keys, vals, pos + 1, len - pos);
        keys[pos] = key;
        vals[pos] = value;
        length = len + 1;
        if (pos == 0) {
          orderedMap.skipListMap.put(keys[0], this);
          if (len != 0) orderedMap.skipListMap.remove(keys[1], this);
        }
      } else if (emptySlotInNextTwo()) {
        if (pos == len) {
          next.put(key, value, orderedMap);
          return;
        }
        next.put(keys[len - 1], vals[len - 1], orderedMap);
        nodeCopy(keys, vals, pos, keys, vals, pos + 1, len - pos - 1);
        keys[pos] = key;
        vals[pos] = value;
        if (pos == 0) {
          orderedMap.skipListMap.remove(keys[1], this);
          orderedMap.skipListMap.put(keys[0], this);
        }
      } else { // current node is full, so requires a new node
        Node n = Node.alloc();
        double[] nkeys = n.keys;
        Object[] nvals = n.vals;
        int l1 = len / 2, l2 = len - l1;
        if (next == null && pos == len) { // this is the last node, simply add to the new node.
          nkeys[0] = key;
          nvals[0] = value;
          n.length = 1;
          orderedMap.skipListMap.put(nkeys[0], n);
        } else if (pos < l1) { // key,value is stored in the current node
          length = l1 + 1;
          n.length = l2;
          nodeCopy(keys, vals, l1, nkeys, nvals, 0, l2);

          nodeCopy(keys, vals, pos, keys, vals, pos + 1, l1 - pos);
          keys[pos] = key;
          vals[pos] = value;
          if (pos == 0) {
            orderedMap.skipListMap.remove(keys[1]);
            orderedMap.skipListMap.put(keys[0], this);
          }
          orderedMap.skipListMap.put(nkeys[0], n);
        } else { // key,value is stored in the new node
          length = l1;
          n.length = l2 + 1;
          int newpos = pos - l1;

          nodeCopy(keys, vals, l1, nkeys, nvals, 0, newpos);
          nkeys[newpos] = key;
          nvals[newpos] = value;
          nodeCopy(keys, vals, pos, nkeys, nvals, newpos + 1, l2 - newpos);

          orderedMap.skipListMap.put(nkeys[0], n);
        }
        n.next = this.next;
        this.next = n;
      }
    }
  /**
   * their way has a higher version and different tags. And it has more nodes. Two of the existing
   * nodes are modified.
   *
   * <p>=> merge it onto my way, no conflict
   */
  @Test
  public void waySimple_AdditionalNodesAndChangedNodes() {

    // -- my data set

    Node n1 = new Node(new LatLon(0, 0));
    n1.setOsmId(1, 1);
    my.addPrimitive(n1);

    Node n2 = new Node(new LatLon(1, 1));
    n2.setOsmId(2, 1);
    my.addPrimitive(n2);

    Way myWay = new Way();
    myWay.setOsmId(3, 1);
    myWay.addNode(n1);
    myWay.addNode(n2);
    my.addPrimitive(myWay);

    // --- their data set

    Node n3 = new Node(new LatLon(0, 0));
    n3.setOsmId(1, 1);
    their.addPrimitive(n3);

    Node n5 = new Node(new LatLon(1, 1));
    n5.setOsmId(4, 1);

    their.addPrimitive(n5);

    Node n4 = new Node(new LatLon(2, 2));
    n4.setOsmId(2, 2);
    n4.put("key1", "value1");
    their.addPrimitive(n4);

    Way theirWay = new Way();
    theirWay.setOsmId(3, 2);
    theirWay.addNode(n3);
    theirWay.addNode(n5); // insert a node
    theirWay.addNode(n4); // this one is updated
    their.addPrimitive(theirWay);

    DataSetMerger visitor = new DataSetMerger(my, their);
    visitor.merge();

    // -- tests
    Way merged = (Way) my.getPrimitiveById(3, OsmPrimitiveType.WAY);
    assertEquals(0, visitor.getConflicts().size());
    assertEquals(3, merged.getId());
    assertEquals(2, merged.getVersion());
    assertEquals(3, merged.getNodesCount());
    assertEquals(1, merged.getNode(0).getId());
    assertEquals(4, merged.getNode(1).getId());
    assertEquals(2, merged.getNode(2).getId());
    assertEquals("value1", merged.getNode(2).get("key1"));

    assertSame(merged.getNode(0), n1);
    assertNotSame(merged.getNode(1), n5); // must be clone of the original node in their
    assertSame(merged.getNode(2), n2);

    assertFalse(
        merged
            .isModified()); // the target wasn't modified before merging, it mustn't be after
                            // merging
  }