protected void inheritMerged(HierNode<T> x) {
   BitSet mask = new BitSet(x.getBitMask() != null ? x.getBitMask().length() : 1);
   for (HierNode<T> p : x.getParents()) {
     mask.or(p.getBitMask());
   }
   updateMask(x, mask);
 }
 protected void resolveConflicts(HierNode<T> x) {
   boolean conflicted = false;
   Collection<HierNode<T>> nodes = new ArrayList<HierNode<T>>(getNodes());
   for (HierNode<T> y : nodes) {
     if (incomparable(x, y)) {
       //                System.out.println( " \t\tIncomparability between " + x + " and " + y );
       int sup = superset(y, x);
       if (sup == 0) {
         // System.out.println( " \t\tIncomparable, with same mask " + y );
         // can't use update mask here, or the already existing node would be removed
         x.setBitMask(increment(x.getBitMask(), freeBit(x)));
         propagate(y, freeBit(x, y));
       }
       if (sup > 0) {
         //                    System.out.println( " \t\tIncomparable, but as parent " + y );
         updateMask(x, increment(x.getBitMask(), freeBit(x)));
       }
       int sub = superset(x, y);
       if (sub > 0) {
         //                    System.out.println( " \t\tIncomparable, but as child " + y );
         modify(x, y);
         conflicted = true;
       }
     }
   }
   if (conflicted) {
     inheritMerged(x);
     resolveConflicts(x);
   }
 }
 // Debug only
 List<T> ancestorValues(T name) {
   List<T> anx = new ArrayList<T>();
   Set<HierNode<T>> nodes = ancestorNodes(getNode(name));
   for (HierNode<T> node : nodes) {
     anx.add(node.getValue());
   }
   return anx;
 }
 protected void updateMask(HierNode<T> node, BitSet mask) {
   boolean in = node.getBitMask() != null && contains(node);
   if (in) {
     remove(node);
   }
   node.setBitMask(mask);
   if (in) {
     add(node);
   }
 }
  protected Set<HierNode<T>> gcs(Set<HierNode<T>> set) {
    Set<HierNode<T>> s = new HashSet<HierNode<T>>();

    Iterator<HierNode<T>> iter = set.iterator();
    BitSet a = new BitSet(this.size());
    a.or(iter.next().getBitMask());
    while (iter.hasNext()) {
      a.and(iter.next().getBitMask());
    }
    // System.out.println( "Root mask for ceil " + toBinaryString( a ) );
    for (HierNode<T> node : getNodes()) {
      if (superset(node.getBitMask(), a) >= 0) {
        s.add(node);
      }
    }

    Set<HierNode<T>> cl = ceil(s);
    return cl;
  }
  public BitSet encode(T member, Collection<T> parents) {
    BitSet existing = getCode(member);
    if (existing != null) {
      return existing;
    }

    HierNode<T> node = new HierNode<T>(member);

    Set<HierNode<T>> parentNodes = floor(parents);

    for (HierNode<T> parentNode : parentNodes) {
      node.addParent(parentNode);
      parentNode.addChild(node);
    }
    encode(node);

    add(node);

    return node.getBitMask();
  }
  protected int freeBit(HierNode<T> x, HierNode<T> z) {
    // System.out.println( "Looking for a free bit in node " + x );
    BitSet forbid = new BitSet(this.size());
    forbid.or(x.getBitMask());
    for (HierNode<T> y : getNodes()) {

      if (superset(y, x) > 0) {
        // System.out.println( "\t\t Subtype " + y + " contributes " + toBinaryString(
        // y.getBitMask() ) );
        forbid.or(y.getBitMask());
      }

      if (z != null) {
        if (superset(y, z) > 0) {
          //                  System.out.println( "\t\t Subtype " + y + " contributes " +
          // toBinaryString( y.getBitMask() ) );
          forbid.or(y.getBitMask());
        }
      }

      if (superset(x, y) < 0) {
        BitSet diff = singleBitDiff(x.getBitMask(), y.getBitMask());
        // System.out.println( "\t\t Incomparable " + y + " contributes " + toBinaryString( diff )
        // );
        forbid.or(diff);
      }
    }
    // System.out.println( "\t Forbidden mask " + toBinaryString( forbid ) );
    return firstZero(forbid);
  }
 @Override
 protected void add(HierNode<T> node) {
   super.add(node);
   bottom.merge(node.getBitMask());
 }
 protected void propagate(HierNode<T> y, int bit) {
   Set<HierNode<T>> descendants = descendantNodes(y);
   for (HierNode<T> s : descendants) {
     updateMask(s, increment(s.getBitMask(), bit));
   }
 }
