예제 #1
0
  private static Ordering newObjectOrdering(boolean ascending) {
    if (ascending) {
      return Ordering.from(
          new Comparator<Comparable>() {
            @Override
            public int compare(@Nullable Comparable left, @Nullable Comparable right) {
              if (left == null) {
                return 1;
              }
              if (right == null) {
                return -1;
              }

              return left.compareTo(right);
            }
          });
    }
    return Ordering.from(
        new Comparator<Comparable>() {
          @Override
          public int compare(@Nullable Comparable left, @Nullable Comparable right) {
            if (left == null) {
              return 1;
            }
            if (right == null) {
              return -1;
            }

            return -left.compareTo(right);
          }
        });
  }
예제 #2
0
  /** Constructor */
  public TreeMapStore() {
    /*
     * For the start times index, the "key comparator" will compare the
     * start times as longs directly. This is the primary comparator for its
     * tree map.
     *
     * The secondary "value" comparator will check the end times first, and
     * in the event of a tie, defer to the ISegment's Comparable
     * implementation, a.k.a. its natural ordering.
     *
     * The same is done for the end times index, but swapping the first two
     * comparators instead.
     */
    fStartTimesIndex =
        checkNotNull(
            TreeMultimap.<Long, T>create(
                SegmentComparators.LONG_COMPARATOR,
                Ordering.from(SegmentComparators.INTERVAL_END_COMPARATOR)
                    .compound(Ordering.natural())));

    fEndTimesIndex =
        checkNotNull(
            TreeMultimap.<Long, T>create(
                SegmentComparators.LONG_COMPARATOR,
                Ordering.from(SegmentComparators.INTERVAL_START_COMPARATOR)
                    .compound(Ordering.natural())));

    fSize = 0;
  }
예제 #3
0
  public void testFrom() {
    Ordering<String> caseInsensitiveOrdering = Ordering.from(String.CASE_INSENSITIVE_ORDER);
    assertEquals(0, caseInsensitiveOrdering.compare("A", "a"));
    assertTrue(caseInsensitiveOrdering.compare("a", "B") < 0);
    assertTrue(caseInsensitiveOrdering.compare("B", "a") > 0);

    @SuppressWarnings("deprecation") // test of deprecated method
    Ordering<String> orderingFromOrdering = Ordering.from(Ordering.<String>natural());
    new EqualsTester()
        .addEqualityGroup(caseInsensitiveOrdering, Ordering.from(String.CASE_INSENSITIVE_ORDER))
        .addEqualityGroup(orderingFromOrdering, Ordering.natural())
        .testEquals();
  }
예제 #4
0
  @GET
  @Path("{userID}")
  @Produces({MediaType.TEXT_PLAIN, CSVMessageBodyWriter.TEXT_CSV, MediaType.APPLICATION_JSON})
  public List<IDValue> get(
      @PathParam("userID") String userID,
      @DefaultValue("10") @QueryParam("howMany") int howMany,
      @DefaultValue("0") @QueryParam("offset") int offset)
      throws OryxServingException {

    check(howMany > 0, "howMany must be positive");
    check(offset >= 0, "offset must be nonnegative");

    ALSServingModel model = getALSServingModel();
    float[] userVector = model.getUserVector(userID);
    checkExists(userVector != null, userID);
    List<Pair<String, float[]>> knownItemVectors = model.getKnownItemVectorsForUser(userID);
    if (knownItemVectors == null || knownItemVectors.isEmpty()) {
      return Collections.emptyList();
    }

    Iterator<Pair<String, Double>> idDots =
        knownItemVectors
            .stream()
            .map(
                itemIDVector ->
                    new Pair<>(
                        itemIDVector.getFirst(),
                        VectorMath.dot(userVector, itemIDVector.getSecond())))
            .iterator();
    Ordering<Pair<?, Double>> ordering =
        Ordering.from((p1, p2) -> p1.getSecond().compareTo(p2.getSecond()));
    return toIDValueResponse(ordering.leastOf(idDots, howMany + offset), howMany, offset);
  }
