Home | History | Annotate | Download | only in impl
      1 /* GENERATED SOURCE. DO NOT MODIFY. */
      2 //  2016 and later: Unicode, Inc. and others.
      3 // License & terms of use: http://www.unicode.org/copyright.html#License
      4 /*
      5 **********************************************************************
      6 * Copyright (c) 2002-2010, International Business Machines
      7 * Corporation and others.  All Rights Reserved.
      8 **********************************************************************
      9 * Author: M. Davis
     10 * Created: December 2002 (moved from UnicodeSet)
     11 * Since: ICU 2.4
     12 **********************************************************************
     13 */
     14 package android.icu.impl;
     15 
     16 import java.util.Iterator;
     17 import java.util.SortedSet;
     18 import java.util.TreeSet;
     19 
     20 /**
     21  * Computationally efficient determination of the relationship between
     22  * two SortedSets.
     23  * @hide Only a subset of ICU is exposed in Android
     24  */
     25 public class SortedSetRelation {
     26 
     27     /**
     28      * The relationship between two sets A and B can be determined by looking at:
     29      * A - B
     30      * A & B (intersection)
     31      * B - A
     32      * These are represented by a set of bits.
     33      * Bit 2 is true if A - B is not empty
     34      * Bit 1 is true if A & B is not empty
     35      * BIT 0 is true if B - A is not empty
     36      */
     37     public static final int
     38         A_NOT_B = 4,
     39         A_AND_B = 2,
     40         B_NOT_A = 1;
     41 
     42     /**
     43      * There are 8 combinations of the relationship bits. These correspond to
     44      * the filters (combinations of allowed bits) in hasRelation. They also
     45      * correspond to the modification functions, listed in comments.
     46      */
     47     public static final int
     48        ANY =            A_NOT_B |   A_AND_B |   B_NOT_A,    // union,           addAll
     49        CONTAINS =       A_NOT_B |   A_AND_B,                // A                (unnecessary)
     50        DISJOINT =       A_NOT_B |               B_NOT_A,    // A xor B,         missing Java function
     51        ISCONTAINED =                A_AND_B |   B_NOT_A,    // B                (unnecessary)
     52        NO_B =           A_NOT_B,                            // A setDiff B,     removeAll
     53        EQUALS =                     A_AND_B,                // A intersect B,   retainAll
     54        NO_A =                                   B_NOT_A,    // B setDiff A,     removeAll
     55        NONE =           0,                                  // null             (unnecessary)
     56 
     57        ADDALL = ANY,                // union,           addAll
     58        A = CONTAINS,                // A                (unnecessary)
     59        COMPLEMENTALL = DISJOINT,    // A xor B,         missing Java function
     60        B = ISCONTAINED,             // B                (unnecessary)
     61        REMOVEALL = NO_B,            // A setDiff B,     removeAll
     62        RETAINALL = EQUALS,          // A intersect B,   retainAll
     63        B_REMOVEALL = NO_A;          // B setDiff A,     removeAll
     64 
     65 
     66     /**
     67      * Utility that could be on SortedSet. Faster implementation than
     68      * what is in Java for doing contains, equals, etc.
     69      * @param a first set
     70      * @param allow filter, using ANY, CONTAINS, etc.
     71      * @param b second set
     72      * @return whether the filter relationship is true or not.
     73      */
     74     public static <T extends Object & Comparable<? super T>> boolean hasRelation(SortedSet<T> a, int allow, SortedSet<T> b) {
     75         if (allow < NONE || allow > ANY) {
     76             throw new IllegalArgumentException("Relation " + allow + " out of range");
     77         }
     78 
     79         // extract filter conditions
     80         // these are the ALLOWED conditions Set
     81 
     82         boolean anb = (allow & A_NOT_B) != 0;
     83         boolean ab = (allow & A_AND_B) != 0;
     84         boolean bna = (allow & B_NOT_A) != 0;
     85 
     86         // quick check on sizes
     87         switch(allow) {
     88             case CONTAINS: if (a.size() < b.size()) return false; break;
     89             case ISCONTAINED: if (a.size() > b.size()) return false; break;
     90             case EQUALS: if (a.size() != b.size()) return false; break;
     91         }
     92 
     93         // check for null sets
     94         if (a.size() == 0) {
     95             if (b.size() == 0) return true;
     96             return bna;
     97         } else if (b.size() == 0) {
     98             return anb;
     99         }
    100 
    101         // pick up first strings, and start comparing
    102         Iterator<? extends T> ait = a.iterator();
    103         Iterator<? extends T> bit = b.iterator();
    104 
    105         T aa = ait.next();
    106         T bb = bit.next();
    107 
    108         while (true) {
    109             int comp = aa.compareTo(bb);
    110             if (comp == 0) {
    111                 if (!ab) return false;
    112                 if (!ait.hasNext()) {
    113                     if (!bit.hasNext()) return true;
    114                     return bna;
    115                 } else if (!bit.hasNext()) {
    116                     return anb;
    117                 }
    118                 aa = ait.next();
    119                 bb = bit.next();
    120             } else if (comp < 0) {
    121                 if (!anb) return false;
    122                 if (!ait.hasNext()) {
    123                     return bna;
    124                 }
    125                 aa = ait.next();
    126             } else  {
    127                 if (!bna) return false;
    128                 if (!bit.hasNext()) {
    129                     return anb;
    130                 }
    131                 bb = bit.next();
    132             }
    133         }
    134     }
    135 
    136     /**
    137      * Utility that could be on SortedSet. Allows faster implementation than
    138      * what is in Java for doing addAll, removeAll, retainAll, (complementAll).
    139      * @param a first set
    140      * @param relation the relation filter, using ANY, CONTAINS, etc.
    141      * @param b second set
    142      * @return the new set
    143      */
    144     public static <T extends Object & Comparable<? super T>> SortedSet<? extends T> doOperation(SortedSet<T> a, int relation, SortedSet<T> b) {
    145         // TODO: optimize this as above
    146         TreeSet<? extends T> temp;
    147         switch (relation) {
    148             case ADDALL:
    149                 a.addAll(b);
    150                 return a;
    151             case A:
    152                 return a; // no action
    153             case B:
    154                 a.clear();
    155                 a.addAll(b);
    156                 return a;
    157             case REMOVEALL:
    158                 a.removeAll(b);
    159                 return a;
    160             case RETAINALL:
    161                 a.retainAll(b);
    162                 return a;
    163             // the following is the only case not really supported by Java
    164             // although all could be optimized
    165             case COMPLEMENTALL:
    166                 temp = new TreeSet<T>(b);
    167                 temp.removeAll(a);
    168                 a.removeAll(b);
    169                 a.addAll(temp);
    170                 return a;
    171             case B_REMOVEALL:
    172                 temp = new TreeSet<T>(b);
    173                 temp.removeAll(a);
    174                 a.clear();
    175                 a.addAll(temp);
    176                 return a;
    177             case NONE:
    178                 a.clear();
    179                 return a;
    180             default:
    181                 throw new IllegalArgumentException("Relation " + relation + " out of range");
    182         }
    183     }
    184 }
    185