@SuppressWarnings("unchecked")
  public static void main(String... args) throws Exception {

    Stream<String> scrabbleWordsStream = Files.lines(Paths.get("files", "ospd.txt"));
    Set<String> scrabbleWords =
        scrabbleWordsStream.map(String::toLowerCase).collect(Collectors.toSet());

    Stream<String> shakespeareWordsStream =
        Files.lines(Paths.get("files", "words.shakespeare.txt"));
    Set<String> shakespeareWords =
        shakespeareWordsStream.map(String::toLowerCase).collect(Collectors.toSet());

    System.out.println("# de mots autorisés au Scrabble : " + scrabbleWords.size());

    // mots utilisés par Shakespeare
    Long nWords1 = shakespeareWords.stream().count();
    System.out.println("# ofmots utilisés par Shakespeare  : " + nWords1);

    // number of words used by Shakespeare and allowed at Scrabble
    long count =
        shakespeareWords.stream().map(String::toLowerCase).filter(scrabbleWords::contains).count();
    System.out.println("# number of words used by Shakespeare and allowed at Scrabble = " + count);

    // words of Shakespeare grouped by their length
    Map<Integer, Long> map1 =
        shakespeareWords
            .stream()
            .collect(Collectors.groupingBy(String::length, Collectors.counting()));
    System.out.println("Words of Shakespeare grouped by their length = " + map1);

    // words of Shakespeare of 16 letters and more
    Map<Integer, List<String>> map2 =
        shakespeareWords
            .stream()
            .filter(word -> word.length() > 15)
            .collect(Collectors.groupingBy(String::length));
    System.out.println("Words of Shakespeare of 16 letters and more = " + map2);

    // words of Shakespeare grouped by their Scrabble score
    // in ascending order
    Function<String, Integer> score = word -> word.chars().map(scrabbleLetterValueEN).sum();
    Map<Integer, Long> map3 =
        shakespeareWords
            .stream()
            .map(String::toLowerCase)
            .filter(scrabbleWords::contains)
            .collect(Collectors.groupingBy(score, TreeMap::new, Collectors.counting()));
    System.out.println("Words of Shakespeare grouped by their Scrabble score = " + map3);

    // words of Shakespeare grouped by their Scrabble score, with a score greater than 29
    // in ascending order
    Predicate<String> scoreGT28 = word -> score.apply(word) > 28;
    Map<Integer, List<String>> map4 =
        shakespeareWords
            .stream()
            .map(String::toLowerCase)
            .filter(scrabbleWords::contains)
            .filter(scoreGT28)
            .collect(Collectors.groupingBy(score, TreeMap::new, Collectors.toList()));
    System.out.println("Words of Shakespeare grouped by their Scrabble score = " + map4);

    // histogram of the letters in a given word
    Function<String, Map<Integer, Long>> lettersHisto =
        word ->
            word.chars()
                .mapToObj(Integer::new)
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

    // score of a given word, taking into account that the given word
    // might contain blank letters
    Function<String, Integer> scoreWithBlanks =
        word ->
            lettersHisto
                .apply(word)
                .entrySet()
                .stream() // Map.Entry<letters, # used>
                .mapToInt(
                    entry ->
                        scrabbleENScore[entry.getKey() - 'a']
                            * (int)
                                Long.min(
                                    entry.getValue(), scrabbleENDistribution[entry.getKey() - 'a']))
                .sum();

    // number of blanks used for the given word
    Function<String, Integer> blanksUsed =
        word ->
            lettersHisto
                .apply(word)
                .entrySet()
                .stream() // Map.Entry<letters, # used>
                .mapToInt(
                    entry ->
                        (int)
                            Long.max(
                                0L,
                                entry.getValue() - scrabbleENDistribution[entry.getKey() - 'a']))
                .sum();

    System.out.println("Number of blanks in [buzzards] = " + blanksUsed.apply("buzzards"));
    System.out.println("Real score of [buzzards] = " + scoreWithBlanks.apply("buzzards"));
    System.out.println("Number of blanks in [whizzing] = " + blanksUsed.apply("whizzing"));
    System.out.println("Real score of [whizzing] = " + scoreWithBlanks.apply("whizzing"));

    // best words of Shakespeare and their scores
    Map<Integer, List<String>> map =
        shakespeareWords
            .stream()
            .filter(scrabbleWords::contains)
            .filter(word -> blanksUsed.apply(word) <= 2L)
            .filter(word -> scoreWithBlanks.apply(word) >= 24)
            .collect(Collectors.groupingBy(scoreWithBlanks, Collectors.toList()));
    System.out.println("Best words of Shakespeare : " + map);
  }