예제 #5
0
 /**
  * Returns a newly-created immutable bimap.
  *
  * @throws IllegalArgumentException if duplicate keys or values were added
  */
 @Override
 public ImmutableBiMap<K, V> build() {
   switch (size) {
     case 0:
       return of();
     case 1:
       return of(entries[0].getKey(), entries[0].getValue());
     default:
       /*
        * If entries is full, then this implementation may end up using the entries array
        * directly and writing over the entry objects with non-terminal entries, but this is
        * safe; if this Builder is used further, it will grow the entries array (so it can't
        * affect the original array), and future build() calls will always copy any entry
        * objects that cannot be safely reused.
        */
       if (valueComparator != null) {
         if (entriesUsed) {
           entries = Arrays.copyOf(entries, size);
         }
         Arrays.sort(
             entries,
             0,
             size,
             Ordering.from(valueComparator).onResultOf(Maps.<V>valueFunction()));
       }
       entriesUsed = size == entries.length;
       return RegularImmutableBiMap.fromEntryArray(size, entries);
   }
 }
예제 #6
0
 /** Returns a newly-created immutable multimap. */
 public ImmutableMultimap<K, V> build() {
   if (valueComparator != null) {
     for (Collection<V> values : builderMultimap.asMap().values()) {
       List<V> list = (List<V>) values;
       Collections.sort(list, valueComparator);
     }
   }
   if (keyComparator != null) {
     Multimap<K, V> sortedCopy = new BuilderMultimap<K, V>();
     List<Map.Entry<K, Collection<V>>> entries =
         Lists.newArrayList(builderMultimap.asMap().entrySet());
     Collections.sort(
         entries,
         Ordering.from(keyComparator)
             .onResultOf(
                 new Function<Entry<K, Collection<V>>, K>() {
                   @Override
                   public K apply(Entry<K, Collection<V>> entry) {
                     return entry.getKey();
                   }
                 }));
     for (Map.Entry<K, Collection<V>> entry : entries) {
       sortedCopy.putAll(entry.getKey(), entry.getValue());
     }
     builderMultimap = sortedCopy;
   }
   return copyOf(builderMultimap);
 }
예제 #7
0
 @Override
 Ordering sortFieldOrdering(boolean ascending) {
   Ordering<String> ordering = Ordering.from(String.CASE_INSENSITIVE_ORDER);
   if (!ascending) {
     ordering = ordering.reverse();
   }
   return ordering;
 }
  private synchronized void removeLeastRecentlyUsedCommand() {
    Ordering<String> ordering =
        Ordering.from(lastUsedComparator).onResultOf(Functions.forMap(this.hayStack));
    ImmutableSortedMap<String, CommandEntry> orderedHay =
        ImmutableSortedMap.copyOf(this.hayStack, ordering);
    String oldestKey = orderedHay.keySet().last();

    hayStack.remove(oldestKey);
  }
예제 #9
0
 /**
  * Returns a collection of multiset entries representing the counts of the distinct elements, in
  * sorted order. Does not check for null.
  */
 public static <E> Collection<Multiset.Entry<E>> sortedCounts(
     Comparator<? super E> comparator, Iterable<E> elements) {
   if (elements instanceof Multiset) {
     Multiset<E> multiset = (Multiset<E>) elements;
     if (hasSameComparator(comparator, elements)) {
       return multiset.entrySet();
     }
     List<Multiset.Entry<E>> entries = Lists.newArrayList(multiset.entrySet());
     Collections.sort(
         entries,
         Ordering.from(comparator)
             .onResultOf(
                 new Function<Multiset.Entry<E>, E>() {
                   @Override
                   public E apply(Entry<E> entry) {
                     return entry.getElement();
                   }
                 }));
     return entries;
   } else if (elements instanceof Set) { // known distinct
     Collection<E> sortedElements;
     if (hasSameComparator(comparator, elements)) {
       sortedElements = (Collection<E>) elements;
     } else {
       List<E> list = Lists.newArrayList(elements);
       Collections.sort(list, comparator);
       sortedElements = list;
     }
     return singletonEntries(sortedElements);
   } else if (hasSameComparator(comparator, elements)) {
     E current = null;
     int currentCount = 0;
     List<Multiset.Entry<E>> sortedEntries = Lists.newArrayList();
     for (E e : elements) {
       if (currentCount > 0) {
         if (comparator.compare(current, e) == 0) {
           currentCount++;
         } else {
           sortedEntries.add(Multisets.immutableEntry(current, currentCount));
           current = e;
           currentCount = 1;
         }
       } else {
         current = e;
         currentCount = 1;
       }
     }
     if (currentCount > 0) {
       sortedEntries.add(Multisets.immutableEntry(current, currentCount));
     }
     return sortedEntries;
   }
   TreeMultiset<E> multiset = TreeMultiset.create(comparator);
   Iterables.addAll(multiset, elements);
   return multiset.entrySet();
 }
