@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); }
@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; }