示例#10
0
  protected void modify(HierNode<T> x, HierNode<T> y) {
    // System.out.println( "Modifying on a inc between " + x + " and " + y );

    int i = freeBit(x, y);
    // System.out.println( "I " + i );

    // System.out.println( "Getting parents of " + y + " >> " + y.getParents() );
    Collection<HierNode<T>> py = y.getParents();
    BitSet t = new BitSet(y.getBitMask().length());
    for (HierNode<T> parent : py) {
      t.or(parent.getBitMask());
    }

    BitSet d = singleBitDiff(t, y.getBitMask());
    int inDex = d.nextSetBit(0);

    if (inDex < 0) {
      propagate(y, i);
    } else {

      // System.out.println( "D " + toBinaryString( d ) );

      Set<HierNode<T>> ancestors = ancestorNodes(x);
      Set<HierNode<T>> affectedAncestors = new HashSet<HierNode<T>>();

      for (HierNode<T> anc : ancestors) {
        if (anc.getBitMask().get(inDex)) {
          affectedAncestors.add(anc);
        }
      }
      // System.out.println( "Ancestors of " + x + " >> " + ancestors );
      // System.out.println( "Affected " + x + " >> " + affectedAncestors );

      if (affectedAncestors.size() == 0) {
        return;
      }

      Set<HierNode<T>> gcs = gcs(affectedAncestors);
      // System.out.println( "GCS of Affected " + gcs );

      Set<HierNode<T>> affectedDescendants = new HashSet<HierNode<T>>();
      for (HierNode<T> g : gcs) {
        affectedDescendants.addAll(descendantNodes(g));
      }
      affectedDescendants.remove(x); // take x out it's not yet in the set

      int dx = firstOne(d);

      if (bottom.get(i)) {
        i = freeBit(new HierNode<T>(bottom));
      }

      for (HierNode<T> sub : affectedDescendants) {

        boolean keepsBit = false;
        for (HierNode<T> sup : sub.getParents()) {
          if (!keepsBit && !affectedDescendants.contains(sup) && sup.getBitMask().get(inDex)) {
            keepsBit = true;
          }
        }
        BitSet subMask = sub.getBitMask();
        if (!keepsBit) {
          subMask = decrement(subMask, dx);
        }
        subMask = increment(subMask, i);

        updateMask(sub, subMask);

        // System.out.println( "\tModified Desc" + sub );
      }

      inDex = d.nextSetBit(inDex + 1);
    }
  }
示例#11
0
  protected void encode(HierNode<T> node) {
    Collection<HierNode<T>> parents = node.getParents();
    // System.out.println( "Trying to encode " + node );
    switch (parents.size()) {
      case 0:
        BitSet zero = new BitSet();

        if (hasKey(zero)) {
          HierNode root = getNodeByKey(zero);

          if (root.getValue() != null) {
            fixedRoot = true;
            HierNode previousRoot = root;
            root = new HierNode((Object) null);
            root.addChild(previousRoot);
            previousRoot.addParent(root);

            root.setBitMask(zero);

            propagate(previousRoot, freeBit(root));
            add(root);
          }

          node.addParent(root);
          updateMask(node, increment(root.getBitMask(), freeBit(root)));

        } else {
          updateMask(node, new BitSet());
        }
        break;
      case 1:
        HierNode<T> parent = parents.iterator().next();
        updateMask(node, increment(parent.getBitMask(), freeBit(parent)));
        break;
      default:
        inheritMerged(node);
        // System.out.println( "
        // -----------------------------------------------------------------------------------------
        // " );
        resolveConflicts(node);
        break;
    }
  }