예제 #10
0
 private static Iterable<Talk> sort(List<Talk> talks) {
   return Ordering.from(
           new Comparator<Talk>() {
             @Override
             public int compare(Talk talk1, Talk talk2) {
               return talk1.fromTime.compareTo(talk2.fromTime);
             }
           })
       .sortedCopy(talks);
 }
예제 #11
0
 @Test(groups = "ordering")
 public void testCompoundOrdering() {
   assertEquals(
       Ordering.from(new StarWarsCharacterYearComparator())
           .compound(new StarWarsCharacterNameComparator())
           .sortedCopy(
               Lists.newArrayList(bobaFett, princessLeia, landoCalrissian, lukeSkywalker, hanSolo))
           .toString(),
       "[Han Solo, Luke Skywalker, Princess Leia, " + "Boba Fett, Lando Calrissian]");
 }
예제 #12
0
 /**
  * The returned string comparator will show the most appropriate (closest) result first
  *
  * @return a string comparator based on the distance to the target string
  */
 public Ordering<String> comparator() {
   final Comparator<Integer> c =
       new Comparator<Integer>() {
         @Override
         public int compare(final Integer arg0, final Integer arg1) {
           return arg0.compareTo(arg1);
         }
       };
   return Ordering.from(c).onResultOf(distanceFunction(this.input));
 }
예제 #13
0
 public static Ordering<TaskAttemptInfo> orderingOnAllocationTime() {
   return Ordering.from(
       new Comparator<TaskAttemptInfo>() {
         @Override
         public int compare(TaskAttemptInfo o1, TaskAttemptInfo o2) {
           return (o1.getAllocationTime() < o2.getAllocationTime()
               ? -1
               : o1.getAllocationTime() > o2.getAllocationTime() ? 1 : 0);
         }
       });
 }
예제 #14
0
 @Override
 public ImmutableSortedMultiset<E> descendingMultiset() {
   ImmutableSortedMultiset<E> result = descendingMultiset;
   if (result == null) {
     return descendingMultiset =
         this.isEmpty()
             ? emptyMultiset(Ordering.from(comparator()).reverse())
             : new DescendingImmutableSortedMultiset<E>(this);
   }
   return result;
 }
예제 #15
0
 @Test(groups = "ordering")
 public void testBinarySearch() {
   StarWarsCharacterNameComparator starWarsCharacterNameComparator =
       new StarWarsCharacterNameComparator();
   StarWarsCharacter key = new StarWarsCharacter("Princess Leia", null);
   assertEquals(
       Ordering.from(starWarsCharacterNameComparator)
           .binarySearch(
               Arrays.asList(bobaFett, hanSolo, landoCalrissian, lukeSkywalker, princessLeia),
               key),
       4);
 }
예제 #16
0
  public void writeAnnotation(
      TypeKey annotationType, Collection<? extends AnnotationElement> elements) throws IOException {
    writer.writeEncodedValueHeader(ValueType.ANNOTATION, 0);
    writer.writeUleb128(typeSection.getItemIndex(annotationType));
    writer.writeUleb128(elements.size());

    Collection<? extends AnnotationElement> sortedElements =
        Ordering.from(BaseAnnotationElement.BY_NAME).immutableSortedCopy(elements);

    for (AnnotationElement element : sortedElements) {
      writer.writeUleb128(stringSection.getItemIndex(annotationSection.getElementName(element)));
      writeEncodedValue(annotationSection.getElementValue(element));
    }
  }