Beispiel #2
0
 @Override
 public long countDepth() {
   return Long.max(level, super.countDepth());
 }
  @Override
  public CorfuDBView getNewView(CorfuDBView oldView, NetworkException e) {
    /* it's null, don't change anything */
    if (e == null) {
      return oldView;
    }
    /* Is the exception for a Logging Unit? */
    if (e.protocol instanceof IWriteOnceLogUnit) {
      /* Okay, so was it a read or a write? */
      if (e.write) {
        /* in the case of a write, find the segment belonging to the protocol,
          and remove that protocol from the segment.
        */
        CorfuDBView newView = (CorfuDBView) Serializer.copyShallow(oldView);

        for (CorfuDBViewSegment segment : newView.getSegments()) {
          for (List<IServerProtocol> nodeList : segment.getGroups()) {
            if (nodeList.size() > 1) {
              nodeList.removeIf(n -> n.getFullString().equals(e.protocol.getFullString()));
            }
          }
        }

        log.info("Reconfiguring all nodes in view to new epoch " + oldView.getEpoch() + 1);
        newView.moveAllToNewEpoch(oldView.getEpoch() + 1);
        return newView;
      }
      /* for reads, we don't do anything, for now...
       */
      log.warn("Reconfigure due to read, ignoring");
      return oldView;
    } else if (e.protocol instanceof ISimpleSequencer) {
      if (oldView.getSequencers().size() <= 1) {
        log.warn(
            "Request reconfiguration of sequencers but there is no fail-over available! [available sequencers="
                + oldView.getSequencers().size()
                + "]");
        return oldView;
      } else {
        CorfuDBView newView = (CorfuDBView) Serializer.copyShallow(oldView);
        newView.moveAllToNewEpoch(oldView.getEpoch() + 1);

        /* Interrogate each log unit to figure out last issued token */
        long last = -1;
        for (CorfuDBViewSegment segment : newView.getSegments()) {
          int groupNum = 1;
          for (List<IServerProtocol> nodeList : segment.getGroups()) {
            for (IServerProtocol n : nodeList) {
              try {
                last =
                    Long.max(
                        last,
                        ((IWriteOnceLogUnit) n).highestAddress() * segment.getGroups().size()
                            + groupNum);
              } catch (NetworkException ne) {

              }
            }
            groupNum++;
          }
        }

        log.warn(
            "Removing sequencer "
                + e.protocol.getFullString()
                + " from configuration, discover last sequence was "
                + last);
        newView.getSequencers().removeIf(n -> n.getFullString().equals(e.protocol.getFullString()));
        try {
          ((ISimpleSequencer) newView.getSequencers().get(0)).recover(last);
        } catch (Exception ex) {
          log.warn("Tried to install recovered sequence from sequencer, but failed", e);
        }
        return newView;
      }
    } else {
      log.warn("Request reconfiguration for protocol we don't know how to reconfigure", e.protocol);
      return (CorfuDBView) Serializer.copyShallow(oldView);
    }
  }
  /*
   Result: 12,690 ±(99.9%) 0,148 s/op [Average]
   		  Statistics: (min, avg, max) = (12,281, 12,690, 12,784), stdev = 0,138
   		  Confidence interval (99.9%): [12,543, 12,838]
   		  Samples, N = 15
   		        mean =     12,690 ±(99.9%) 0,148 s/op
   		         min =     12,281 s/op
   		  p( 0,0000) =     12,281 s/op
   		  p(50,0000) =     12,717 s/op
   		  p(90,0000) =     12,784 s/op
   		  p(95,0000) =     12,784 s/op
   		  p(99,0000) =     12,784 s/op
   		  p(99,9000) =     12,784 s/op
   		  p(99,9900) =     12,784 s/op
   		  p(99,9990) =     12,784 s/op
   		  p(99,9999) =     12,784 s/op
   		         max =     12,784 s/op


   		# Run complete. Total time: 00:06:26

   		Benchmark                                               Mode  Cnt   Score   Error  Units
   		ShakespearePlaysScrabbleWithRxJava.measureThroughput  sample   15  12,690 ± 0,148   s/op

   		Benchmark                                              Mode  Cnt       Score      Error  Units
  ShakespearePlaysScrabbleWithRxJava.measureThroughput   avgt   15  250074,776 ± 7736,734  us/op
  ShakespearePlaysScrabbleWithStreams.measureThroughput  avgt   15   29389,903 ± 1115,836  us/op

   */
  @Benchmark
  @BenchmarkMode(Mode.SampleTime)
  @OutputTimeUnit(TimeUnit.MILLISECONDS)
  @Warmup(iterations = 50)
  @Measurement(iterations = 50)
  @Fork(1)
  public List<Entry<Integer, List<String>>> measureThroughput() throws InterruptedException {

    //  to compute the score of a given word
    Function<Integer, PublisherBase<Integer>> scoreOfALetter =
        letter -> PublisherBase.just(letterScores[letter - 'a']);

    // score of the same letters in a word
    Function<Entry<Integer, LongWrapper>, PublisherBase<Integer>> letterScore =
        entry ->
            PublisherBase.just(
                letterScores[entry.getKey() - 'a']
                    * Integer.min(
                        (int) entry.getValue().get(),
                        (int) scrabbleAvailableLetters[entry.getKey() - 'a']));

    Function<String, PublisherBase<Integer>> toIntegerPublisherBase =
        string ->
            PublisherBase.fromIterable(
                IterableSpliterator.of(string.chars().boxed().spliterator()));

    // Histogram of the letters in a given word
    Function<String, PublisherBase<HashMap<Integer, LongWrapper>>> histoOfLetters =
        word ->
            toIntegerPublisherBase
                .apply(word)
                .collect(
                    () -> new HashMap<Integer, LongWrapper>(),
                    (HashMap<Integer, LongWrapper> map, Integer value) -> {
                      LongWrapper newValue = map.get(value);
                      if (newValue == null) {
                        newValue = () -> 0L;
                      }
                      map.put(value, newValue.incAndSet());
                    });

    // number of blanks for a given letter
    Function<Entry<Integer, LongWrapper>, PublisherBase<Long>> blank =
        entry ->
            PublisherBase.just(
                Long.max(
                    0L, entry.getValue().get() - scrabbleAvailableLetters[entry.getKey() - 'a']));

    // number of blanks for a given word
    Function<String, PublisherBase<Long>> nBlanks =
        word ->
            histoOfLetters
                .apply(word)
                .flatMap(map -> PublisherBase.fromIterable(() -> map.entrySet().iterator()))
                .flatMap(blank)
                .reduce(Long::sum);

    // can a word be written with 2 blanks?
    Function<String, PublisherBase<Boolean>> checkBlanks =
        word -> nBlanks.apply(word).flatMap(l -> PublisherBase.just(l <= 2L));

    // score taking blanks into account letterScore1
    Function<String, PublisherBase<Integer>> score2 =
        word ->
            histoOfLetters
                .apply(word)
                .flatMap(map -> PublisherBase.fromIterable(() -> map.entrySet().iterator()))
                .flatMap(letterScore)
                .reduce(Integer::sum);

    // Placing the word on the board
    // Building the streams of first and last letters
    Function<String, PublisherBase<Integer>> first3 =
        word ->
            PublisherBase.fromIterable(
                IterableSpliterator.of(word.chars().boxed().limit(3).spliterator()));
    Function<String, PublisherBase<Integer>> last3 =
        word ->
            PublisherBase.fromIterable(
                IterableSpliterator.of(word.chars().boxed().skip(3).spliterator()));

    // Stream to be maxed
    Function<String, PublisherBase<Integer>> toBeMaxed =
        word ->
            PublisherBase.fromArray(first3.apply(word), last3.apply(word))
                .flatMap(PublisherBase -> PublisherBase);

    // Bonus for double letter
    Function<String, PublisherBase<Integer>> bonusForDoubleLetter =
        word -> toBeMaxed.apply(word).flatMap(scoreOfALetter).reduce(Integer::max);

    // score of the word put on the board
    Function<String, PublisherBase<Integer>> score3 =
        word ->
            PublisherBase.fromArray(
                    score2.apply(word),
                    score2.apply(word),
                    bonusForDoubleLetter.apply(word),
                    bonusForDoubleLetter.apply(word),
                    PublisherBase.just(word.length() == 7 ? 50 : 0))
                .flatMap(PublisherBase -> PublisherBase)
                .reduce(Integer::sum);

    Function<
            Function<String, PublisherBase<Integer>>, PublisherBase<TreeMap<Integer, List<String>>>>
        buildHistoOnScore =
            score ->
                PublisherBase.fromIterable(() -> shakespeareWords.iterator())
                    .filter(scrabbleWords::contains)
                    .filter(word -> checkBlanks.apply(word).blockingFirst())
                    .collect(
                        () -> new TreeMap<Integer, List<String>>(Comparator.reverseOrder()),
                        (TreeMap<Integer, List<String>> map, String word) -> {
                          Integer key = score.apply(word).blockingFirst();
                          List<String> list = map.get(key);
                          if (list == null) {
                            list = new ArrayList<String>();
                            map.put(key, list);
                          }
                          list.add(word);
                        });

    // best key / value pairs
    List<Entry<Integer, List<String>>> finalList2 =
        buildHistoOnScore
            .apply(score3)
            .flatMap(map -> PublisherBase.fromIterable(() -> map.entrySet().iterator()))
            .take(3)
            .collect(
                () -> new ArrayList<Entry<Integer, List<String>>>(),
                (list, entry) -> {
                  list.add(entry);
                })
            .blockingFirst();

    //        System.out.println(finalList2);

    return finalList2;
  }