예제 #17
0
  @Override
  public int compareTo(Supplier o) {
    int diff =
        ComparisonChain.start()
            .compare(companyNm, o.companyNm, Ordering.from(String.CASE_INSENSITIVE_ORDER))
            .compare(
                contactTitle,
                o.contactTitle,
                Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(address, o.address, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(city, o.city, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(region, o.region, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(
                postalCode, o.postalCode, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(country, o.country, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(phone, o.phone, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(fax, o.fax, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(
                homePage, o.homePage, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .result();

    return diff;
  }
예제 #18
0
 /** Returns a newly-created immutable set multimap. */
 @Override
 public ImmutableSetMultimap<K, V> build() {
   if (keyComparator != null) {
     Multimap<K, V> sortedCopy = new BuilderMultimap<K, V>();
     List<Map.Entry<K, Collection<V>>> entries =
         Ordering.from(keyComparator)
             .<K>onKeys()
             .immutableSortedCopy(builderMultimap.asMap().entrySet());
     for (Map.Entry<K, Collection<V>> entry : entries) {
       sortedCopy.putAll(entry.getKey(), entry.getValue());
     }
     builderMultimap = sortedCopy;
   }
   return copyOf(builderMultimap, valueComparator);
 }
  @Override
  public synchronized ArrayList<String> find(String needle) {

    Ordering<String> ordering =
        Ordering.from(comparator).onResultOf(Functions.forMap(this.hayStack));
    ImmutableSortedMap<String, CommandEntry> orderedHay =
        ImmutableSortedMap.copyOf(this.hayStack, ordering);

    ArrayList<String> needles = new ArrayList<>();
    for (String straw : orderedHay.keySet()) {
      if (straw.contains(needle)) {
        needles.add(straw);
      }
    }
    return needles;
  }
예제 #20
0
 @Override
 public ImmutableSortedMap<K, V> descendingMap() {
   // TODO(kevinb): the descendingMap is never actually cached at all. Either it should be or the
   // code below simplified.
   ImmutableSortedMap<K, V> result = descendingMap;
   if (result == null) {
     if (isEmpty()) {
       return result = emptyMap(Ordering.from(comparator()).reverse());
     } else {
       return result =
           new ImmutableSortedMap<K, V>(
               (RegularImmutableSortedSet<K>) keySet.descendingSet(), valueList.reverse(), this);
     }
   }
   return result;
 }
예제 #21
0
 /** Returns the same range relative to the reversed comparator. */
 GeneralRange<T> reverse() {
   GeneralRange<T> result = reverse;
   if (result == null) {
     result =
         new GeneralRange<T>(
             Ordering.from(comparator).reverse(),
             hasUpperBound,
             getUpperEndpoint(),
             getUpperBoundType(),
             hasLowerBound,
             getLowerEndpoint(),
             getLowerBoundType());
     result.reverse = this;
     return this.reverse = result;
   }
   return result;
 }
예제 #22
0
 private static <K, V> ImmutableSortedMap<K, V> fromEntries(
     Comparator<? super K> comparator,
     boolean sameComparator,
     Entry<K, V>[] entryArray,
     int size) {
   switch (size) {
     case 0:
       return emptyMap(comparator);
     case 1:
       return ImmutableSortedMap.<K, V>of(
           comparator, entryArray[0].getKey(), entryArray[0].getValue());
     default:
       Object[] keys = new Object[size];
       Object[] values = new Object[size];
       if (sameComparator) {
         // Need to check for nulls, but don't need to sort or validate.
         for (int i = 0; i < size; i++) {
           Object key = entryArray[i].getKey();
           Object value = entryArray[i].getValue();
           checkEntryNotNull(key, value);
           keys[i] = key;
           values[i] = value;
         }
       } else {
         // Need to sort and check for nulls and dupes.
         Arrays.sort(entryArray, 0, size, Ordering.from(comparator).<K>onKeys());
         K prevKey = entryArray[0].getKey();
         keys[0] = prevKey;
         values[0] = entryArray[0].getValue();
         for (int i = 1; i < size; i++) {
           K key = entryArray[i].getKey();
           V value = entryArray[i].getValue();
           checkEntryNotNull(key, value);
           keys[i] = key;
           values[i] = value;
           checkNoConflict(
               comparator.compare(prevKey, key) != 0, "key", entryArray[i - 1], entryArray[i]);
           prevKey = key;
         }
       }
       return new ImmutableSortedMap<K, V>(
           new RegularImmutableSortedSet<K>(new RegularImmutableList<K>(keys), comparator),
           new RegularImmutableList<V>(values));
   }
 }
 private Collection<AuditLogEntry> purgeEntriesAndTransform(List<String> stringEntries) {
   Collection<AuditLogEntry> entries =
       Collections2.transform(
           stringEntries,
           new Function<String, AuditLogEntry>() {
             public AuditLogEntry apply(String from) {
               try {
                 return mapper.readValue(from, AuditLogEntryImpl.class);
               } catch (IOException e) {
                 throw new RuntimeException(
                     "Failed to parse AuditLogEntry from JSON string: " + from, e);
               }
             }
           });
   // Purge old entries
   entries = Collections2.filter(entries, purgePolicy);
   return Ordering.from(auditLogDateComparator).reverse().sortedCopy(entries);
 }
예제 #24
0
파일: Validator.java 프로젝트: kumon/presto
 private static Comparator<List<Object>> rowComparator(int precision) {
   final Comparator<Object> comparator = Ordering.from(columnComparator(precision)).nullsFirst();
   return new Comparator<List<Object>>() {
     @Override
     public int compare(List<Object> a, List<Object> b) {
       if (a.size() != b.size()) {
         return Integer.compare(a.size(), b.size());
       }
       for (int i = 0; i < a.size(); i++) {
         int r = comparator.compare(a.get(i), b.get(i));
         if (r != 0) {
           return r;
         }
       }
       return 0;
     }
   };
 }
  public String createUpdateAgainstCommittedSchema(
      URL schema, DatabaseWithIndexes newDatabase, URL indexNames) throws Exception {
    final DatabaseSnapshot reference = LiquibaseModelFactory.create(newDatabase.getDatabase());
    final DatabaseSnapshot target = createFromCommittedSchema(schema, indexNames);

    Collections.sort(
        newDatabase.getIndexNames().getIndexNames(),
        Ordering.from(String.CASE_INSENSITIVE_ORDER)
            .onResultOf(
                new Function<HibernateIndexName, String>() {
                  @Override
                  public String apply(HibernateIndexName input) {
                    return input.getTableName() + "-" + StringUtils.join(input.getColumns(), ',');
                  }
                }));

    final StringBuilder sb = new StringBuilder();
    printChanges(reference, target, sb);
    return sb.toString();
  }
예제 #26
0
  /** Given a jobId, returns the N most recent events in it's history in the cluster. */
  @Override
  public List<TaskStatusEvent> getJobHistory(final JobId jobId) throws JobDoesNotExistException {
    final Job descriptor = getJob(jobId);
    if (descriptor == null) {
      throw new JobDoesNotExistException(jobId);
    }
    final ZooKeeperClient client = provider.get("getJobHistory");
    final List<String> hosts;
    try {
      hosts = client.getChildren(Paths.historyJobHosts(jobId));
    } catch (NoNodeException e) {
      return emptyList();
    } catch (KeeperException e) {
      throw Throwables.propagate(e);
    }

    final List<TaskStatusEvent> jsEvents = Lists.newArrayList();

    for (String host : hosts) {
      final List<String> events;
      try {
        events = client.getChildren(Paths.historyJobHostEvents(jobId, host));
      } catch (KeeperException e) {
        throw Throwables.propagate(e);
      }

      for (String event : events) {
        try {
          byte[] data =
              client.getData(Paths.historyJobHostEventsTimestamp(jobId, host, Long.valueOf(event)));
          final TaskStatus status = Json.read(data, TaskStatus.class);
          jsEvents.add(new TaskStatusEvent(status, Long.valueOf(event), host));
        } catch (NoNodeException e) { // ignore, it went away before we read it
        } catch (KeeperException | IOException e) {
          throw Throwables.propagate(e);
        }
      }
    }

    return Ordering.from(EVENT_COMPARATOR).sortedCopy(jsEvents);
  }
예제 #27
0
 public CommitLogReplayer() {
   this.tablesRecovered = new NonBlockingHashSet<Table>();
   this.futures = new ArrayList<Future<?>>();
   this.buffer = new byte[4096];
   this.invalidMutations = new HashMap<Integer, AtomicInteger>();
   // count the number of replayed mutation. We don't really care about atomicity, but we need it
   // to be a reference.
   this.replayedCount = new AtomicInteger();
   // compute per-CF and global replay positions
   this.cfPositions = new HashMap<Integer, ReplayPosition>();
   for (ColumnFamilyStore cfs : ColumnFamilyStore.all()) {
     // it's important to call RP.gRP per-cf, before aggregating all the positions w/ the
     // Ordering.min call
     // below: gRP will return NONE if there are no flushed sstables, which is important to have in
     // the
     // list (otherwise we'll just start replay from the first flush position that we do have,
     // which is not correct).
     ReplayPosition rp = ReplayPosition.getReplayPosition(cfs.getSSTables());
     cfPositions.put(cfs.metadata.cfId, rp);
   }
   this.globalPosition = Ordering.from(ReplayPosition.comparator).min(cfPositions.values());
   this.checksum = new PureJavaCrc32();
 }
예제 #28
0
  private List<List<TPlayer>> getNonFixedSumPlayerGroups(
      final List<TPlayer> players, int numRoles, final Multiset<Set<TPlayer>> matchupsSoFar) {

    // Two-player: there's an elegant round-robin algorithm we
    // could use here, "rotate" all but one player in two rows

    // Do something naive for now
    //        final Multiset<Set<TPlayer>> matchupsSoFar =
    // nonFixedSumMatchupsSoFarByNumPlayers.get(numRoles);
    Preconditions.checkNotNull(matchupsSoFar);
    //        Map<Player, Multiset<Integer>> roleAssignmentsSoFar =
    // nonFixedSumRoleAssignmentsSoFarByNumPlayers.get(numRoles);
    List<TPlayer> playersToAssign = Lists.newArrayList(players);
    List<List<TPlayer>> results = Lists.newArrayList();
    while (playersToAssign.size() >= numRoles) {
      TPlayer player = playersToAssign.get(0);

      // Grab the first available players with the fewest previous matchups against us and each
      // other
      final List<TPlayer> playersInGroup = Lists.newArrayList(player);
      playersToAssign.remove(player);
      while (playersInGroup.size() < numRoles) {
        Ordering<TPlayer> playerOrder =
            Ordering.from(
                    new Comparator<TPlayer>() {
                      @Override
                      public int compare(TPlayer p1, TPlayer p2) {
                        int sum1 = getSum(p1);
                        int sum2 = getSum(p2);
                        return Integer.compare(sum1, sum2);
                      }

                      // Sum of matchups against players already in group
                      private int getSum(TPlayer p) {
                        int sum = 0;
                        for (TPlayer playerInGroup : playersInGroup) {
                          sum += matchupsSoFar.count(ImmutableSet.of(p, playerInGroup));
                        }
                        return sum;
                      }
                    })
                .compound(
                    new Comparator<TPlayer>() {
                      @Override
                      public int compare(TPlayer o1, TPlayer o2) {
                        int seed1 = players.indexOf(o1);
                        int seed2 = players.indexOf(o2);
                        return Integer.compare(seed1, seed2);
                      }
                    });
        TPlayer playerToAdd = playerOrder.min(playersToAssign);
        playersInGroup.add(playerToAdd);
        playersToAssign.remove(playerToAdd);
      }
      // TODO: Shuffle the roles intelligently, somehow
      // Should role shuffling be per-game? Across the tournament?

      results.add(playersInGroup);
    }

    for (List<TPlayer> playerGroup : results) {
      // TODO: Fix this
      for (int p1 = 0; p1 < playerGroup.size(); p1++) {
        for (int p2 = p1 + 1; p2 < playerGroup.size(); p2++) {
          matchupsSoFar.add(ImmutableSet.of(playerGroup.get(p1), playerGroup.get(p2)));
        }
      }
    }

    return results;
  }
예제 #29
0
@Immutable
public final class Duplication {
  private static final Ordering<Duplicate> DUPLICATE_ORDERING =
      Ordering.from(DuplicateComparatorByType.INSTANCE)
          .compound(Ordering.natural().onResultOf(DuplicateToFileKey.INSTANCE))
          .compound(Ordering.natural().onResultOf(DuplicateToTextBlock.INSTANCE));

  private final TextBlock original;
  private final SortedSet<Duplicate> duplicates;

  /**
   * @throws NullPointerException if {@code original} is {@code null} or {@code duplicates} is
   *     {@code null} or {@code duplicates} contains {@code null}
   * @throws IllegalArgumentException if {@code duplicates} is empty
   * @throws IllegalArgumentException if {@code duplicates} contains a {@link InnerDuplicate} with
   *     {@code original}
   */
  public Duplication(final TextBlock original, final Iterable<Duplicate> duplicates) {
    this.original = requireNonNull(original, "original TextBlock can not be null");
    this.duplicates =
        from(requireNonNull(duplicates, "duplicates can not be null"))
            .filter(FailOnNullDuplicate.INSTANCE)
            .filter(new EnsureInnerDuplicateIsNotOriginalTextBlock(original))
            .toSortedSet(DUPLICATE_ORDERING);
    checkArgument(!this.duplicates.isEmpty(), "duplicates can not be empty");
  }

  /** The duplicated block. */
  public TextBlock getOriginal() {
    return this.original;
  }

  /**
   * The duplicates of the original, sorted by inner duplicates, then project duplicates, then
   * cross-project duplicates. For each category of duplicate, they are sorted by:
   *
   * <ul>
   *   <li>file key (unless it's an InnerDuplicate)
   *   <li>then by TextBlocks by start line and in case of same line, by shortest first
   * </ul
   * <p>
   *
   * The returned set can not be empty and no inner duplicate can contain the original {@link
   * TextBlock}.
   */
  public SortedSet<Duplicate> getDuplicates() {
    return this.duplicates;
  }

  @Override
  public boolean equals(@Nullable Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    Duplication that = (Duplication) o;
    return original.equals(that.original) && duplicates.equals(that.duplicates);
  }

  @Override
  public int hashCode() {
    return Objects.hash(original, duplicates);
  }

  @Override
  public String toString() {
    return "Duplication{" + "original=" + original + ", duplicates=" + duplicates + '}';
  }

  private enum FailOnNullDuplicate implements Predicate<Duplicate> {
    INSTANCE;

    @Override
    public boolean apply(@Nullable Duplicate input) {
      requireNonNull(input, "duplicates can not contain null");
      return true;
    }
  }

  private enum DuplicateComparatorByType implements Comparator<Duplicate> {
    INSTANCE;

    @Override
    public int compare(Duplicate o1, Duplicate o2) {
      return toIndexType(o1) - toIndexType(o2);
    }

    private static int toIndexType(Duplicate duplicate) {
      if (duplicate instanceof InnerDuplicate) {
        return 0;
      }
      if (duplicate instanceof InProjectDuplicate) {
        return 1;
      }
      if (duplicate instanceof CrossProjectDuplicate) {
        return 2;
      }
      throw new IllegalArgumentException(
          "Unsupported type of Duplicate " + duplicate.getClass().getName());
    }
  }

  private enum DuplicateToTextBlock implements Function<Duplicate, TextBlock> {
    INSTANCE;

    @Override
    @Nonnull
    public TextBlock apply(@Nonnull Duplicate input) {
      return input.getTextBlock();
    }
  }

  private static class EnsureInnerDuplicateIsNotOriginalTextBlock implements Predicate<Duplicate> {
    private final TextBlock original;

    public EnsureInnerDuplicateIsNotOriginalTextBlock(TextBlock original) {
      this.original = original;
    }

    @Override
    public boolean apply(@Nullable Duplicate input) {
      if (input instanceof InnerDuplicate) {
        checkArgument(
            !original.equals(input.getTextBlock()),
            "TextBlock of an InnerDuplicate can not be the original TextBlock");
      }
      return true;
    }
  }

  private enum DuplicateToFileKey implements Function<Duplicate, String> {
    INSTANCE;

    @Override
    @Nonnull
    public String apply(@Nonnull Duplicate duplicate) {
      if (duplicate instanceof InnerDuplicate) {
        return "";
      }
      if (duplicate instanceof InProjectDuplicate) {
        return ((InProjectDuplicate) duplicate).getFile().getKey();
      }
      if (duplicate instanceof CrossProjectDuplicate) {
        return ((CrossProjectDuplicate) duplicate).getFileKey();
      }
      throw new IllegalArgumentException(
          "Unsupported type of Duplicate " + duplicate.getClass().getName());
    }
  }
}
예제 #30
0
  @Override
  public int compareTo(Employee o) {
    int diff =
        ComparisonChain.start()
            .compare(lastName, o.lastName, Ordering.from(String.CASE_INSENSITIVE_ORDER))
            .compare(firstName, o.firstName, Ordering.from(String.CASE_INSENSITIVE_ORDER))
            .compare(title, o.title, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(
                titleCourtesy,
                o.titleCourtesy,
                Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(birthDate, o.birthDate, Ordering.natural().nullsFirst())
            .compare(hireDate, o.hireDate, Ordering.natural().nullsFirst())
            .compare(address, o.address, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(city, o.city, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(region, o.region, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(
                postalCode, o.postalCode, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(country, o.country, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(
                homePhone, o.homePhone, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(
                extension, o.extension, Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsFirst())
            .compare(reportsTo, o.reportsTo, Ordering.natural().nullsFirst())
            .result();
    if (diff != 0) return diff;

    if (photo == null) return o.photo == null ? 0 : -1;
    if (o.photo == null) return 1;
    return UnsignedBytes.lexicographicalComparator().compare(photo, o.photo);
  }