From 746eb7c69c73a32eb4c98431efb59806e621f1ae Mon Sep 17 00:00:00 2001 From: Frank McSherry Date: Mon, 21 Sep 2026 13:53:04 -0400 Subject: [PATCH] Remove the three unbuildable crates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `advent_of_code_2017`, `tpchlike` and `doop` are commented out of `workspace.members` and are not in `workspace.exclude` either, so they cannot be built by any route — a standalone `cargo check` fails with "current package believes it's in a workspace when it's not". They have missed the last several API migrations. `experiments`, `diagnostics` and `dogsdogsdogs` were updated for timely #817-#819 in \#877; these three were not, and were last touched in #724 (April) and \#673 (February). Nothing outside their own trees references them beyond the three commented `members` lines removed here. 13,294 lines, ~21% of the repository's Rust. Co-Authored-By: Claude Opus 5 (1M context) --- advent_of_code_2017/Cargo.toml | 14 - advent_of_code_2017/src/bin/day_01.rs | 48 - advent_of_code_2017/src/bin/day_02.rs | 82 - advent_of_code_2017/src/bin/day_03.rs | 105 -- advent_of_code_2017/src/bin/day_04.rs | 569 ------- advent_of_code_2017/src/bin/day_05.rs | 1102 ------------- advent_of_code_2017/src/bin/day_06.rs | 71 - advent_of_code_2017/src/bin/day_07.rs | 1134 -------------- advent_of_code_2017/src/bin/day_08.rs | 1151 -------------- advent_of_code_2017/src/bin/day_09.rs | 164 -- advent_of_code_2017/src/bin/day_10.rs | 64 - advent_of_code_2017/src/bin/day_11.rs | 64 - advent_of_code_2017/src/bin/day_12.rs | 2061 ------------------------- advent_of_code_2017/src/bin/day_13.rs | 93 -- advent_of_code_2017/src/bin/day_14.rs | 95 -- advent_of_code_2017/src/bin/day_15.rs | 46 - advent_of_code_2017/src/bin/day_17.rs | 43 - advent_of_code_2017/src/lib.rs | 0 doop/Cargo.toml | 14 - doop/self-contained.dl | 561 ------- doop/src/main.rs | 1242 --------------- tpchlike/Cargo.toml | 17 - tpchlike/README.md | 44 - tpchlike/src/bin/arrange.rs | 246 --- tpchlike/src/bin/batch.rs | 166 -- tpchlike/src/bin/just-arrange.rs | 223 --- tpchlike/src/bin/sosp.rs | 200 --- tpchlike/src/bin/stream-concurrent.rs | 219 --- tpchlike/src/bin/stream.rs | 223 --- tpchlike/src/lib.rs | 280 ---- tpchlike/src/queries/mod.rs | 22 - tpchlike/src/queries/query01.rs | 90 -- tpchlike/src/queries/query02.rs | 167 -- tpchlike/src/queries/query03.rs | 115 -- tpchlike/src/queries/query04.rs | 88 -- tpchlike/src/queries/query05.rs | 137 -- tpchlike/src/queries/query06.rs | 63 - tpchlike/src/queries/query07.rs | 148 -- tpchlike/src/queries/query08.rs | 136 -- tpchlike/src/queries/query09.rs | 109 -- tpchlike/src/queries/query10.rs | 122 -- tpchlike/src/queries/query11.rs | 112 -- tpchlike/src/queries/query12.rs | 117 -- tpchlike/src/queries/query13.rs | 97 -- tpchlike/src/queries/query14.rs | 85 - tpchlike/src/queries/query15.rs | 154 -- tpchlike/src/queries/query16.rs | 127 -- tpchlike/src/queries/query17.rs | 102 -- tpchlike/src/queries/query18.rs | 88 -- tpchlike/src/queries/query19.rs | 126 -- tpchlike/src/queries/query20.rs | 140 -- tpchlike/src/queries/query21.rs | 139 -- tpchlike/src/queries/query22.rs | 159 -- tpchlike/src/types.rs | 310 ---- 54 files changed, 13294 deletions(-) delete mode 100644 advent_of_code_2017/Cargo.toml delete mode 100644 advent_of_code_2017/src/bin/day_01.rs delete mode 100644 advent_of_code_2017/src/bin/day_02.rs delete mode 100644 advent_of_code_2017/src/bin/day_03.rs delete mode 100644 advent_of_code_2017/src/bin/day_04.rs delete mode 100644 advent_of_code_2017/src/bin/day_05.rs delete mode 100644 advent_of_code_2017/src/bin/day_06.rs delete mode 100644 advent_of_code_2017/src/bin/day_07.rs delete mode 100644 advent_of_code_2017/src/bin/day_08.rs delete mode 100644 advent_of_code_2017/src/bin/day_09.rs delete mode 100644 advent_of_code_2017/src/bin/day_10.rs delete mode 100644 advent_of_code_2017/src/bin/day_11.rs delete mode 100644 advent_of_code_2017/src/bin/day_12.rs delete mode 100644 advent_of_code_2017/src/bin/day_13.rs delete mode 100644 advent_of_code_2017/src/bin/day_14.rs delete mode 100644 advent_of_code_2017/src/bin/day_15.rs delete mode 100644 advent_of_code_2017/src/bin/day_17.rs delete mode 100644 advent_of_code_2017/src/lib.rs delete mode 100644 doop/Cargo.toml delete mode 100644 doop/self-contained.dl delete mode 100644 doop/src/main.rs delete mode 100644 tpchlike/Cargo.toml delete mode 100644 tpchlike/README.md delete mode 100644 tpchlike/src/bin/arrange.rs delete mode 100644 tpchlike/src/bin/batch.rs delete mode 100644 tpchlike/src/bin/just-arrange.rs delete mode 100644 tpchlike/src/bin/sosp.rs delete mode 100644 tpchlike/src/bin/stream-concurrent.rs delete mode 100644 tpchlike/src/bin/stream.rs delete mode 100644 tpchlike/src/lib.rs delete mode 100644 tpchlike/src/queries/mod.rs delete mode 100644 tpchlike/src/queries/query01.rs delete mode 100644 tpchlike/src/queries/query02.rs delete mode 100644 tpchlike/src/queries/query03.rs delete mode 100644 tpchlike/src/queries/query04.rs delete mode 100644 tpchlike/src/queries/query05.rs delete mode 100644 tpchlike/src/queries/query06.rs delete mode 100644 tpchlike/src/queries/query07.rs delete mode 100644 tpchlike/src/queries/query08.rs delete mode 100644 tpchlike/src/queries/query09.rs delete mode 100644 tpchlike/src/queries/query10.rs delete mode 100644 tpchlike/src/queries/query11.rs delete mode 100644 tpchlike/src/queries/query12.rs delete mode 100644 tpchlike/src/queries/query13.rs delete mode 100644 tpchlike/src/queries/query14.rs delete mode 100644 tpchlike/src/queries/query15.rs delete mode 100644 tpchlike/src/queries/query16.rs delete mode 100644 tpchlike/src/queries/query17.rs delete mode 100644 tpchlike/src/queries/query18.rs delete mode 100644 tpchlike/src/queries/query19.rs delete mode 100644 tpchlike/src/queries/query20.rs delete mode 100644 tpchlike/src/queries/query21.rs delete mode 100644 tpchlike/src/queries/query22.rs delete mode 100644 tpchlike/src/types.rs diff --git a/advent_of_code_2017/Cargo.toml b/advent_of_code_2017/Cargo.toml deleted file mode 100644 index a120d2cd16..0000000000 --- a/advent_of_code_2017/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "advent_of_code_2017" -version = "0.1.0" -authors = ["Frank McSherry "] -publish = false -edition.workspace = true -rust-version.workspace = true - -[lints] -workspace = true - -[dependencies] -differential-dataflow = { workspace = true } -timely = { workspace = true } diff --git a/advent_of_code_2017/src/bin/day_01.rs b/advent_of_code_2017/src/bin/day_01.rs deleted file mode 100644 index c6159872b0..0000000000 --- a/advent_of_code_2017/src/bin/day_01.rs +++ /dev/null @@ -1,48 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/1 - -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = b"7385764686251444473997915123782972536343732657517834671759462795461213782428342931896181695578996274321317419242359534783957372932953774336338118488967172727651862498838195317654289797558683458511126996217953322817229372373455862177844478443391835484591525235651863464891177927244954925827786799436536592561374269299474738321293575385899438446558569241236278779779983587912431395475244796538888373287186921647426866237756737342731976763959499149996315591584716122199183295277439872911371313924594486766479438544417416529743495114819825984524437367225234184772617942525954961136976875325182725754768372684531972614455134523596338355374444273522115362238734383164778129376628621497662965456761631796178353599629887665939521892447361219479646483978798392716119793282717739524897385958273726776318154977675546287789874265339688753977185129334929715486381875286278528247696464162297691698154712775589541945263574897266575996455547625537947927972497979333932115165151462742216327321116291372396585618664475715321298122335789262942284571328414569375464386446824882551918843185195829547373915482687534432942778312542752798313434628498295216692646713137244198123219531693559848915834623825919191532658735422176965451741869666714874158492556445954852299161868651448123825821775363219246244515946392686275545561989355573946924767442253465342753995764791927951158771231944177692469531494559697911176613943396258141822244578457498361352381518166587583342233816989329544415621127397996723997397219676486966684729653763525768655324443991129862129181215339947555257279592921258246646215764736698583211625887436176149251356452358211458343439374688341116529726972434697324734525114192229641464227986582845477741747787673588848439713619326889624326944553386782821633538775371915973899959295232927996742218926514374168947582441892731462993481877277714436887597223871881149693228928442427611664655772333471893735932419937832937953495929514837663883938416644387342825836673733778119481514427512453357628396666791547531814844176342696362416842993761919369994779897357348334197721735231299249116477"; - let length = input.len(); - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let worker_input = - input - .iter() - .map(|digit| digit - b'0') - .enumerate() - .filter(move |&(pos,_)| pos % peers == index) - .map(|(pos, digit)| (digit, pos)); - - worker.dataflow::<(),_,_>(|scope| { - - let digits = scope.new_collection_from(worker_input).1; - - // The two parts ask to line up elements with the next one in the sequence (part 1) and - // the one half way around the sequence (part 2). To find matches, we will shift the - // associated position field while keeping the part identifier as a field (`1` or `2` - // respectively). We then restrict both by the original `digits` to find matches. - - let part1 = digits.map(move |(digit, position)| ((digit, (position + 1) % length), 1)); - let part2 = digits.map(move |(digit, position)| ((digit, (position + length/2) % length), 2)); - - part1 - .concat(part2) // merge collections. - .semijoin(digits) // restrict to matches. - .explode(|((digit, _pos), part)| Some((part, digit as isize))) // `part` with weight `digit`. - .consolidate() // consolidate weights by `part`. - .inspect(|elt| println!("part {} accumulation: {:?}", elt.0, elt.2)); // check out answers. - }); - - }).unwrap(); -} \ No newline at end of file diff --git a/advent_of_code_2017/src/bin/day_02.rs b/advent_of_code_2017/src/bin/day_02.rs deleted file mode 100644 index 048464bab3..0000000000 --- a/advent_of_code_2017/src/bin/day_02.rs +++ /dev/null @@ -1,82 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/2 - -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = -"86 440 233 83 393 420 228 491 159 13 110 135 97 238 92 396 -3646 3952 3430 145 1574 2722 3565 125 3303 843 152 1095 3805 134 3873 3024 -2150 257 237 2155 1115 150 502 255 1531 894 2309 1982 2418 206 307 2370 -1224 343 1039 126 1221 937 136 1185 1194 1312 1217 929 124 1394 1337 168 -1695 2288 224 2667 2483 3528 809 263 2364 514 3457 3180 2916 239 212 3017 -827 3521 127 92 2328 3315 1179 3240 695 3144 3139 533 132 82 108 854 -1522 2136 1252 1049 207 2821 2484 413 2166 1779 162 2154 158 2811 164 2632 -95 579 1586 1700 79 1745 1105 89 1896 798 1511 1308 1674 701 60 2066 -1210 325 98 56 1486 1668 64 1601 1934 1384 69 1725 992 619 84 167 -4620 2358 2195 4312 168 1606 4050 102 2502 138 135 4175 1477 2277 2226 1286 -5912 6261 3393 431 6285 3636 4836 180 6158 6270 209 3662 5545 204 6131 230 -170 2056 2123 2220 2275 139 461 810 1429 124 1470 2085 141 1533 1831 518 -193 281 2976 3009 626 152 1750 1185 3332 715 1861 186 1768 3396 201 3225 -492 1179 154 1497 819 2809 2200 2324 157 2688 1518 168 2767 2369 2583 173 -286 2076 243 939 399 451 231 2187 2295 453 1206 2468 2183 230 714 681 -3111 2857 2312 3230 149 3082 408 1148 2428 134 147 620 128 157 492 2879"; - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let worker_input = - input - .split('\n') - .enumerate() - .filter(move |&(row, _line)| row % peers == index) - .flat_map(|(row, line)| - line.split_whitespace() - .enumerate() - .map(move |(col, int)| (int.parse::().unwrap(), row, col)) - ); - - worker.dataflow::<(),_,_>(|scope| { - - let entries = scope.new_collection_from(worker_input).1; - - entries - .map(|(val, row, _col)| (row, val)) - .group(|_row, vals, output| { - - // Part one solution (difference of max and min within rows) - let mut min = vals[0].0; - let mut max = vals[0].0; - for &(val, _) in vals.iter() { - if min > val { min = val; } - if max < val { max = val; } - } - output.push((1, (max - min))); - - // Part two solution (ratio of two even divisors in the row) - if vals.iter().filter(|&&(_,count)| count > 1).next().is_some() { - output.push((2, 1)); - } - else { - for &(val1, _) in vals.iter() { - for &(val2, _) in vals.iter() { - if (val1 % val2) == 0 && val1 != val2 { - output.push((2, val1 / val2)); - } - } - } - } - }) - .map(|(_, part)| part) - .consolidate() - .inspect(|elt| println!("part {} checksum: {:?}", elt.0, elt.2)); - }); - - }).unwrap(); -} \ No newline at end of file diff --git a/advent_of_code_2017/src/bin/day_03.rs b/advent_of_code_2017/src/bin/day_03.rs deleted file mode 100644 index d51ab21ab2..0000000000 --- a/advent_of_code_2017/src/bin/day_03.rs +++ /dev/null @@ -1,105 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/3 - -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = 347991; - - // The sequence of numbers going down and to the right are the squares of odd numbers. - // - // 1, 9, 25, ... - // - // The next odd square is arrived at by following four edges, each of which has length - // equal to the even number between the odd numbers. To determine the position of any - // given number, we can subtract the largest odd square from it and then subtract the - // multiples of the even length, at which point we have a distance along an edge, from - // which we can determine coordinates. - // - // Similarly, we can determine the sequence number from the coordinates, by determining - // which layer the point is in, adding the appropriate squared odd number, and then some - // cases to figure out where the point is in the sequence along that layer. - // - // We are going to skip doing part one, because we can just solve for the answer (480), - // and instead write up part two. - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - worker.dataflow::<(),_,_>(move |scope| { - - let worker_input = (1 .. 2).filter(move |&pos| pos % peers == index); - - let values = scope.new_collection_from(worker_input).1; - - values - .map(|_val| ((0, 0), (1, 1))) - .iterate(|_scope, inner| { - - inner - .filter(move |&(_, (_, val))| val < input) // stop working when we've gotten enough - .flat_map(|((x,y), (idx, value))| // announce your value to all neighbors - (x-1 .. x+2).flat_map(move |x| (y-1 .. y+2).map(move |y| ((x,y), (idx,value)))) - ) - .group(|coords, idx_vals, output| { - - let seq = sequence(*coords); - if seq == 1 { // output for one is always one. - output.push(((1, 1), 1)); - } - // otherwise, if we have data from the immediate predecessor... - else if idx_vals.iter().find(|x| (x.0).0 == seq - 1).is_some() { - let mut sum = 0; - for &(idx_val, wgt) in idx_vals.iter() { - if idx_val.0 < seq { - sum += idx_val.1 * wgt; - } - } - output.push(((seq, sum), 1)); - } - }) - }) - .map(|(_,(_,val))| ((),val)) // discard keys, retain and group vals. - .group(|&(), input, output| output.push((*input[input.len()-1].0, 1))) - .consolidate() - .inspect(|x| println!("{:?}", (x.0).1)) - ; - }); - - }).unwrap(); - -} - -fn sequence(input: (isize, isize)) -> isize { - - if input == (0, 0) { return 1; } - else { - - let mut layer = 0; - - // extract the L0 norm (max absolute value). - if input.0 > layer { layer = input.0; } - if input.1 > layer { layer = input.1; } - if -input.0 > layer { layer = -input.0; } - if -input.1 > layer { layer = -input.1; } - - // input exists in layer from ((2 * layer - 1)^2, (2 * layer + 1)^2]. - // note: excludes first number, includes last number. - - let base = (2 * layer - 1) * (2 * layer - 1); - - if input.1 == -layer { base + 3 * (2 * layer) + input.0 + layer } - else if input.0 == -layer { base + 2 * (2 * layer) + layer - input.1 } - else if input.1 == layer { base + 1 * (2 * layer) + layer - input.0 } - else if input.0 == layer { base + 0 * (2 * layer) + input.1 + layer } - else { - panic!("should be unreachable"); - } - } -} \ No newline at end of file diff --git a/advent_of_code_2017/src/bin/day_04.rs b/advent_of_code_2017/src/bin/day_04.rs deleted file mode 100644 index 982d37a21a..0000000000 --- a/advent_of_code_2017/src/bin/day_04.rs +++ /dev/null @@ -1,569 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/4 - -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = -"oaoe rxeq vssdqtu xrk cjv yaoqp loo -mveua dogbam szydvri hyzk lbega abzqw xwjn wniug kwbre -npaoy uivpxwd oynpa rcdk uixpvdw -yserir iikzcm ieuroca iuwcfov rvb giti crdpdcv mxpps -spyuhgo lucasl ucllsa bymnjig yflbv nxitmlf -xlxyhwz xla mpye fvjegwg fezlfrt inetrh vhg xpvstx ydhvq -xgue cvtmh myg ontvvyw ygm oqzrdrw -srdfsjf dli kccb kauk kauk apa doefc cdffkhh cdffkhh -msizb elqiov lqn epamk onmnlst baawab ncafwaf jrataml iyzhy svycuec -wdzqpcn dkgdumv wdzqpcn qxdmwib cjsigi bgcihgh fmua -kpvbzf kpvbzf svyq flg shwtgp -ywrynt cesjtgk hsvitr brpiul lxgvvrl cesjtgk cesjtgk xuflpfn -tik mrpht gkv unqp wypscc vmwiu ldrigk okbc wztc -zpy kyzvijv bilpf etbrgk edza vuz jzgn -yoa rgppd kzpopd cffjk murcb jmt raace iwt -aobgkja drc ztkd qskxxbv lve lev rhhoqex bmd eolf ybxjr yiiut -zhjcfms fpabnu aozp delsc mge yqi eovg pwefafe -gukf iys qztqxz xhsssz pfqq slg jdbp pfqq yabztc asow ygh -fmr ijgmjrc zbhwsmx ylgccz ycydcyx hjjset -zybsr iqisbs hffmij ikby lwufzvg gwd -ruk rku kur ydurp upmebe -baqide zdijcf ezqfe ovrldez delzrov szimd irmk busim ppv zepqk mlwpl -bxlvp dxumme byaada cgyn diz -xlxr jhili bmcke nkl vuhqsn lxzb zmyuxgk qcqr tyxe -wvth gyerrd yewrta kgri yewrta -fall jpyuusu lffybb ivmtmzx alfl yjupusu -lzvcg xwnt mjyiklh vwlz qejj mjyiklh dmcwq qejj -vgutb smc yvnsbgd bxmjd qmhia krxz luhgg emnrp -uuvhtia aiuutvh brstbr tsrbrb -howd japlq lhk qtsfdq htfufj qkyywy anxxxqw jtmryw cdtajh -pksswl jprpccl wpklss yyrbo -furp pfru bftha iekamfc bixwmr sslovex -nrqobo hyb byh hby -mugix kzlbtuq hmju ysstccs hmju btsuh -hsrlhw zilj jtvto zilj fjq -lvol xic hqqdeo gmsug yqe wue vhmrq buj juv wxexdot -lqeybb odpv mttm bxqy vqbqr ylbei wyjcxco urufsuz kyq -youbiz kvrea xsfcp zaz zybiou earvk qpf -bowsref ooobtic apiushu kplpyza -hxfhoyy ybbe ceebt recegzz ftnlv ukaf gpvx opvd lqnvk ybbe ygnwa -jpbgc aahm aahm aahm -qyvheb xyb elt oaksuj dvgpmel poiowc ykgbgpz dxpit ytg -vgsv yrjo vjss kyfvim izwo yrjo vgsv -hkk xmqx crlki dtp nuh okef okef xomktit viia nuh tplhrx -bmkjclx sbwe bwes bsbnqd nqbsbd -gfwrl vocwln hsuxkz zpclb qprrvlt bkcluvs pqy sxucrla npb fensz -adjklj nyr btmav roxv jrri vqfnis gzsab ogskmaj -bvjm fer ztgfx mtp vvhps hptzrar wpy yhvmh qklfwpf edgrdts vmhhy -lngra nrlga xokqu mgq -mksdk bkkbfsq hazlai nixee vyxh hpvebeg jujoqe wkw mzpxixm -kxrkkx qivtt xsm xsm rqvgdjl jilosjs rji -xiqga rez igqxa odiilj izoiwf xgqia -aepioo krcr aepioo jhigtx krcr qubkv jgo zybyvy wbsguz -ntyscmf duwvvb kga xvaypk sfjlg daguzm kqat otj zmnki -ggxaery jazo ggxaery zevobo zux wfnd wbyd hmhmo oaakvab jsimsw -vqdnvgy qiex yqeweds yqvdvgn iqcukgc bvrc osi -esjzak krwe ivbri hnbah iuvb begybsk ctxmlym gjqi lcscum -hyxdilx tsv evckza bdbscwj jlihiqk dciuj hamd dqsm ydihxxl -lurtwhx ygwf pwhj whxtrlu zfvywxr gcrl zvl wienpqb woto -mfaektr ocvho ukfx ukfx old daqwotk pybjtiz kumkiq tmql lqou tmql -guwy ceqsyvs svteymr nrovwz tesymrv rmsveyt -pigilsu zpyiohn zpyiohn xzl pryi zpyiohn ohdz -pziqfg hhrzdr wxl zpqigf -psnmnxz oed edo deo -tkdp tkdp auozn tfyo wmp jtp wjyskeh dag ojdvw gbptp deiqi -xkr nmsbk mreiv occcvva eca bupc gvaoopu jdhr flh ptgdumz mks -dlevn vmwzws dlevn dlevn -qwx qnuqgc rtzc yvym sft wxq fhv fts nyvrfxz ydjvcq tnwz -debkk pullndo ezaibw ldnloup nllupdo wiiw nij -hng rpd aud epq opzjh jnzge -rmtauf nwinyl nwnliy pjzahm lywnin -cgiv omva fos irse uytiqu iqjo riplx capa dhdl echbyjw cutfam -fqrqmi jfrj zllh gfhhq fqrqmi mmyqv -yoepae uabuxlz jzqy yoepae sxena jzqy -bfr jlrycal ndg xejwjdp khwg wckevqb tud xljzem ntfbazf lkr -aomdwt sji sij jsi wlsvvva kgjzqj whhf -ogorbil orlgiob iorlbog xapwiqs jxb -tnn sxgdikv ynick ynick aumwthl rwhx eqxd jdbzyk kbil pmnifp dpeips -vzeoilq son olqvh jawmny -vsifce kcighpn mubl zkgwm -ncagxs ilohd lyq oqhjf nfeij qmtvf qpru tfmtaj -pfjkcpr dqrfde efqddr edqdrf -wdyygax hscx ptmro wqko ecnfkhj ywui -gdv nrnrzdc vyq vyq vesrj vyq jwxg -oqhrr daoew zpoduh zwmoss nfkh vubf xza kju rhrpt fvsc -oqp ppyq swvin mut uacwd swivn ucdaw icfj ldcujh cejl -dar bqp ajdhuej sxwt bqp tppexrh tppexrh -sitplaj xnb ldopp mqd gwtk uhnvozu ljz dqm ylzy qltf gwtjksx -eqkvncb jdp pahwje avhrer awb zqnwfhx zohmcz fitbyab -xlnel gjzviy cndpuoj jvwxs qsd kwli quisju kyoix imzg -czqjkk evyima ixpelbv eobpd wwuxxof pbxc dgj -czsigs lbdaynp amsexn aemsxn easnmx rsitdzf -xdpc xfbp lrjwlo ntnnob sbe bse -suud fws zgn kvfimsi -wnexa diexvky oemdq uasxzhq qxa kevyixd lpw unluohs -ylruxt beqvn vbenq ogsov mvftu sovog gshtb qriaxko vthgfr jwj -gmz wcjb cqjlb hijz qwuluuf xdpu jybdf ajiv xizwb -fcxos spz idg rjb uhr ert bxia urh xfxp ixba bnvxy -uxiie eixiu wgmwbj euiix qknyd wtaojk naeqfz qmhnulk uscgwxa -qwyxd jno xelqd isdjht qxz dbwnr bfzhewu opxmkgj igfiuck -ljpphwc ijzic pfsemsc mfedoxy pad wsk beqjpbj gbjr imce xumhr -causc ogypj csacu pdokc itpgjl xfx nyt yytg srhrup bontz xbalwnj -asohjj qer pfgwo qgdw wgdq -gpzvyhh tsnx tyu kswlgb whju zkkpdm bmh hdov -unux lhrn unux lhrn rxr -epq ksew pqct jib pqebafk jib pyfjy gnu pqct -anzbbs oyhm moyh mhyo -dpk zael zael mxots zfcum -aehljyc wrj lfhife xbss ztszba vlg eljycah ihffle coypll -aoqedco bogk bogk aoqedco sanwwo -udmbz yxe dft rzolgtp nwwjpti -efu qcls rtx mestnqt pkh ciekj scrv uswd oroowx lcztvt -urnwt uapni ood lzce -zjiqxt jzqxti infgde xbmi kawilp kaipwl -lsfn kxfw zgzdfq meqwql zpqqu otert -taajsho gbeoguv bpi nxeuy -dpoyzi rqlzx rqlzx udhuwjm qnu bnuma udhuwjm gfezx cbjpfp woir -mjbv isni ixjtjue fwsk ncgwpn vqnmq pivz jbmv qoakqou argval dacvksc -xxjcn amdgdhh iup hlk xxjcn elx -gyhocay ofqosv nldfqay aqu dsrz lmekze bus lmekze gfoq lmekze vkor -xidyqq bimvxu zrkg rpcdca ymg nmxkkqu gygcmp euemr -gvd ywog ywog gvd hwjzzq -byu ggpwrl lpexjcf hgy jee febgcae valcgc tcfwicu texqi lxfjepc qeraxcs -lkjejsb eonp jtsbps pfvlos neop ikwnb avzxnk -big pjgttfb eetr jobjfae odvl jheh tuz ystrh tuz tuz ige -czubaxq czubaxq pbxgs jhuopn snmhhc qwmcka xdhxfuz jhuopn eummw -xdwduc sqcano zopaco ozbbc bczob eas cbbzo -oanpgo tiav bbssup ttzchih tpb xmfnqwa ghdx uepmz fzqbx -ahha zsbdq jggv zfcjdp dzcfpj dkew jxmelbf jgsohj oghsjj -awdy plulzw gdi jiiq lod rog mrf uihaz sebk guvb -tlhwro sapaws ovlbbfh xctruk spzpzm latyy -ligaot xfhacs jvk xbnpu yuanx yvvi gjek -nfwuug nxccj dxpfvfq pvxcvy ayss lfwz wwole ewowl xceybeb efs zfwl -lzowlql armo yrlgfg kbl vudahci yav evdi ofak ysmfjk upe -qtmmqrl gxi rrhbi pydbopp yvevlq ovwwdrt mrppov lzzs yjyrxh srzo -hytkyas wpuqvf fftiso fftiso -yutais qjdbzo kewsi opy ysl zyvyoty wkp -qtbad bxfjkwa stcdk lyre tabdq yler -friyh ivp hshy ksmanzq mzdbbub ncbx mhzki friyh vyjk hshy -ijeysr aww evn ttqvshg xkd zjy honvuqy zyj quvyohn gphcir -okft smja fkto etb -pbi zhyy kyjdho mqsuyic vegocmw gdkskg kgavjag dbqh wamfijz ktihnrg -csqix soz ingra gvslgk -ugxgzqt pdn hiynufo lpfabmi rmwj uhsqoo pmlzad ferdup guzqtxg voxd -wkixiq vck vck sylv ttqcbwv ywqta vblz mhohx frv -phns ozeghgm dfodkyv iyc psnh tedotyz xqz gqbyj ydttezo kxgju mvip -chc jdjo pyq usyn vtrbnq ohnx dsxpdzn mgbc ysun mlalmu mqemyuw -qrkosx wcwcv brvbwo nvxwg bvrwob -bovt gpb rwm gpb pitttl rwm rvfzn tbo -zczkb tmpwtj kackkx yzqkzso rsg ema ereo jptvfd jptvfd flbjfii -fcdyetv jqelvx jlevqx cfvetyd -dtyp wfh rxtpwr nolbro iozrs mnshu tkesvyk pkmkf -lvecoh ohpb brlqwx immgqe dzfac bwlrxq hng clxmpd qodfyv -sjbc dsoqk dqosk iyla lqzrsgi tjgt mfxshtd ztmc -nxveg vmxf jwnub kujji aqkonjl xtit xitt -jsft pmojruo vtvjox wimrlhj rezqi rnv hjnvdka -vnl vzgltnl mry kkqf fekwjw knsrvt nct kqy infvys -jbvm igq gvcl crry ylia nbqcq ouduen jklepay -ermsf emrsf uksuvz zrnlun -ecksf dkydasw wddasky pmfhi yltmedt bdovedg vfnyoze ufcki civrjs ohozga -hvf gfqgc adbeykt jdz zmgonhi yua kifxyoy umsza ivnbvoc whnpi gtbinze -nmy fsdu myn iiw -yrkwca jkxc yrkwca yrkwca kxqtvqh -ildxc taopx spykdz dzbpcxp wzgka cbyr xpvrzbk -qqp axdmvo cmppp shx -uldyu luyud uduly rgcmugh -woc vjdpyq cwshqq tlh fzyuz cbwgp egpy sfw -adyv cnrn bhaxvx ofdbkn yxrtir cnrn -ycz ednsydc bqsdcpx adnq bydb tqy tqy vqzpy erdcnv -mouv ouiy gld stdv gwr lxlfq gdl ldg -gtx bbvr fxytm veofwp bvbr opefvw -pcf scu ovso rawtjxs kzxgnuy ifcn tvibap -ugcbob xkjgtx ugcbob ilkkx dikca wpxyq retqhlu ugcbob ylmt tigcmmm -gmnde ool qeuwc ctux -wpajwn gooy fedmjur pxiq xkyniyp xtgi eyfpc gjx -uaivt kvfyn mpsya qxu kvnyf wvoeaz mbt fkyvn -jth awxbprn kpcodj qxegybo -sfvitld mdzczg pdptzm fmz himb eutpyi mgrde gubsta tfsldvi dfistvl -piabmr fckmhrv twnlnka jyb selqflm iwcutk pvvann -uxjfm rmleg ochuj ruiq aobxbb tpuusot uhwjojw tutopus -dzj qdyxzk oan rtpz ona qkdzyx nkunr -urjydh dfreifg tmbetd aakc vdr dkdkldw xgvtfsa ivv doadb axgvstf -fdjhr ujgbj ulkm dfzh tmhx zfdh ckt ortg -obe ywwge rgqmt cfcnyt atn fdkdrwz lmb zwpe sqfoc yllxs akdlsso -ckhbu jfqhkml abenw ckp xvjy wsyhxox jzsz hqksq -tjx zlh zgyrjpe bdorry uofh hgkzl ezixges kaxlkjw ztijupu hlgkz -belj ipbygk dxe cqoyukw jnncelh ihvom qstbowu rocqsz ifiztlf fjrf nsit -vyswalv reaqae hzoqyun lbci ibqfljz cgjflqf kos -njrzfvu nxw nxw bdsgnxp -gxlgn qrx nspbvl pzuob nggxl ipak wjr lggxn zas -xkd sooef fsayaob tfsiyl -ecldvh jugto ghfpbev xzlc -rpyattn spb ajdplq eaorgi ackirxg knrap cobdeu qca pkp zkc -bhh tczwffg bhh bhh hrjx jwyu gry kkgghnx -zsav frsakbr bvzd gafr homzjw frsakbr yasgz homzjw kqa -nbd mekhfif mekhfif keuoag nbd -mzv vzm utuxhuf uufuhtx -siy tdbii qtu yrxar ruubale yrxar lsvnr yqxq ruubale -wstykuz fxnuszr tgmkw eovvrd ohheh raf degh hzoeun tiou wpt cqnw -dzbyhrv vzlbvn ncoa xfglcye ncoa sykfps ghi -lvi ilv xalhd ztejzb -zaeu diz zaeu gtdjsz fmoxgju diz uvh -zef lmkqlcs jnhgqww qsm fuatcq ixfa -wgp gvu rpmxrjh yokepvc yokepvc lywdl bbvvbf yokepvc -etjfs gjh tvmxb agovg yihn rmmh nue jfil -zgcco slios jbfodb wpthe ydvit regizw regizw qosou slios cto jfz -kmmq lnafaha ddos hrsjtxk zjch rfynx eovks -ezeuzu jfpv oinrstv vsw naoz enrcy svw jfvp kgmfwf cfisxzo -ljtv watps equf ljtv equf -axijki zotolsi ryqujrm xmhug fhz lkgaw umzokxh ktr jsdsfat trk iosoztl -vpqvvvn ydjz tcqc asffcxr rxb fyt vyham fys -agxrcxl obcncq htod ved ozesk obcncq iwqmksk fsijtg iidyy lxu ozesk -orsyqt otqrys pnaax qtrsoy -oyisc chu ahdp abhbtry kjsqve tkpux tkpux sxzu sxzu -wquw umlbwf mxzdbvb upp fopxe aub bau eritni punrpfc esnkyg -jjlzy hozskgo jjlzy aiq jjlzy sgfyhsd -ejghc ejghc ejghc igacslu -unzmg fugzotb nxkdlds ewn hydj fbr iuly oiwwkbg scnozau sfi dsishk -xuhjduu hfloaga xhuuduj mbavfkd nrnl ral erc mntev elpoqgq -seydro onpi qjey skgkiox fbdgyt xhr rhvz dpsjcj tfzd spjdcj btqn -difyxz cdm jlzsz oycm txyssd wckqshu ihya yjyb -nmrhlif wcreso chtqfov qcftvoh lqp egd erc myep plq cjdh -hcnwgkq kkrpxxj gwe xqgea kkrpxxj nxz mumqbw kwxhlz kkrpxxj otqy -rxbioyf cszah mhu mhu mhu -qpbrf jzink ojy idt nrjykzu -omnrq kkol dex eaqdmej dnpaum ynnntw ddwewsh ztcenhc zqdrq hmi -ngmqpu owmcuz gop gdbsfc nyott cdsflq ngmqpu -srus lrexy aqgkqvm tiyjm -wxa qopky glaaekv ykopq lna gyxvpx xwa hly dbvo -vqf sqrqw phxn xiw gejyzip ugg gghhugl zyqae -ylj cyolrx giim yrchuu yrchuu ylj -rixa yfusuqn yfusuqn yfusuqn -lpm gboakz ylyv gje yxu ahokxb ixwnpu hlcka cndhbbm nkmvts xdtqbc -veul zjvz regtyp njwfpm -pdlyjbn edawa xbcmyew gme yuk yek nfknzgn ehjz -rcgun ulv ntbwnvg ptf givapv bych gmxxxf iajqpb gwh ipavvg -qvpwk grbb gptdgrh sij vunv hsb uegsmt uos vkxdd -iun aagzlj elqcq vkrk awl yyt dxfhkwq hbkeht -cgf omofuz zddgwef iyosk hmou -mvjorn zseyo wpfjlac kpxb dlh ggo zgxoso txzuy jfbmv lacjpwf vha -twrsrw pxv iklzg rtfcl kfbcjix uyvowpa kfbcjix ofnsf adqm -qvi ivr plxfrg awugjh fxbv ztlljk qvi jdkfts xyq jdkfts uqwgdr -phs eimuuf lmxq wmp -laf gmuowr rplgkh orentm whor lkrhgp mjwr zapz mdqtqyq ttkfkf -fxk wdbl fjh ojqxp yvs fkx ysv ngksb -oclyxqu tpajqun vvmj twin zclk -srcwxs xiduxd tqpfc sbqybp sdtzw gizfn bpji kaolpuy -pfkmk olmsaz uffy uyff -crpazh pcrzha lew lkhcjij stfxq -nkbb rnlo icnzg rnlo ejanu mofx ujblud -abte xnjfo boz fnxzid nqfhifm jmnmsgh -lvck nfll szdgrxc nghig szdgrxc oytahh cibk szdgrxc -sduf jgv rrt spxw fdus -gplutjv ufep fuzrnj tmko zzpj cpd mvtrzq -ycdiav qvr ycdiav tjngezs mphk oykgcei ycdiav -egbkscg ksgcbeg qmw jdbj -kbgx otnfyc agouh iai lyhqd yzihyq ouagh snzhxa xyxrgz -kdpqljx rin dlxms ukdzedc duezdkc ikgplm ffk vdmie qziajdf ftfwl -prrzhj okffaot tlrxpjd aquc dbonaef enfdoab nwbtuh -vyzf ijo cdhek bvlgxt kvldmp kvldmp vfvg -zhijgyb yfkkal utb brew vfj ztiftq -kodsuol ubnbdv iozwfum ayqxgnj qkp yiiv wbkgi psi wnfa epw -iok mecjsp lccn nrb kobca wkznctc afjjlrt -yrw yhsva hgx nxjfbb -dbdj vef xjssylt hjlld bqbmx ihfmz uhij zoh opzrmy mfq -wqhcq usyfuc wqhcq pmf aryq nhvtkh -nkviwge snpfdza nadzfsp evvdnrl qled ekqs qumle myhky -rgljws kjuk txgeein ajmph pjhdy pmvr upae yfh -vmepn wekgc qfwybl midbac vmepn ddqmbu vmepn uhfccp yuh zzz gnx -hyqv fud xdc bssziiv mwo xfrsn xqehs mwo -djhr qxhfy vdjs ueoi mbmwa lkeumzd hyxfq krbyy ywvcstf wdkum xfqyh -heprtex wgxpign lvm vlm ypswfxr ggxipwn hdszz blrv ppy -fwalim sbqj zewxcaf qjsb cjgujwr uclxro wceu wmaifl rnd -gmivd spncot jxeycn notspc nzb wie ceyjxn xlam -cfujai hfvux hhtwe hfvux oputz oam -gmwu xwthnkp xwthnkp mdxa xwthnkp -shfqzi hdq uyyqjrd wczfvy wciko hdq nuywebl -dtkq qnb uzmo ypxfja cekqe cekqe tnaibc uzmo pmtnb -apdz exdze pop pvm pce hywvftx jrjezgd jkajq jcdjli -satq czv cfhyca cshnyh cshnyh rcu cshnyh -mxp ujq fmrnzxx xqv mxp -nel whnnxak lwzlre mrxq kpo pko bsa gimtzwb -okssco iuke vcnv okssco liawwc vcnv aztl -kjvq rye eawplkw qzxt jkqv bxbfyv -bphssax ylemih wsm jnpxce jgh repsyj ieypbz asx -dwivit ptcwt qwectqk ttwcp bklpa ivditw -ies knj zemmcto mczotme yanr kjdrwr mcry ndols -dqzdpg adb ulsv ulsv qux ppmoru sjcn dpihqz -akazkk kssdguo cgigktm indfh wwh kevuhv dclpjv kgtd ehjxous -spogxy jyzhag qumd brk cbu akbpjxb spie -jgyn cxbar axtkwh hktgcm cfsla xll rpauwl cgpziuh dyc brcxa -dodey dysnjxe kzmyytw tzddd cnupwmv -nqab whxkb kvc kvc jcjhywy mbbpfwj fxozlt whxkb qwz -ihmif xhjc lmfk yjrsioo uvtd qvtqsgt dqd -uvzedxd afli hkrigd lkzkzu ncki toam hoaefui -zmvywjv jsjf nrbrgt mbs yog eexuo -ukzab euwb qnkanyt lgeqf qefgl ewub -zbol bolz ilncu ciunl -hjryu qyl ajwju rplplr skbdsl xvto -ojfotbx zvta jofxtbo ejjnhi jyeiz yzeij -ivr pvrwef ivr zgnm jscgaoq hfjuzju cea hfjuzju ehszaz -yikp gul ugbniac jehm fwqxb hqbhi hlfr iyuuf vacrao fwqxb -plsjh efu napxwe jfxfjz efacqcp sythfxc sythfxc napxwe qncqc -meuf rcjzf mhluz kbrk tzjrcn omoiprl khs oyzad yuzbz -exvzzuc ckqfivf uoyidkg mwztyf wxtg uzrls gudioyk wfihpzn tdmwhf -qoovwqm bldswvy xkb yqrcluk qyrclku cluqyrk qgakbv urclhse -rmmymgg ytpqtuq ibt tmedibz tmbsdg ytpqtuq cxbnng -qkyeo frjjht vkpt ikztq avzqon diw noqzva dvkhwdt -opz usos kdqseyb cdxvve nahjc hbr rhsfm hcjna wnczls kky -sgeml uyaoe ked utxab hxqa glems wbdo kzrjsq -isp bmebt becira ixoz yeakj fmueu -jrd qyys cik bmaief zxllza rsu swvodiv ivvdsow ikpvwaj jdr qte -gzjjre tkjhdn lrqmvw gues ositymc xhfiutm -kcnble oxoh zggvo zjz auub kunoj snil zggvo lgql -yyfmd wbwmizs vmb clba bpzzjz nlt wgukoe hedlp osxz -skic mgcr chkj eiiy kdhch gcanziz dpecug fccp -jhnejy akpwbj mhrunvm wjzwyhe lwxostl gfe niuhj iuf bewur -nuursk gehzvck szm fllr bfaq ijpjp gehzvck bfaq -ecx etrsadp lyekp lxf flx tadreps -gbo wzkner hky ggoqu -yiitvf tyvifi xpnbk iiytfv -okpjxyq mmxcha pujgv ltgfdk wpporh bfle tuupth ukyyjgv vlnwhz -phbs qtpolnh udito ukx kjqsi jbwf sgkkwgm udito mwwb wihg -mces dhc qccy sxyilmb qmki dyqnr qsh aigaemz oofdw hbifiz -yyben jjklnz whwswg tox vgytp noijcv jjsa ybney eyrvg htjl vxli -detb tus rloz zymvmg zpe -usvkehi kxgvo rna scnaljd jmowud ipfkkf rxvpie nxysvj pvquagf fjhsvef -ytosun puwdoix oyc qdufuw ysunot -htw biy htw oxot oxot -xgzi nbq lxxtmt nbq lxxtmt fnzmmno -lko bdbj kcqvc torg enbfbj sbooco afjbclm dendwq -cgih ikmfn lyhzhxd ubq ixrori tofbo -glfhfzs gihsccj yic mlci slne -wdiu lhl hdlhzo voo yhqckcy axnz yqyi fyss qhvtsbc -aotbk zfokegh uax myhehay terwus hmzic fdwojh wjuwlp -ucbiex eigq qqe ifqw sxakwl xkwsal qeq -pknvybh qkrwi povvd phairw qst inklob yrryv bcuv dolvr okwe iexrpbw -kkah qrt dihygsm nly rblqvrm sxguxj yspmre -gzhhkjt uimif bssle vdiaa wkohq nrgboi htkojiw -aeb xihgva vwcjbjh lri nlwbxun sargiey uyekrc -fnnwfbj yyccaxu fhqb nlmwhc ymbqky ooljix mfijg ryykirn womn rygezi qsdwgpw -itfs udfr sitf gml -gknztly vay ypy jpid pyy mbpfmwz pfmzbwm qqec -bbhmw uus xffgd xcjzrlk kyecv zcerxe -ncpc otqzotf godtu yhcpsyw ncpc fbs -ggoiqm ofk pryqt kqdbo ktek kklhlju iqgmgo gqoimg flscx -gsgmvy tktzj kgi ikyz pthtk hxt gik -bunvugy fefqpkk juwk aent -atm tma dzyret jmuqke xbayiit jumqke -dilfw qws ldwfi lnujld ywrogk kjh adaj khmlb hkbml -veaemc xugf udpphf mydi jbvebgp ngyhly pufdph vbgepbj -vyd tisntn qmc yzal -uxdlc piw mwjnk qiar xwpspf sxktemh jmw -qhhvar pox aed bgwq doe uyktv pox vriy ndel pzx aed -tswei dtfb yhj krxu yqio wtzpm wtzpm yqio -bjzp zzp qdzdfv tzkbl nggbfqs vquqds xiud xgrkb -ffvjfwp jbzslqo ffvjfwp pchzrqv ffvjfwp pkd nlav -czepixn yurmsw ucckih qqlnxjj exipznc -xeu llc jnmp dmz pnmj stqzao -fzvu uscqp xerkzkg roivhri fzvu yiwae xguz ajpg -qdzk uyyoi cspmnc qdzk nwknfx fnngvla cbl -acg utwrv cahupdm xgat elb aemkf wmkdzj kfmae ahlrwu yxfcj -vdumh rcd rgc hpqk qeum fpgva qkhmuji rjxpuzk ommk -ztvm ntxkav ajv avj ippodg sukg bivcslu tes gdlrbnt bdlkaye xpgslef -aygsym pwq owxmx xjw -dkhykf pfqeyo lfq saoewy qldrky sdgrrcr frdqn tkfezop doo saoewy -cwof mqlscm iqxhb nnkex nxx glgpbn -noq zikmeyx yodahj ssu qqmifa plcbv rsahsd -nvc fuwiyq myv hjn rtuoq zoyp rqnt xchlrg -dziscfa nbzsuvp rbnrban cjdprp dkj zcry ckxtm -stpm ifcbmmw dpkpzo sot ydpeydw nusp nkciqa psnr -udikjfr foqnxl whq ojuspzz ddyz emdktzb gfio mnd hyb -vchdphx zkrtky ucyifqx ryzl txdixd cip aid cip -wcz ywzwpp viswpsm qfus uzopaq mhps sidjky kipvjg -wehhc rzujn urprwzw gkwzhk rhrpph xkzzl rzujn yddlb -wlhif foh rpvylg gruiqdv daih yflhbr coe yflhbr hvluddj -hfzi ffjntj fdth crkrzdr nyel nlxm cawze bfjz neixnw uygqvmw zayf -guthfwn kcinec glhaiqv rfgbi cbrm -mvqv lszqu eyjn suq lavyjbh ujivbza aianl wik noy zth -zkn ren ncoyj fppsy dwgtgqz til -ybxepr hrzcrxs zhrscxr uvpxxl eprxby vzgg -xhi zess zet mtpcu ibz nkwq cbzb etz kjjcns -kvmu rxgw xboplw enlqcxi uxysl xboplw kvmu oqxislh xeg qwhdc spsddge -dxaao ltjjn cpsvnxe core aojgu pbss nudwi -llro yoy tixzyc beim qirnb lffcr gzm -quxetbf gfpll gqyav dckhp xbfetqu xaebz xuqfteb -fblkc hsydxqt bvmwujr rak -epeohq olrwyft cmrvov fbdyxbg -uzqk pkhizw jbrnlvx aqkq mtmjmy gpcln gaqt rinrz gwis gpcln -ttkcu ttkcu mcq xao lhnxdph djj ylet atdln xao -pmwn svqktkm isopar krrfbna knrw kbm zsohxrk xlsmm knrw cmoikq etqeggc -undrw issrttk mcoe pvufl bwjwqkx jdz undrw vje -kfzqbb djpcjv ixctsvb rqsntv fcqz -agezraf ezrfaga pftdwrk slsxu axw -ezvkn smwko utdlu nizby -ygl dwtrpsh qzz cuntrr hdrn lujcx iwc bll qvjhg -jrdrvj ledrjp noqx igodve odgiev -zonvzgy ujnzj ujnzj zonvzgy ckzd -rmg lmib fdn nfd gfobw wrc iro nsz -acgxvh sdn zcef sdn jvgnmhi xitkqgy tbascbh -ykuzk ovp mikolx xxgpylt secuf yrtilra wnoypy mty lmnagx -wwmlins mxwye kjntv sadc wnvyoov rzdawl -ali ncsrq tcbjzpu oiw iimxlbp mwi hdvdl dqnicf lxit -sql vywv vycj nprzb tdqe qwvljm myhpvxy hdixbk ywqpn xvue vrno -etncz etncz czqw moz uaxbtm axlslow fhephy moz -wsriuaj umjkx mhxau luzf wmo kyx jidl ufuoz cbk -msfrvbt bxnd msfrvbt yut qwbx -rhag vfkqf rekoz buw qffvk wxs ghra -meignx dhdu xacg hmiqkd nrijc gcxa gwap lov ybtyr vol -qoqns swib mlegyjn ojdtt tvdrrhg oetg xdret nzpq -ntc zowllt dwiyht ztdeifx velaumx jfxxsqt uefmb gwn -bgykxl bykan tvvgcpa wdcsj coonage hpocfz sqmihw pnagv uozsh -wass vve ngyd yyvxmsq rsaypsa newxyc adqmbm xqsvymy ygdn idysq -ybo vpjcf tsbpc hcdszr qrxwjqr bzz tgjhkpu hgtxkt stpbc woro -ogszrg rszt owufa cohmv msygfw fud fzi lhts sfiy dfu gxsuj -fclumcq ejuj jkbu hbsv ythmpoo xdzg dkvrdue -rbf sunzzl sokgih rngqli xndnuj rbf smiea mqzpzb fwpcx smiea -uuuxchs uuuxchs fzna qlj tcjnv oghk fzna -zuiyk tbn nqma wptoecs xndgbqm mqan wmcahvm qpir -ztexf pqsc icxqsuf tkgr itnn yorg oyvqaj yoxggqk lep -ehm hysd jfv iugyt jyvh -fenjp zjtvvhb xfe dgxoah ljn ixvdyi fenjp odnlr -uosxyy euicgp lrsc euicgp mcszotm kvxrpk jfo oxu xyeiv fhdwl wbw -tsmdp gshgm kpb tlx kfznsu gglefv pkb gcnydo eavgrc rgd lgefvg -xuq svh cmzt bxxlvfm rtblxpu imuexhl lbre hqyedxa hwkgaak -hhlfj mlrdv dlsn zgcy hciiuzw uwciihz iizhcwu gwx -ukqoj kjqou hlk nfyz lusf kebvmrw ccaj ewmicq useba -jlnnl jsmox vnw ucr ggithr usqe allzc pfumkkm jlnnl -mswpbk lffjwq icc kef zlba uolrrl fqlfwj tbc -bfmra hdgczrw dgmnod afbmr fnczx -dcqrso cgbymsg jbx ofpbp rmtygip syly -yrmn wzkt lqys tzkw sqyl fxoc -wal zgjy cwnqyaf bhz dbpft owx -xnrautk dlsyot nzbohog xmzsbh soec wyy -kde jpkvbs eyzw ukgiv ggrtzcd vikgu mxqy jyh crdtgzg ebzet -psg jsykdw drpqzl qzqbge ldqpzr wsdykj lmhbldv hbognjp nqej fmxoq guuf -ueo ncedaju ijasprn rvxb mxkddl qvgdlbx bpj bpf pxewuf chvo lvrq -zlmg eciyqi xfbeoq pupyrc bfqexo ituqab pycrpu -jsk clo vqxzl aja jfbce ldov -muss tzg iksvdej zpw fxwhrv eeye fxwhrv -kjjd dzf zkppx qdwlx irudds kjgd pdrz rgogy qdwlx egx rjxldp -szjpf aouvl ehxq exqh -nzweop qlkje welkfs jqmvqi coc -ivmjzk usk auvmc vvcnwn qubihx vkms fbt udn uyto jjt kxqy -rayw ijaklcr ywra qkj qytxeh pmnfh qffvsft tyxheq -pea cqy tkg qidvx qidvx pea skgrndq -iijm xgwq zzpskl qtjezqt yqjwy dhbq -dfuv iqw iejb bjei iwq -ogrmldp xdc dcx cqhbwlp -wzwb xrjl keciql ckky litdr bmurdk anjs nyggesn ygwt svmee -bvkkzj rcr lozrw mgpwkm lwm yecsr ykl tzny aeus jmq mchopp -rsnvaa oikce angqn rnvsaa mhc -hsiov kxqpxtc rzh vjrqlx xxtkpqc wiunol qckxtpx -aosek lhi ruqgd rmr -agqvlao pvhcgz esw kwnpefs qsrvxz hgkgrs mpx odaiqi -dvqkrzf dawioo jtaco oeutol ravp apvr frjunad -wss nahhsh pfwgcfr rvvvq uqxxmhq qax vtrkfou medfj -imdyfc sez gve kgtryl kmqklg -crmg yhkpa bsfouax kyttpa who mcrbzaj kcsktxe yfv -zpw zlab pzw pwz okb -fgqlb byhkhfn qglfb ladle ifa -skr zwwjnr iub wekt biu jnrwwz -mpvt mpvt havn ztf -odqhd uxrswp ppj eztyj nxzwm fvxyadn tostwy odo abyp meqdm ktqkvh -fgufup uabd vhxem imto imto vhxem -vrpxxhi kii zwatqg nokg wesxju xplc sumte muwjj -nsse iquhoc giuv pxaa qpqn zrfk kywjr spz kgzc lfa -cjjgarr psvwoap ivijyt nfbxu ktiuy jajrgrc goyc -yrfzf wyxda gsslsy oeyve jczghf cbuwf iwnu izyrtho dyoup toizyhr vzzrr -bwqgxsr ufy cnouypd qwxbgsr efdkfe rwsblis bhvyws oodh -piqpez yhqahjp oxu qtomld -vjvpnwy kajjaim lcxmbyd fkdy ywvvnjp xcn nbwlklo -qghq mihdp vuv ocrzsw mlmkn rgnbfcm qgufcks btlulb effsrih -psazbfo vbpr efcspj yrjl pqjrfe relxjc nzzvb yviuhc -tbbhdbm uxhawtk bmdhtbb rqxrr pspjzx krtmf pnaz srcej rsjec -owikzec glvbqy jhknyuz jkaxu ldhnlpx wdp -qvuv wteohr daynue nehs gzqu porzrsk cqokye zzsbqox rqh ogxtn pskorrz -gnm grlfoon lxid isxa -jes iixswl umgbg qfixa xnecpns asm nopsmo axaopsm qahwpqd -orr auvlruu mqq uurlvua urauuvl fjrcuo mqht tkdgps tdvnhvq iezdv -txwyzy zzwk bzi etfg gtef -qyydr lllgosq qyydr lllgosq -xqm uyl ldpowm pxhi ievvvez hmhzwmr ldpowm jaw -qlvfq efgivhr rfhhu gvw bxgsrp sgbnjh ekgbp cyof rvghph nxfekia xym -lgladv ogj cir jxx msz fshf ayheu wpmke zckng vgrlv lxgmge -fcmp aabxdp hpxbb bblpy mpcf eju pnkv jxwoy hmv fgynps pbdxaa -jcrh dgg lzyiv ojop vhk vdb uinoetv -utlzcf ziizdo njffmxe uhyjxdb cztluf yjdhbxu -ubl cgz tyg nljl -slwe qaos ybcwdoh ogazkj tqh opggnzt ffrscl opggnzt izeh -evitfwb jpivmn dpnxzuf gdkx zprogl xehb -dktt kpnkizb rreq gjmosa iekdtpj rcxk eweawk qrre olv -cmcw vmw mujx mujx ypqfz -nzxcl fzwa ftcrc immendi tmxzzi hslye eibc tmxzzi -abfc jdqvk lichxx uiomtz tlq -mnkthoj nohjktm eued izmcjj -ullh wju bxfsif icnrmmj qnufw zubcnmo yewz phovhv -ndfvd gcyt wnm badaww twm jahlat ndfdv mtw xrq bechxx dnp -ceg gcxgu gnudeib utsynwx dpg wpsnp ahbbvkt wpsnp iou -wutcg congyz erkj ibtcics -xsbq lyycse qbsx ppgutls lroo tyor -hfiwoy hclhl gcwgqox ogo hlqr ultkaz yke iwohyf oog -bcl nemims udwkmlm nokck tkwny ulkihcu knwty pngamqg yxtphkn kuihlcu -nwsr enrutc eqcfb uxmdgju rfnzhsn tzk vysc -wbtki vjmkk kvjkm ibwkt sckvbv -xjxnow tli woxldj rotrtz nfkhcz ibh mla ybxldg -cwtpkhr oxywg qpwrgfm dfjpfuc kpcopa -byczby tbfkonk ytlczzf bbyczy -khuvrne rnamlgt akjtu qlx odr git xmiazr icwsxsq -jfm bneh tkdzuad bsr oruvmqq uauw zjlp gwov hot jkjbex -jjo uvk vlpy lpxd irntb uvk ehhsqv fxhvt jjo fpa -qrwu mgnw hvflf ytspp mco ikvbqg fflvh wts cbbf"; - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let worker_input = - input - .split('\n') - .enumerate() - .filter(move |&(pos,_)| pos % peers == index) - .map(|(_, phrase)| phrase.to_string()); - - worker.dataflow::<(),_,_>(|scope| { - - let phrases = scope.new_collection_from(worker_input).1; - - phrases - .filter(|phrase| { - - // We want to allow exactly those phrases containing either - // - // part 1: no exact duplicate words, or - // part 2: no anagrams (duplicates after sorting). - // - // Technically treating everything as bytes isn't utf8 friendly, - // but whatever; `String` doesn't have a `.sort()` method. - - let mut words = phrase.split_whitespace().map(|x| x.as_bytes().to_owned()).collect::>(); - let len = words.len(); - - // comment for part 1, uncomment for part 2. - for word in words.iter_mut() { word.sort(); } - - words.sort(); - words.dedup(); - - words.len() == len - }) - .map(|_| 1) - .consolidate() - .inspect(|elt| println!("part {} checksum: {:?}", elt.0, elt.2)); - }); - - }).unwrap(); -} \ No newline at end of file diff --git a/advent_of_code_2017/src/bin/day_05.rs b/advent_of_code_2017/src/bin/day_05.rs deleted file mode 100644 index 25be4f410a..0000000000 --- a/advent_of_code_2017/src/bin/day_05.rs +++ /dev/null @@ -1,1102 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/5 - -use timely::dataflow::Scope; - -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; -use differential_dataflow::operators::iterate::Variable; - -fn main() { - - let input = -"2 -0 -0 -1 -2 -0 -1 --4 --5 -0 --1 -0 --6 -0 --5 -2 --9 --11 --15 --3 --11 --12 --14 --5 --16 --3 --13 --6 -0 --3 --17 -0 --17 --5 --1 --26 --21 --14 --20 --7 --24 --26 --32 --41 --2 --18 --18 --13 --28 -0 --32 --3 --2 --14 --17 --54 --22 --34 --33 --34 -0 --46 --3 --44 --58 --10 --56 --65 --46 --24 --20 --4 --27 --41 --33 --31 --20 --75 --73 --41 --36 --31 --70 --46 --1 --79 --61 --51 --77 --44 --55 --2 --18 --26 --50 --79 --59 --69 --62 --80 --13 --69 --97 --71 --24 --7 --40 --10 --23 --85 --97 --103 --55 --90 --40 --60 --98 --95 --39 --76 --63 --12 --2 --65 --109 --47 --12 --37 --5 --23 --125 --124 --49 --91 --70 --134 --54 --122 --135 --12 --23 --22 --83 --40 --133 --77 --88 --119 --146 --26 --12 --108 --63 --111 --148 --99 --77 --77 --76 --89 --37 --95 --105 --76 --137 --151 --146 --141 --162 --12 --68 --36 --116 --60 --73 --61 --60 --101 --168 --142 --143 --118 --165 --108 --179 --180 --11 --152 --67 --33 --10 --169 --155 --16 --136 --165 --164 -2 -1 --28 --131 --86 --153 --116 --113 --149 --66 --64 --36 --168 --116 --159 --15 --180 --125 --146 --135 --105 --161 --133 --207 --192 --192 --99 --146 --93 --21 --5 --189 --86 --16 --4 --44 --167 --20 --201 --110 --103 --223 --182 --71 --194 --68 --90 --237 --147 -2 --88 --184 --90 --12 --119 --85 --138 --179 --152 --158 --82 --122 --179 --191 --120 --174 --165 --137 --181 --58 --250 --66 --194 --202 --171 --179 --137 --250 --248 --167 --108 --27 --175 --34 --254 --35 --157 --158 --31 --52 --236 --238 --247 --279 --209 --257 --167 --151 --7 --182 --2 --149 --87 --245 --141 --238 --186 --71 --97 --128 --147 --52 --93 --142 --197 --296 --73 --89 --14 --253 --190 --295 --312 --47 --236 --233 --238 --305 --121 --191 --251 --91 --307 --77 --228 --300 --197 --91 --191 --299 --77 --255 --51 --232 --64 --198 --187 --96 --86 --203 --216 --203 --343 --203 --78 --99 --174 --269 --349 --173 --52 --233 --154 --151 --304 --70 --235 --106 --226 --325 --142 --192 --115 --170 --15 --35 --174 --267 --108 --374 --128 --60 --131 --364 --371 --56 --96 --365 --305 --140 --50 --220 --179 --43 --356 --120 --216 --276 --103 --389 --28 --393 --341 --74 --85 --361 --68 --111 --4 --216 --263 --115 --194 --382 --285 --176 --145 --24 --59 --291 --170 --358 --226 --355 --292 --185 --297 --156 --248 --332 --319 --311 --46 --170 --428 --222 --35 --136 --206 --81 --330 --89 --75 --248 --42 --52 --24 --39 --129 --228 --242 --396 --222 --433 --168 --362 --4 --345 --395 --435 --14 --439 --136 --267 --417 --107 --177 --8 --208 --219 --222 --453 --155 --183 --252 -0 --173 --71 --164 --187 --80 --292 --246 --89 --217 --227 --93 --244 --82 --51 --23 --283 --261 --50 --384 --415 --149 --103 --481 --404 --267 --80 --61 --130 --228 --310 --319 --186 --88 --173 --40 --69 --231 --398 --342 --176 --33 --304 --232 --220 --381 --436 --74 --116 --398 --467 --341 --483 --137 --5 --437 --67 --296 --137 --166 --216 --192 --307 --68 --319 --296 --524 --308 --68 --21 --515 --531 --221 --173 --261 --200 --450 --95 --366 --14 --29 --23 --173 --397 --373 --283 --104 --246 --153 --240 --378 --306 --495 --518 --459 --459 --340 --475 --96 --347 --8 --365 --7 --482 --113 --223 --313 --456 --89 --205 --507 --538 --115 --310 --484 --96 --367 --582 --32 --550 --247 --257 --479 --165 --346 --514 --188 --180 --506 --117 --92 --128 --507 --387 --52 --535 --210 --221 --560 --245 --70 --552 --99 --529 --607 --263 --345 --253 --426 --351 --92 --489 --478 --226 --606 --287 --277 --432 --336 --418 --94 --2 --192 --600 --454 --26 --3 --630 --294 --105 --439 --589 --425 --623 --451 --487 --117 --538 --78 --126 --485 --326 --455 --370 --389 --379 --158 --441 --524 --435 --160 --198 --172 --313 --380 --128 --166 --562 --427 --23 --616 --95 --188 --417 --419 --589 --488 --377 --520 --412 --348 --359 --488 --108 --409 --56 --460 --364 --233 --352 --59 --313 --609 --534 --432 --104 --514 --68 --83 --305 --308 --645 --535 --624 --453 --630 --274 --98 --280 --38 --443 --620 --411 --624 --379 --373 --338 --410 --382 --171 --645 --430 --294 --696 --513 --659 --690 --558 --2 --325 --234 --437 --610 --158 --186 --539 --405 --78 --100 --311 --201 --558 --604 --386 --457 --125 --419 --680 --147 --237 --107 --155 --550 --565 --214 --528 --353 --637 --6 --634 --332 --92 --474 --289 --617 --141 --398 --367 --537 --369 --88 --608 --699 --257 --602 --276 --406 --92 --746 --398 --387 --234 --331 --225 --480 --667 --264 --299 --673 --265 --142 --512 --573 --508 --551 --471 --270 --328 --648 --625 --779 --232 --393 --749 --84 --240 --59 --220 --55 --224 --350 --130 --23 --239 --105 --2 --762 --702 --163 --94 --350 --11 --176 --43 --654 --136 --348 --215 --67 --599 --757 --636 --367 --61 --209 --623 --342 --111 --93 --14 --613 --362 --837 --734 --468 --803 --548 --699 --744 --429 --243 --633 --382 --780 --668 --498 --664 --539 --781 --525 --697 --715 --126 --276 --504 --175 --592 --688 --92 --548 --298 --33 --532 --674 --57 --531 --488 --310 --90 --757 --496 --132 --733 --701 --61 --797 --215 --319 --700 --295 --572 --41 --140 --176 --479 --560 --164 --338 --794 --132 --453 --709 --445 --802 -2 --336 --562 --802 --878 --547 --368 --502 --574 --275 --687 --560 --432 --423 --174 --367 --59 --605 --340 --626 --142 --601 --488 --299 --466 --521 --783 --140 --731 --779 --252 --663 --906 --410 --601 --524 --332 --750 --556 --730 --749 --294 --798 --93 --345 --316 --186 --634 --904 --237 --134 --765 --953 --170 --854 --910 --99 --782 --564 --505 --49 --827 --64 --297 --548 --841 --598 --414 --184 --67 --99 --880 --855 --722 --725 --582 --416 --473 --339 --491 --162 --311 --43 --938 --608 --524 --212 --4 --945 --544 --879 --382 --21 --512 --169 --284 --140 --588 --407 --56 --610 --75 --412 --321 --801 --881 --220 --388 --116 --962 --1007 --862 --20 --409 --116 --943 --558 --1001 --548 --302 --165 --730 --1012 --669 --875 --393 --979"; - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let worker_input = - input - .split('\n') - .map(|phrase| phrase.parse::().unwrap()) - .enumerate() - .filter(move |&(pos,_)| pos % peers == index) - .map(|(pos, jump)| (pos as isize, jump)); - - worker.dataflow::<(),_,_>(|scope| { - - let program = scope.new_collection_from(worker_input).1; - let address = scope.new_collection_from(if index == 0 { Some((0,0)) } else { None }).1; - - scope.scoped(|nested| { - - let program = Variable::from(program.enter(nested)); - let address = Variable::from(address.enter(nested)); - - // (addr, jump, steps) - let instruction = program.join(address); - - fn part1(jump: isize) -> isize { jump+1 } - // fn part2(jump: isize) -> isize { if jump >= 3 { jump-1 } else { jump+1 } } - - let new_program = - instruction - .map(move |(addr, jump, _)| (addr, part1(jump))) - .concat(instruction.map(|(addr, jump, _)| (addr, jump)).negate()) - .concat(program) - .consolidate(); - - let new_address = - instruction - .map(|(addr, jump, steps)| (addr + jump, steps + 1)) - .concat(instruction.map(|(addr, _, steps)| (addr, steps)).negate()) - .concat(address) - .consolidate(); - - program.set(new_program); - address.set(new_address) - .leave() - }) - .consolidate() - .inspect(|elt| println!("{:?}", elt)) - ; - }); - - }).unwrap(); -} \ No newline at end of file diff --git a/advent_of_code_2017/src/bin/day_06.rs b/advent_of_code_2017/src/bin/day_06.rs deleted file mode 100644 index 10017e224f..0000000000 --- a/advent_of_code_2017/src/bin/day_06.rs +++ /dev/null @@ -1,71 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/6 - -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = "10 3 15 10 5 15 5 15 9 2 5 8 5 2 3 6"; - - timely::execute_from_args(std::env::args(), move |worker| { - - let worker_input = - input - .split_whitespace() - .map(|phrase| phrase.parse::().unwrap()) - .collect::>(); - - worker.dataflow::<(),_,_>(|scope| { - - let banks = scope.new_collection_from(Some(worker_input)).1; - - let stable = banks.iterate(|scope, iter| - iter.map_in_place(|banks| recycle(banks)) - .concat(banks.enter(scope)) - .distinct() - ); - - stable - .map(|_| ((),())) - .count() - .inspect(|x| println!("part 1: {:?}", (x.0).1)); - - // determine the repeated state by stepping all states and subtracting. - let loop_point = stable - .map_in_place(|banks| recycle(banks)) - .concat(stable.negate()) - .concat(banks); - - // restart iteration from known repeated element. - loop_point - .iterate(|scope, iter| - iter.map_in_place(|banks| recycle(banks)) - .concat(loop_point.enter(scope)) - .distinct() - ) - .map(|_| ((),())) - .count() - .inspect(|x| println!("part 2: {:?}", (x.0).1)); - }); - - }).unwrap(); -} - -fn recycle(banks: &mut [u8]) { - let mut max_idx = 0; - for i in 0 .. banks.len() { - if banks[i] > banks[max_idx] { - max_idx = i; - } - } - - let redistribute = banks[max_idx] as usize; - banks[max_idx] = 0; - let banks_len = banks.len(); - for i in 1 .. (redistribute + 1) { - banks[(max_idx + i) % banks_len] += 1; - } -} \ No newline at end of file diff --git a/advent_of_code_2017/src/bin/day_07.rs b/advent_of_code_2017/src/bin/day_07.rs deleted file mode 100644 index 0d4a91be2b..0000000000 --- a/advent_of_code_2017/src/bin/day_07.rs +++ /dev/null @@ -1,1134 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/6 - -use differential_dataflow::VecCollection; -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = "czlmv (78) -fiwbd (57) -twxnswy (98) -dhrnu (62) -yptrqp (64) -vikplll (9) -lgxjcy (359) -> vsbfmt, kbdcl -tvisu (70) -imxraee (33) -qfbqiv (55) -> gwlyvbx, uanby -eolilw (78) -gywnt (52) -dnybu (88) -yiyhuxk (15) -axrep (33) -ajtjym (11) -zjmhab (68) -xcstcy (20) -> iequdmw, fozfiqf, ytkmda, ywawq, nfgmyd, bzumy -dgscbm (29) -sghuxq (9) -jfmuzo (164) -> istoj, jyzrmnp -zjklq (52) -zwcucws (104) -> vqghe, alycm -ldfhqjw (809) -> wpprys, heotf, dybitt -ckbjuyy (63) -> ygvwdmg, pwxorqj, hshbiaq, oxqvzzv -xnalv (11) -owkily (191) -> cqnmo, fhqah -wrbknnc (80) -imakkq (99) -iymrfq (57) -> iwdjjf, zamje, eduxyw -umzsfe (66) -ruvmsg (55) -ewtdu (66) -uwcqi (91) -> umzsfe, tqjzv -nqqxz (123) -> jrkbh, hyyeb, abwmmuw -metyk (77) -> euriiux, zztvgwh -smxwnsk (16) -xhodzi (31) -unscz (67) -> dpavyu, lrdmltp -yrluhjr (50) -> qdpcslx, echdbt, aeeas, uodyv -vvqtv (91) -sigxauh (64) -> dnybu, kpnbj -nqjmi (49) -rsocykv (55) -vqghe (93) -lumomlj (5) -ewods (83) -qggycuv (26) -zqbtgtw (94) -> ewtdu, xpmpulq, kpnjmwz -qnbnflf (53) -aintn (73) -ibnho (16) -vsbfmt (25) -zwake (64) -swpvgrn (36) -vlsyqg (93) -> lrauqzk, gdhekde -zawbrvg (10) -wqgczyl (200) -> ilgue, bwdfntd, zlgst -qhyan (391) -> obxyz, ahutsc -vrppl (78) -rqebmc (176) -> snnxhgn, anucwoj -hhpib (98) -iqdjcwm (57) -xpmpulq (66) -afckhxn (16) -uynmvcu (304) -> imxraee, rmfwij -cybhcko (256) -> pgfomf, dacrm -ylrxgoz (35) -edmzea (60) -xuokqm (35) -rmfwij (33) -gtezger (64) -dmjech (59) -avbnxz (47) -aapssr (72) -> twimhx, wfdiqkg, guuri, qwada, mwsivlf -guuri (38) -> ydmxb, lndfaxo, sjfue, hufrsq, rxfma -uyaarr (55) -jtudcya (98) -fwgdynj (92) -kpnbj (88) -anucwoj (13) -paxdij (10) -cadrzx (29) -odbbac (614) -> lnkowzc, zqcluqc, pvatk, thymhif, gchcumo, rffqotx, juscmde -maiiqc (133) -> apagba, mhhbej -voeps (50) -apagba (36) -drpgz (590) -> zabqp, vercm, maiiqc, egyfwlq -hgtyjhv (23) -> ffqwo, yqzdjj, yrwcj, ilxgo, bvoxahz, iymrfq -zjevsui (23) -> feiitan, upgfr -btzlwo (37) -vzpqvfx (51) -liwqqqi (117) -> ckdeo, movesh, abgfgav, mrlnt -udslj (75) -twhcdv (58) -> uqzoo, ytwvl, gjxgd, ehcrq -qtfzj (92) -xlufcc (1391) -> qlsdtum, swkor, ndsvlr -hghpgj (11) -oxckpuw (218) -> nssexu, uwogu -rlwyzv (86) -wontek (77) -> lqfsw, ejljdxo, jtudcya -zpeuqlo (57) -coibvjw (65) -xuqozk (9) -wdyxwia (45) -zetdtq (93) -enymia (66) -> ckurzc, lcohspm -heotf (5) -> gminpu, jodhx -bttlx (37) -snnxhgn (13) -uqcxvh (70) -zvxhi (92) -yfzypu (50) -xhrttm (17) -erhiag (13) -wbnux (92) -upgfr (87) -hxkeypq (43) -dexabuc (5) -cjjwz (27) -kbdcl (25) -rrmtlri (80) -> jkknc, vvkrst, vblyk, ghiftw, tilvzsd, drzoi -ujaiypo (31) -mgcyq (91) -mqrgut (255) -> dhfrnu, bzijz -zobnnps (411) -cxjmggj (286) -> kmkqsvl, remwhfn -xpinqek (50) -fzvyv (14) -vvkrst (264) -lrdmltp (64) -mjgilv (163) -> ifegka, olwcj, eheeelo, cvjhub -rhqfa (80) -wswjfu (52) -tqbouv (443) -> dtqxiic, chsuzvr -xxyjm (267) -jofbj (256) -> vikplll, vjaqo -zbtptb (394) -> hiuuk, diriz, liudq -ixuyx (92) -yfkgike (56) -> dhrnu, ehzvm -rchhwx (46) -gatdc (35) -zheomzg (12) -> kkimdb, hhomxd -lzstd (47) -zqzrxe (10) -kpnjmwz (66) -qvpob (322) -> vtzfsci, uexfxv -ckurzc (85) -rpxhqmz (240) -mhhyoxf (86) -ryiytg (63) -kmxek (226) -> rbgonm, qgfxzo, sghuxq, hauul -idprbpo (146) -> wkurl, plwdhth, staoh -liudq (19) -cmouh (82) -> hmulqgo, qjsjrz, owkily, jkqbf, bipzxj -pneftv (97) -ulwzhy (54) -vbdycf (931) -> uwrmetx, lruhvsn, hssfwi -gdckdzx (37) -dueof (87) -hooxvp (40) -> rahsrp, uqcxvh -nxgnumb (91) -> hdmdxi, oxxse, jhmvp -vekdbjs (15) -> etznlt, kvwqrd, udslj -ptamwey (245) -> laovxxw, cpdtw -ictgyp (241) -> zbiypv, rrmtlri, odbbac, tkqke -dybitt (37) -> ulwzhy, wrumij -cfuned (17) -nvgnls (54) -iwdjjf (79) -fvifqfr (91) -> uxgbnjk, phckimp, apeba, udzzv -cbtgtqb (24) -yidnjq (10) -bbdayq (86) -bzzsss (92) -zedqbr (26) -yljjx (276) -> wumlwia, rnvlepv -sarwcau (48) -rquaisv (389) -> fbbkkxh, xhodzi -zlgst (54) -dxxzpr (16) -vatlgyb (16) -qojqcd (5) -azpmzli (262) -> xodsc, tzlzl -husns (217) -> btzlwo, sntovuq -wltlu (59) -nzzwzmh (38) -apeba (90) -cflrkd (31) -fbmalu (275) -> qtqbdp, ldrfyi -qnvby (57) -ovgpa (29) -weejuk (64) -ourium (26) -yckuqt (43) -hyyeb (53) -hgrwjoy (221) -cfqczei (39) -bhwnch (184) -> qhyan, fvifqfr, rquaisv -iibalc (73) -> dgmevpb, mojye, zcfztz, qsvyfv, ulxxt, hzxiv, spovj -tlpydjm (48) -pfvoay (31) -vmpev (37) -eheeelo (22) -tzlzl (6) -oncjf (68) -kirowa (37) -uqzqmo (124) -> pgkeahi, owgile -pwxorqj (91) -dhfrnu (66) -ogjqrb (199) -mwsivlf (18042) -> xcstcy, jluccf, pftdcqs -cqbtoo (11) -hlysw (14) -ekgsba (57) -zcfztz (228) -> scyuq, vggwo -owgile (18) -keczktv (10) -gtixbu (85) -hgywlzc (135) -> osysik, fmmgboi -bwdfntd (54) -atoveeu (297) -> crtnt, qnvby -muecmt (51) -tqjzv (66) -zsraq (47) -idoml (79) -mwgimvy (49) -gchcumo (138) -> msqtvwu, feqefvb -zrmqrif (32) -qsrfkq (118) -> sgxil, tiugk -lrauqzk (88) -dckozkt (89) -> kbefh, pnqri, zdnvz, tuzquw -evsnlxn (99) -vwwvjg (1005) -> nqqxz, dfewulo, qsrfkq -dacrm (12) -wnrqkg (362) -nimeytn (147) -> difavgr, idcvpt, mjgrhot, glllgqs, qsguy -bdrerk (146) -> oswqr, gjjyumz -zfdhua (65) -> deewhp, nerzb -kfjbjl (243) -> hatmf, tywedfu -vsijk (213) -> hvtsr, qwhelvj -lcohspm (85) -brqvmh (70) -sinhju (87) -uilshuf (20) -jodhx (70) -puiks (20) -wvuqq (65) -zamje (79) -rqfjzox (86) -yjfazsr (44) -kufsr (425) -> sdeana, byrxbgo, tvarspr -nbmat (39) -gwrred (131) -> aujwg, touzm -svkcvg (53) -> rbzqh, abnhpi, zrmqrif, kvtpc -dasbhc (80) -> pmlim, gwoiid -opnbls (202) -knqqz (123) -> vebli, axwdrai -jyzrmnp (49) -difavgr (236) -> ukzfd, rxkpkvi -wpjaa (76) -sbfhxsx (99) -> pusdii, qqodh, tlpydjm, jgoaja -qaedcl (61) -oxwnu (24) -gtvpf (65) -> knqqz, qzfwf, vlsyqg, anvxtbs, idprbpo -huansqc (29) -oaabog (705) -> nmbql, yodnj, yrluhjr -ghiftw (182) -> gpikz, mvkxva -qfhfg (50) -zqcluqc (30) -> kdwzx, yflpz, aokvbbi -twimhx (25773) -> xsmdo, gpormp, akioek -brdbeoe (23) -cfshobe (91) -jojnh (241) -ettsd (32) -> rzpmulz, fmjfhoo -liymh (86) -hmulqgo (275) -> xjrheul, cykhmjj -zbptsb (80) -vjaqo (9) -wmfro (410) -> mcpyfmy, rzlxx -wpprys (113) -> tkcmrl, dxxzpr -farpozz (13) -> wepvw, zzjmukx, ooenol -wpwxn (51) -izphu (97) -epuiwg (54) -efcqep (79) -dnvqlog (53) -knwlsi (54) -zfrsmm (763) -> aapsp, gfsnb, jojnh -zjxcrv (43) -lnkowzc (88) -> aaqsdv, ujaiypo -vgtxty (199) -> fcbxsf, acchih -grgjs (345) -> uvntywl, nzzwzmh -lewfa (45) -> aouljs, swvae, ybwgz, spdsz -nfgmyd (1390) -> yljjx, lcdleci, zcoyhde -zzjmukx (69) -vjwptwp (36) -spfds (86) -vqbsvk (72) -eyslsq (84) -> oncjf, nuibgd -gvegx (90) -> qhujoiu, dpvmn, cyhnayc -opfey (37) -ypiwj (27) -> pupaehu, hekhbd, kgfldlb, atoveeu, zobnnps, iukfd -vzkneq (52) -> gvegx, mqrgut, bsvmale, fjueoko, cdoed -kynrf (104) -> bnmgqen, iuftirx -wibgm (83) -> zetdtq, dcytmqp, xfxqvk -alycm (93) -rcnhfcz (13) -smbkvwd (276) -> rvwvqij, avbnxz -kitggwr (91) -kbsmiq (70) -touzm (32) -xyfeczu (317) -slnezfv (83) -xpizz (60) -seicwz (964) -> izpxbq, gdomj, jrsbjr -mbjsjy (51) -aoltxw (51) -zztvgwh (87) -rznqdxq (60) -vggwo (13) -tlxdyxj (1022) -> cnztmm, dkjwj, drigjl -qjsjrz (125) -> aqrxpru, polnw -khpntc (92) -> hxkeypq, wfefbdt, mhbov -qrdtzc (35) -glllgqs (348) -> paxdij, yidnjq -jnghyrm (107) -> soebcx, opfey -abnhpi (32) -tziqot (226) -> peyyn, chwoyn -hgdbip (10) -goqhcu (60) -kddex (87) -> goqhcu, rxohrzb, ucsvcy -zfzwko (20) -uhjxtrp (16) -zmzwttu (54) -vdyftz (50) -> ypttuns, gfcfsf, ymonx, fjdyms -ctien (177) -> cqbtoo, hghpgj -jfqlxa (86) -nhwgy (44) -lruhvsn (86) -> ljeiizi, opctg -uxvgnv (29) -cwdoo (164) -> eozev, gohdd -ghkmb (165) -> pnuvuf, nskayc -wumlwia (34) -xryqzl (52) -fbhnbdw (90) -wuijd (50) -dannmef (61) -aokgycq (50) -wfefbdt (43) -zmqxmtf (92) -biioe (70) -wwcqz (55) -echdbt (83) -tdtxcm (35) -tvarspr (6) -zkhtua (187) -> zmbimk, kmxek, tziqot, aewbhax -phckimp (90) -rcomsru (73) -aaztou (24) -pwdoio (184) -> nxcus, bpbmbq, zbtptb -impqm (64) -> yumbba, zltzea -bkjcc (41) -cnztmm (255) -jdbel (87) -vcjavrw (60) -udkba (87) -jretzi (202) -donza (96) -staoh (41) -subnd (77) -jzrlfrl (86) -sgxil (82) -wahmvp (49) -lvtxk (35) -cxrukf (5) -atcole (135) -> ykwvu, yckuqt -bjeto (71) -> msoip, wjkky -qsvyfv (220) -> cfuned, vzayzaq -ztodsnq (344) -> lqrde, ukvzqny, svzqi -pkditpt (99) -rgshogg (33) -drefe (29) -rnqvaa (91) -> wvuqq, uifug -cpxkqg (96) -bstznzu (45) -iflhr (7) -pczpj (60) -jhmvp (30) -aouljs (68) -ndqomrl (368) -> fhyfhjg, qnbnflf -wrumij (54) -ehcrq (299) -> cpllg, asnsvv -auvkb (40) -gdomj (191) -dnnlgt (77) -wasnz (63) -rzpmulz (85) -tiugk (82) -sdjzc (27) -jdxth (14) -aeeas (83) -crtnt (57) -ytwvl (313) -> nqjmi, mwgimvy -avmhq (86) -juscmde (150) -kbpvvf (72) -wegmegy (280) -> oaantta, fzvyv -kfdtg (68) -matvb (55) -ehzvm (62) -ebxyi (54) -qgfxzo (9) -zoodui (220) -dapjhx (93) -ywawq (1093) -> ptcby, kufsr, pxsuagy -laovxxw (27) -furny (8) -> lgxjcy, hcsiqp, vsijk -gzocll (70) -kifypgu (63) -kywpr (91) -eikjv (10) -wjkky (57) -fkwsxxk (1446) -> eyixz, bjeto, ghkmb -weeriq (19) -rxkpkvi (66) -bipzxj (81) -> bpgafw, ilidonx, uxswi -trjird (51) -istoj (49) -idcvpt (71) -> zzdgmmd, imakkq, jbodnl -pehio (202) -> bstznzu, xzdhzoa -exxbgm (77) -tuzquw (83) -ydmxb (1610) -> udoiqj, isfyuxu, hgtyjhv, tlxdyxj, inreau, qiinez -jmsuq (31) -dkjwj (155) -> nbbiqh, nbfbkao -xxbwj (122) -> xpinqek, xqmsvth -dfewulo (48) -> phmmydn, eyjdqm, qpblhez -ukvzqny (47) -gpormp (3465) -> ymogkwe, ywtwrq, hixtw, zmssxbl, twhcdv -diriz (19) -zltzea (47) -jkqbf (87) -> wpwxn, vzpqvfx, muecmt, trjird -uodyv (83) -fhqah (50) -aapsp (5) -> nvhbnlc, dzqax, ndjjag, dmjech -bxfwhrd (51) -knoziw (29) -> sinhju, otbxf, udkba -wbupk (63) -ixvxtb (87) -rnvlepv (34) -nerzb (81) -brtmsqe (59) -gjjyumz (81) -ogpvd (53) -ypttuns (56) -yzkpvn (50) -hssfwi (102) -> qfhfg, uvkecqz -ooenol (69) -mucpe (31) -bpbmbq (83) -> irkhv, navnyn, bzzsss, wbnux -kkimdb (84) -sfgatoz (40) -bqfor (66) -tobsrs (89) -polnw (83) -xlqycb (20) -uwrmetx (202) -jtjzsr (13) -tehdy (16) -feiitan (87) -hcsiqp (65) -> rlwyzv, liymh, huzjje, spfds -udghm (35) -iequdmw (572) -> cwxgg, geqnwz, smbkvwd, swhnbvw, uynmvcu -mwxiwty (90) -> lvtxk, ylrxgoz -xqmsvth (50) -ulszh (64) -cpllg (56) -oswpicl (51) -gcglasa (143) -> nbmat, cfqczei -kdwzx (40) -igumiu (373) -> ggynw, lrodp -jptqm (200) -> avrfgx, mucpe -yrwcj (112) -> cfshobe, mgcyq -uvkecqz (50) -mjgrhot (314) -> sdjzc, cjjwz -ohuvi (89) -uplxy (60) -ymfurx (26) -vrkrr (55) -tkxuj (86) -mydixq (60) -obgin (293) -> lewfa, ukwydlj, xyfeczu -swvae (68) -adlvipk (168) -> uilshuf, qxkilb -vxjhric (220) -mhbeqm (99) -vcyfwm (88) -> qrdtzc, gatdc -xujof (5) -rjkhl (257) -> mogla, nlewmv, mxxecyh -oxqvzzv (91) -rwxmoi (265) -> dnvqlog, ogpvd -tcybjv (178) -> iuneyv, cgszcig -xtpgpbx (15) -umtpolq (98) -zkdwxd (64) -gqiiycg (97) -pftdcqs (2087) -> xeefzwg, vyudgjy, ylvvgmj, fefnhby, ypiwj -vyudgjy (1079) -> ettsd, knastam, jretzi, rqebmc, kngspv, onudby, opnbls -micfuva (85) -dgmevpb (120) -> xcmre, upslw -ncghncy (36) -oxtckvl (144) -> erhiag, kvcak -tilvzsd (98) -> slnezfv, sxick -snaebf (11) -sdnzxl (2345) -> xhkrx, tcmkx -qdpcslx (83) -ymogkwe (597) -> srqbs, hgrwjoy, khpntc, atcole, spdyx -tywedfu (92) -chhmaxr (10) -onudby (18) -> zvxhi, zmqxmtf -xdwzfh (45) -avrfgx (31) -ctafsp (26) -cnbvz (360) -> zpeuqlo, iqdjcwm -uuijd (98) -gwlyvbx (86) -aewbhax (70) -> glhbvi, ulszh, rbawcc -fcbxsf (15) -yqzxa (306) -bbmbn (65) -nskayc (10) -ywuxmil (54) -> wasnz, ryiytg, raaxwq, jtkrr -dtrxzld (131) -> wontek, rjkhl, rwxmoi -shetkt (9) -> jqmcro, rqfjzox -movesh (26) -uylnr (46) -uexfxv (43) -tjxms (92) -> cfwox, vpcfu, boiuyt, nvgnls -cyhnayc (99) -rwtdhr (49) -glxtiz (80) -hhmrwj (178) -> oswpicl, bxfwhrd -nwkxd (19) -dxgntli (46) -xodsc (6) -ffgplgk (117) -> bkjcc, bclkir, cwhjt -fdcnhr (92) -waojp (14) -jtkrr (63) -mhbov (43) -sxick (83) -qwhelvj (98) -thrmrw (134) -> tliov, xhpvb, vjbjy -navnyn (92) -rpjiwuz (85) -> jmsuq, ctqgj -cfwox (54) -ghwwfca (131) -> fsmidq, aaztou, bpcrtwl, vfojca -pnqri (83) -lqdqct (98) -etznlt (75) -geqnwz (370) -orydf (91) -ywtwrq (1021) -> qfbqiv, ghwwfca, zfdhua -ayrucb (14) -jkmernz (94) -rxohrzb (60) -rffqotx (84) -> rgshogg, axrep -xxtdti (83) -jluccf (8332) -> xlpzp, obgin, dtrxzld, nzbknfm, ldfhqjw -pnuvuf (10) -iqqevm (80) -iuftirx (33) -sprno (14) -zcyfth (24) -poenou (76) -> evsnlxn, mhbeqm -pxifep (91) -tlgew (49) -xriiu (15) -hxzthym (303) -> zsbcn, nwejb, dckozkt, grgjs -jagoxt (10) -nuibgd (68) -emqqx (17) -erzayz (611) -> ywuxmil, clhyd, yqzxa, cxjmggj, kcqvnd, cvipqzv -umjwkfc (94) -> wpcry, pkbxhn, xmnreh -tjnxnd (123) -> gnitpo, yfzypu -kxftjs (43) -> tjxkxom, hrbsamg, qvpob -dbrlat (411) -> sprno, waojp -dqggz (76) -aqrxpru (83) -qedsq (894) -> sscfkq, waxrcby, fkwsxxk -kngspv (60) -> hhuhid, mhoaev -yonxye (177) -> qallt, vmpev -goqdmgy (85) -> fiwbd, ekgsba -nboczvq (55) -zlrvs (78) -zabqp (147) -> uxvgnv, huansqc -ndsvlr (88) -> mbjsjy, mjxtbvx -hnnjspe (79) -> wuijd, aokgycq, yzkpvn -hjjri (1300) -> vrkrr, jaxae -bvoxahz (184) -> kmvkkze, nboczvq -bpareqw (391) -> pehio, pxjve, zqbtgtw -afpxssv (45) -ibzpdf (119) -> gywnt, jogksw -sdeana (6) -sgzijsv (76) -peyyn (18) -xdszea (185) -> kbpvvf, vqbsvk -kvwqrd (75) -tyuyffp (228) -> tlcseu, xryqzl, hraby -fistzz (1760) -> vgtxty, bffvo, hnnjspe -zqqyhq (60) -qwada (40305) -> wfkcsb, qlboef, pkowhq -remwhfn (10) -vatqulm (66) -psirxj (42) -> rcomsru, aintn -mhblqw (10) -uwogu (38) -fsmidq (24) -bsvmale (79) -> exxbgm, trvjrbi, subnd, dnnlgt -zsbcn (421) -ilgue (54) -ldsbhlt (153) -> ayrucb, hlysw -scyuq (13) -piqgu (833) -> dkwde, dkhjdb, dqoatul, psirxj, mbmaqh, gxdqpcd -qsemjfo (241) -> yjfazsr, aeiktt -bfxmh (94) -rrnjpdu (280) -> lmuwznh, iflhr -jaxae (55) -nbbiqh (50) -vwisj (44) -gwoiid (78) -ctidma (26) -> ncghncy, swpvgrn, xwtgr, vjwptwp -oovlaqz (69) -fezhnw (71) -> ixuyx, pkesm, fdcnhr, qtfzj -hauul (9) -dkhjdb (66) -> dannmef, qaedcl -rtlde (120) -> glxtiz, rhqfa -qtfuwru (24) -mqyipy (23) -hvrmmxf (94) -swhnbvw (54) -> zodbq, qmiurj, idoml, efcqep -zcoyhde (92) -> esjuqh, vxucz, kifypgu, bveaw -qhujoiu (99) -sophzzn (407) -> uhjxtrp, vatlgyb -wfhixl (15) -eyixz (175) -> hmeolu, lumomlj -ldrzzzz (11) -hdmdxi (30) -azrcn (98) -jbodnl (99) -dkrdqpo (15) -wpcry (62) -ivnufgs (93) -mgreg (68) -vxobef (73) -nxcus (361) -> wdyxwia, nhhyvm -bdgwdt (280) -mculw (54) -jmavfy (35) -asnsvv (56) -wpezq (224) -> qppamj, pokjgkl -gsaci (313) -> tkxuj, jzrlfrl -eeuohnm (70) -zzdgmmd (99) -msoip (57) -spovj (58) -> lqdqct, omxny -covpz (123) -> wbzwxs, hvlfx -ukzfd (66) -ygldlhw (17) -> bbmbn, coibvjw -xmnreh (62) -nssexu (38) -zibnjxk (11) -fhyfhjg (53) -jaebowl (50) -vfojca (24) -gminpu (70) -ylpahav (29) -zdnvz (83) -tlulph (94) -hvlfx (49) -sadhkpb (204) -> edmzea, pczpj, jxevrgz -thymhif (150) -ewfql (37) -cykhmjj (8) -xlpzp (158) -> jnghyrm, nxgnumb, ldsbhlt, svkcvg, avnosfl, shetkt -ylvvgmj (1785) -> csvxlo, enymia, dasbhc -tdfgfqn (55) -rnyarzh (44) -exgsu (94) -heqvbi (48) -ybwgz (68) -rbzqh (32) -iwwngux (98) -> hvrmmxf, nebwj, bfxmh, fkrdkav -wolyko (13) -jrsbjr (45) -> vxobef, zsjoz -wowgkro (1847) -> vcvjtf, biioe -xjrheul (8) -gohdd (63) -tlfbyq (168) -> zqzrxe, jagoxt, zawbrvg, chhmaxr -jgoaja (48) -ghmxos (43) -bvqcnc (195) -ffqwo (116) -> ohuvi, ygtbl -qallt (37) -aujwg (32) -upslw (67) -axwdrai (73) -hyeetiq (70) -inreau (23) -> rosop, baimp, oxckpuw, nehwool, rrnjpdu, rqecouz -wfdiqkg (27213) -> ictgyp, yffxaiy, prvckio, qedsq, fjmjc -obxyz (30) -hatmf (92) -xffmho (423) -> xdszea, qsemjfo, fvfehj -omxny (98) -kfjqheo (1683) -> gwrred, bvqcnc, unscz -bffvo (169) -> puiks, zfzwko, xlqycb -tpbeg (6) -> sgzijsv, ysgnao -onwqp (22) -> mowkbi, gsaci, wuogj, ztodsnq, tqbouv -fcfbxmb (73) -iuneyv (48) -qybyrm (98) -cszchsg (73) -> ieqgh, fezhnw, sophzzn, dbrlat, igumiu -lrodp (33) -qmiurj (79) -rbawcc (64) -hhomxd (84) -euriiux (87) -esjuqh (63) -pxsuagy (369) -> ewfql, gdckdzx -xhpvb (52) -jroea (42) -> jmavfy, udghm, tdtxcm -tmfyif (15) -stfqd (59) -> zqqyhq, uplxy, rznqdxq, xpizz -vcwlaw (68) -> zeaxycf, izphu -eyrgmc (102) -> bbdayq, avmhq -pusdii (48) -cgszcig (48) -byrxbgo (6) -ukwydlj (135) -> vvqtv, ffjie -boiuyt (54) -mnbkaa (93) -> pneftv, gqiiycg, hrqaph -vxucz (63) -ejljdxo (98) -dkwde (50) -> shwsv, oovlaqz -aktswyh (51) -dvvkzv (40) -qppamj (8) -bftoy (221) -dzqax (59) -rlrnjnz (1115) -> dqggz, wpjaa -qzfwf (247) -> ldrzzzz, cxfqupv -ffjie (91) -mowkbi (93) -> uuijd, umtpolq, twxnswy, ivowf -ljeiizi (58) -emsjxz (47) -> jaebowl, vyxgc, voeps -hrqgfhg (415) -> vcwlaw, dsrostg, tfzsp, jptqm, vmuqpj, jfmuzo -xwtgr (36) -ctqgj (31) -bwqxk (220) -> xtpgpbx, dkrdqpo, wfhixl, yiyhuxk -kpwfqfc (93) -ulxxt (236) -> xuqozk, tyxfxu -yumbba (47) -rvwvqij (47) -prvckio (93) -> zqjqic, kfjqheo, cszchsg -uifug (65) -zeaxycf (97) -cxfqupv (11) -kcqvnd (306) -pxjve (246) -> rizbeea, brdbeoe -mhoaev (71) -rzlxx (32) -rnoaimc (99) -olwcj (22) -fmmgboi (31) -bclkir (41) -hraby (52) -jqmcro (86) -kvcak (13) -msqtvwu (6) -trvjrbi (77) -jogksw (52) -cdoed (240) -> tlgew, rwtdhr, wahmvp -qpblhez (78) -rqecouz (260) -> emqqx, xhrttm -zmbimk (22) -> zbptsb, wrbknnc, iqqevm -zmssxbl (1033) -> tjnxnd, ibzpdf, uwcqi -qlsdtum (158) -> ibnho, smxwnsk -hyzzwx (93) -bhvvs (173) -> zcyfth, oxwnu -soebcx (37) -lgltgc (98) -lcbljqb (226) -> bcpbir, zlubkqa -jrkbh (53) -icziaym (1507) -> uqzqmo, mwxiwty, ihskp -lqrde (47) -hrqaph (97) -qyrhb (486) -> wegmegy, tjxms, bdrerk -zwvjv (89) -rizbeea (23) -mjxtbvx (51) -drfeinj (30) -> cpxkqg, donza -spdyx (189) -> tehdy, afckhxn -dqxwazb (54) -vblyk (160) -> zjklq, wswjfu -mcpyfmy (32) -xzormv (5) -cwhjt (41) -drigjl (6) -> xxtdti, ewods, dkysxdp -fmjfhoo (85) -tliov (52) -gjxgd (371) -> hgdbip, eikjv, keczktv, mhblqw -cpdtw (27) -xaxuyg (372) -> bvfdo, aoltxw -dpavyu (64) -egyfwlq (133) -> cbtgtqb, qtfuwru, mnjirpy -llrntn (106) -> rcnhfcz, nqzvz, wolyko, jtjzsr -fjdyms (56) -sjfue (11700) -> vcyfwm, impqm, llrntn, tpbeg -nmbql (250) -> bqfor, vatqulm -udzzv (90) -dsrostg (232) -> xriiu, tmfyif -ihskp (42) -> wltlu, brtmsqe -zsxjxs (23) -lqfsw (98) -qsguy (252) -> drefe, ylpahav, dgscbm, emznzp -ilidonx (70) -hekhbd (411) -zodbq (79) -fjueoko (105) -> jkmernz, exgsu, tlulph -idqaieo (88) -> sfgatoz, dvvkzv, auvkb -udoiqj (914) -> sbfhxsx, fbmalu, husns -fbbkkxh (31) -nzbknfm (84) -> thrmrw, cwdoo, zwcucws, knoziw -hixtw (582) -> rtlde, hhmrwj, lcbljqb, umjwkfc -ifegka (22) -bnmgqen (33) -yodnj (320) -> pfvoay, cflrkd -hiuuk (19) -mlafk (38) -> wqgczyl, wnrqkg, wibgm, tpnvx -drzoi (68) -> lgltgc, cpess -dqoatul (42) -> fcfbxmb, qququw -bibly (37) -opctg (58) -abwmmuw (53) -ucsvcy (60) -anvxtbs (97) -> jfqlxa, mhhyoxf -hwevm (11) -qiinez (107) -> wpezq, sigxauh, rpxhqmz, xxlwrd, ffgplgk, hvsywx, vekdbjs -rhnota (37) -mrlnt (26) -ytkmda (1825) -> ctien, ogjqrb, goqdmgy -uanby (86) -oxxse (30) -jkknc (44) -> uyaarr, wwcqz, ruvmsg, tdfgfqn -xxxxbnh (299) -fefnhby (1167) -> liwqqqi, bftoy, covpz, bhvvs, gcglasa, rnqvaa -xsqvwa (274) -xmgank (374) -> dexabuc, xzormv -xxlwrd (194) -> zsxjxs, mqyipy -yyyel (68) -fvfehj (49) -> tvisu, hyeetiq, kbsmiq, brqvmh -ivowf (98) -isfyuxu (1346) -> ygldlhw, jroea, rpjiwuz -cqnmo (50) -mxxecyh (38) -aaqsdv (31) -dkysxdp (83) -chsuzvr (21) -vjbjy (52) -pyzwl (90) -izpxbq (7) -> wennxvo, fwgdynj -fkrdkav (94) -kmkqsvl (10) -oswqr (81) -pvatk (18) -> nhwgy, rnyarzh, vwisj -gxdqpcd (188) -ggynw (33) -acchih (15) -ldrfyi (8) -tjxkxom (230) -> zwvjv, tobsrs -vyxgc (50) -wfkcsb (6251) -> vxjhric, farpozz, eyslsq, zoodui -otbxf (87) -shwsv (69) -uxswi (70) -cvjhub (22) -zkyiauj (41) -> pqnkr, mnbkaa, xmgank, sadhkpb, tyuyffp -akioek (53) -> wowgkro, icziaym, nimeytn, hrqgfhg, hxzthym, vzkneq -emznzp (29) -hvtsr (98) -yqzdjj (33) -> dueof, jdbel, ixvxtb -fqkbscn (418) -> kddex, nylhp, xxyjm, agkgi -plwdhth (41) -abgfgav (26) -wbzwxs (49) -tlcseu (52) -vercm (79) -> aejbixg, wbupk -uvntywl (38) -hmeolu (5) -swkor (80) -> matvb, rsocykv -deewhp (81) -bveaw (63) -qlboef (81) -> gtvpf, qyrhb, xffmho, drpgz, hjjri -cvipqzv (296) -> xujof, vsffvp -mvkxva (41) -osysik (31) -tkcmrl (16) -xfxqvk (93) -sscfkq (720) -> ckbjuyy, zdlxv, kfjbjl -aejbixg (63) -lndfaxo (97) -> rqsjqrg, onwqp, sdnzxl, erzayz, fistzz -bcpbir (27) -feqefvb (6) -xsmdo (4571) -> vwwvjg, iibalc, ysgotr, oaabog -knastam (180) -> zibnjxk, snaebf -waxrcby (83) -> tcybjv, xsqvwa, poenou, eyrgmc, azpmzli, vdyftz, jofbj -bvfdo (51) -nvhbnlc (59) -vcvjtf (70) -mojye (244) -> qojqcd, cxrukf -qqodh (48) -ahutsc (30) -vtzfsci (43) -wennxvo (92) -ykwvu (43) -tfzsp (126) -> zjmhab, kfdtg -mogla (38) -rxfma (8531) -> kxftjs, bpareqw, rlrnjnz -ckdeo (26) -wkurl (41) -huzjje (86) -lcdleci (344) -nqxju (90) -cwxgg (232) -> uylnr, rchhwx, dxgntli -gfcfsf (56) -ysgnao (76) -kvtpc (32) -raaxwq (63) -fewkfib (965) -> pyzwl, fbhnbdw, nqxju -yffxaiy (1014) -> piqgu, zkyiauj, xlufcc -xeefzwg (1740) -> mjgilv, metyk, yonxye -gnitpo (50) -nlewmv (38) -gdhekde (88) -tyxfxu (9) -lmuwznh (7) -chwoyn (18) -mbmaqh (188) -xsulc (19) -hrbsamg (16) -> hhpib, qybyrm, agcpul, azrcn -tpnvx (284) -> qggycuv, ctafsp, ourium -uxgbnjk (90) -nqzvz (13) -kgfldlb (378) -> ajtjym, xnalv, hwevm -rosop (294) -wuogj (411) -> rhnota, gdawyc -hzxiv (176) -> zedqbr, ymfurx, xfapfj -zbiypv (1040) -> tlfbyq, idqaieo, adlvipk -dcytmqp (93) -saykbn (91) -gpikz (41) -rqsjqrg (1937) -> ctidma, kynrf, oxtckvl -bzijz (66) -ozxpbo (137) -> bwqxk, bdgwdt, imzegu, dvjssd, cybhcko -pkowhq (1187) -> zfrsmm, tlskukk, fqkbscn, mlafk -nylhp (171) -> heqvbi, sarwcau -nwejb (313) -> epuiwg, mculw -xfapfj (26) -sntovuq (37) -nehwool (78) -> knwlsi, zmzwttu, dqxwazb, ebxyi -dvjssd (98) -> nbccggn, orydf -oaantta (14) -vzayzaq (17) -zlubkqa (27) -xhkrx (51) -tkqke (1073) -> zjevsui, emsjxz, hgywlzc -nhhyvm (45) -pokjgkl (8) -dpvmn (99) -aokvbbi (40) -bzumy (1522) -> yfkgike, nqata, zheomzg, hooxvp, glrrnl -bpcrtwl (24) -irkhv (92) -tlskukk (1464) -> ixoiuh, jdxth -nbccggn (91) -svzqi (47) -tcmkx (51) -clhyd (220) -> ghmxos, zjxcrv -zdlxv (287) -> eeuohnm, gzocll -eyjdqm (78) -pmlim (78) -nbfbkao (50) -aeiktt (44) -rbgonm (9) -phmmydn (78) -agkgi (156) -> bibly, bttlx, kirowa -zqjqic (1602) -> humqvl, drfeinj, xxbwj -aghou (51) -ysgotr (954) -> xxxxbnh, stfqd, ptamwey -kmvkkze (55) -glhbvi (64) -baimp (158) -> yyyel, mgreg -xcmre (67) -mhhbej (36) -gdawyc (37) -spdsz (68) -pupaehu (99) -> eolilw, czlmv, zlrvs, vrppl -vmuqpj (160) -> aghou, aktswyh -agcpul (98) -hhuhid (71) -pgkeahi (18) -nebwj (94) -glrrnl (52) -> zwake, gtezger -dtqxiic (21) -pkbxhn (62) -qququw (73) -ilxgo (237) -> nwkxd, xsulc, weeriq -ymonx (56) -nqata (122) -> ovgpa, cadrzx -rahsrp (70) -wepvw (69) -kbefh (83) -cpess (98) -pqnkr (186) -> rnoaimc, pkditpt -uqzoo (47) -> kitggwr, kywpr, saykbn, pxifep -pgfomf (12) -vpcfu (54) -srqbs (221) -ixoiuh (14) -eozev (63) -qtqbdp (8) -zsjoz (73) -yflpz (40) -bpgafw (70) -imzegu (190) -> afpxssv, xdwzfh -ygvwdmg (91) -vebli (73) -hshbiaq (91) -humqvl (222) -fozfiqf (52) -> ndqomrl, iwwngux, xaxuyg, cnbvz, wmfro -iukfd (291) -> vcjavrw, mydixq -eduxyw (79) -ygtbl (89) -fjmjc (3192) -> zkhtua, furny, fewkfib -csvxlo (236) -xzdhzoa (45) -avnosfl (87) -> zsraq, lzstd -ptcby (71) -> dapjhx, hyzzwx, kpwfqfc, ivnufgs -hvsywx (170) -> tvhftq, xuokqm -gfsnb (71) -> gtixbu, micfuva -qxkilb (20) -pkesm (92) -ndjjag (59) -vsffvp (5) -ieqgh (247) -> zkdwxd, weejuk, yptrqp -jxevrgz (60) -mnjirpy (24) -hufrsq (3110) -> cmouh, vbdycf, seicwz, pwdoio, bhwnch, ozxpbo -tvhftq (35)"; - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let worker_input = - input - .split('\n') - .enumerate() - .filter(|&(pos,_)| pos % peers == index) - .map(|(_,line)| { - let mut words = line.split_whitespace(); - let name = words.next().unwrap().to_string(); - let weight = words.next().unwrap().trim_matches('(').trim_matches(')').parse::().unwrap(); - words.next(); - let links = words.map(|x| x.trim_matches(',').to_string()).collect::>(); - (name, weight, links) - }) - .collect::>(); - - worker.dataflow::<(),_,_>(|scope| { - - let input = scope.new_collection_from(worker_input).1; - - input.flat_map(|(_,_,links)| links) - .negate() - .concat(input.map(|(name,_,_)| name)) - .consolidate() - .inspect(|line| println!("part1: {:?}", line.0)); - - let weights = input.explode(|(name,weight,_)| Some((name, weight as isize))); - let parents = input.flat_map(|(name,_,links)| links.into_iter().map(move |link| (link,name.to_string()))); - - let total_weights: VecCollection<_,String> = weights - .iterate(|scope, inner| { - parents.enter(scope) - .semijoin(inner) - .map(|(_, parent)| parent) - .concat(weights.enter(scope)) - }); - - parents - .semijoin(total_weights) - .map(|(link,name)| (name,link)) - .group(|key, input, output| { - if input.len() > 0 { - let mut input = input.to_vec(); - input.sort_by(|x,y| x.1.cmp(&y.1)); - if input[0].1 != input[input.len()-1].1 { - if input[0].1 != input[1].1 { - output.push(((), input[0].1)); - } - else { - output.push(((),input[input.len()-1].1)); - } - } - } - }) - .inspect(|x| println!("part2: {:?}", x)); - }); - - }).unwrap(); -} diff --git a/advent_of_code_2017/src/bin/day_08.rs b/advent_of_code_2017/src/bin/day_08.rs deleted file mode 100644 index e55aacee3a..0000000000 --- a/advent_of_code_2017/src/bin/day_08.rs +++ /dev/null @@ -1,1151 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/8 - -// use differential_dataflow::VecCollection; -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; -use differential_dataflow::algorithms::prefix_sum::PrefixSum; - -fn main() { - - let input = "ebu inc 626 if iq < 0 -obc dec -809 if sdw == -2 -vb inc 568 if k > -2 -wl dec 721 if wui <= 2 -xbh dec -310 if bx != 1 -qun inc 741 if qun > -4 -k dec 661 if sdw != 0 -wui inc 628 if k >= -4 -qet inc 563 if skh == 0 -ebu dec 197 if wl < -716 -qun dec 239 if sdw < 7 -n dec 655 if azg == 0 -iq inc -857 if kxm <= -9 -qet inc -959 if tzy > 5 -azg inc -643 if qun >= 510 -ebu inc 537 if c >= -8 -eh inc -677 if bx >= -1 -c dec -267 if ebu < 341 -sdw dec 811 if tzy != -1 -wui inc -775 if qet >= 562 -iq inc 215 if azg >= -8 -qun inc 949 if sdw > -813 -xjo inc -652 if vb != 563 -skh inc -560 if n < -645 -xjo dec 978 if ne == 5 -skh dec 913 if k > -6 -iq inc 783 if azg != 1 -skh inc 955 if ne == 0 -xbh inc -981 if n > -660 -eh inc -361 if vb == 578 -iq dec 304 if obc != -3 -eh inc 408 if tzy >= -2 -w inc -576 if tzy == 0 -iq dec 102 if udh < 7 -k inc -627 if qet > 558 -xjo inc -232 if ne == 0 -azg dec -739 if j > -5 -a dec -141 if qet == 567 -a dec -731 if a < 2 -i dec -839 if as < 8 -v dec 855 if xbh >= -672 -wl dec -602 if wl == -721 -obc inc -613 if ebu == 340 -j inc 605 if wui >= -148 -kxm dec -192 if skh > -521 -skh dec 551 if skh >= -512 -xbh dec 340 if bx != -9 -qet inc 156 if w <= -575 -azg dec 627 if eh < -276 -qet inc 7 if ne != 5 -vjx inc -922 if as == 0 -vjx inc -680 if k <= -623 -as dec -807 if w != -576 -tzy inc -808 if qun != 1458 -wui dec -905 if a <= 740 -bx inc 371 if n != -655 -xbh inc 721 if n != -664 -xbh inc 79 if w == -576 -udh dec 217 if azg > 738 -eh dec 300 if a > 721 -k inc 684 if xbh >= -215 -i inc -281 if qet >= 717 -v dec -408 if kxm > 187 -as inc 923 if xbh <= -202 -v dec 640 if vjx < -1592 -kxm inc 537 if xbh < -215 -xbh dec 426 if eh == -564 -obc dec -269 if c < 272 -udh dec -256 if wl == -119 -xbh inc -519 if v <= -1083 -eh inc 134 if wl >= -117 -azg dec 485 if eh >= -576 -obc dec -134 if as != 925 -wui inc 549 if udh < 42 -eh dec -323 if obc >= -219 -a dec 553 if w < -575 -vjx dec 311 if qet == 726 -vjx dec 602 if as != 930 -tzy dec -588 if udh < 41 -i inc 479 if eh < -238 -eh inc 602 if j != 609 -wl inc -800 if sdw == -811 -qet dec -493 if k >= 48 -obc dec -469 if v >= -1084 -ne dec 100 if skh == -518 -c inc 574 if tzy >= -225 -wui dec -390 if bx > -7 -ebu dec 786 if v < -1079 -kxm inc -637 if i == 1037 -as dec 378 if w == -576 -ne dec -946 if v <= -1092 -udh inc -433 if obc <= -220 -azg dec 660 if w >= -581 -v inc 61 if qun == 1451 -v inc 644 if v <= -1025 -udh inc 531 if k >= 52 -obc inc 381 if n <= -655 -xjo inc -485 if a != 174 -tzy dec -526 if obc > 179 -azg inc -831 if skh == -518 -sdw dec 288 if sdw <= -808 -kxm inc 759 if kxm != -451 -n inc -847 if c > 839 -skh dec 384 if tzy != -220 -i dec -532 if obc > 163 -a inc 570 if eh == 356 -c dec 437 if wui > 1687 -i inc -403 if vb >= 564 -wui dec -223 if azg >= -1238 -vb dec 370 if vb != 574 -qun inc -251 if skh == -518 -n inc 490 if iq < 594 -kxm inc -542 if v >= -376 -c dec 49 if kxm == 314 -a inc -970 if xbh >= -734 -skh inc -258 if j == 605 -kxm dec 180 if j == 605 -j dec 243 if k >= 54 -vb inc 832 if azg >= -1231 -udh dec 662 if tzy >= -229 -c inc -327 if bx != -6 -obc dec 973 if kxm == 128 -udh dec 543 if vb <= 196 -n inc 534 if qun < 1208 -xjo dec -734 if eh < 362 -j dec 629 if azg == -1237 -wl dec -205 if qet <= 1219 -qet dec -811 if a <= -214 -azg inc -936 if sdw >= -1099 -udh dec 222 if azg < -2172 -j inc -526 if obc < 174 -ebu inc -725 if n >= -484 -eh inc 120 if i == 1166 -wl dec 292 if n >= -487 -k inc -718 if c == 28 -qet inc -472 if ne < -109 -ne inc -426 if qet == 2030 -a dec 351 if iq < 600 -sdw inc -446 if qet >= 2023 -i inc 666 if qun <= 1194 -obc dec -915 if udh > -315 -tzy inc 281 if a == -573 -udh inc -18 if as == 545 -k inc 767 if as >= 552 -as inc 84 if xjo != -641 -vjx dec -321 if qun != 1204 -v inc 799 if i > 1162 -qet dec -575 if obc > 1079 -vb dec -671 if obc < 1077 -bx inc -976 if vb == 198 -tzy dec 316 if qun == 1200 -skh dec -352 if qet <= 2600 -sdw dec 407 if qet <= 2605 -c dec -398 if iq != 597 -i dec 943 if a < -569 -wui dec -455 if as != 625 -skh inc 392 if k > -668 -qun inc 162 if k != -667 -xbh dec -311 if sdw == -1962 -sdw dec 219 if wl < -1012 -vb inc 610 if qun < 1372 -bx dec 314 if azg != -2170 -xjo inc 298 if wl >= -1007 -iq dec -229 if vjx != -2194 -obc dec -71 if kxm >= 127 -k dec 936 if n > -485 -azg dec -282 if v >= 417 -j dec 8 if qet < 2614 -j dec 599 if tzy >= -254 -w inc -111 if v >= 416 -skh inc -365 if wui <= 2375 -vb inc 830 if qun <= 1362 -bx dec -992 if qun >= 1366 -obc inc -254 if obc != 1150 -azg dec -557 if udh >= -326 -c inc -438 if sdw >= -1953 -eh inc 41 if as < 635 -eh inc -725 if sdw != -1958 -azg dec 515 if vb <= 1640 -vb dec 149 if qet >= 2597 -a inc 431 if wui < 2381 -qun inc 596 if c >= -14 -i dec -520 if a != -151 -v dec -500 if j == -803 -wui inc -581 if vjx == -2204 -vb inc -753 if a < -139 -tzy inc 309 if j > -796 -xbh inc -182 if w > -685 -qun dec -315 if j < -792 -as dec 688 if eh < -202 -bx inc -348 if ne > -533 -n dec 198 if w >= -690 -eh inc 179 if azg == -2406 -qun dec -636 if eh == -19 -skh dec 684 if a == -137 -i dec -501 if wl < -1005 -w inc -894 if obc >= 903 -qun dec 529 if ebu < -1172 -sdw inc -303 if eh != -34 -wui inc -912 if bx >= -1630 -wui inc 222 if bx != -1643 -ebu inc -907 if c < -17 -tzy inc -871 if tzy > -256 -bx inc -119 if iq > 591 -udh dec 56 if n > -678 -qun inc -839 if vjx <= -2189 -udh inc 867 if j < -791 -w inc 26 if i <= 1247 -i inc 633 if vb <= 745 -v inc -384 if skh >= -757 -ebu inc 876 if ne >= -529 -udh inc 116 if a <= -145 -a dec 179 if a >= -146 -ne dec 643 if c == -12 -c dec -490 if bx > -1764 -qet inc 286 if ebu > -291 -as dec -213 if i < 1884 -sdw inc -80 if wui != 2597 -xjo inc 59 if azg != -2406 -n inc 640 if azg > -2399 -k dec 444 if wl >= -1006 -sdw inc -45 if qun != 1437 -kxm inc -330 if bx >= -1757 -wui inc 934 if i == 1884 -qet dec 295 if azg > -2416 -j inc 435 if xbh > -736 -a inc -454 if eh >= -36 -obc dec -533 if iq == 592 -w inc 388 if ne > -1170 -wui inc 866 if udh >= 474 -wl inc -858 if vb != 736 -wl inc -90 if vb < 745 -wui dec 794 if vb >= 727 -w dec -198 if eh <= -22 -n dec 203 if qun != 1431 -a inc 252 if bx <= -1757 -udh dec 589 if vjx != -2194 -azg inc 10 if azg < -2403 -vb inc -293 if xbh > -739 -udh inc -737 if a != -519 -j dec -582 if obc >= 1433 -xjo dec -892 if xjo == -337 -qun inc 668 if obc <= 1443 -udh inc -124 if bx == -1757 -azg inc -210 if wui < 2665 -i inc -312 if wl > -1087 -ebu dec 356 if k > -2041 -qet inc 928 if skh == -749 -tzy inc 299 if i != 1874 -vb dec 151 if vb <= 447 -qun dec 936 if eh < -25 -eh inc 782 if vjx < -2191 -n inc 515 if j < 226 -udh inc 482 if obc > 1434 -azg dec -244 if n < -356 -n inc -192 if kxm == -196 -wl inc -573 if bx > -1760 -sdw inc 423 if vjx >= -2195 -c dec -72 if wui <= 2670 -k inc 984 if a == -523 -eh inc -288 if a > -525 -ebu dec 855 if a < -514 -kxm dec -261 if a > -533 -wui inc -58 if udh == 100 -sdw inc -304 if skh <= -742 -vjx dec -86 if qet < 3247 -w dec 163 if v >= 32 -kxm inc 231 if ne != -1169 -vb inc -291 if udh <= 97 -v dec 759 if iq >= 584 -xjo inc 390 if xbh < -728 -bx dec -760 if j > 215 -wl dec 370 if kxm > 57 -kxm inc 871 if vb >= 285 -c dec 4 if n > -556 -i dec 813 if v > -734 -v dec 129 if udh <= 100 -qun dec -762 if ebu == -1150 -v dec -415 if as >= 151 -ne dec 366 if obc == 1440 -udh inc 298 if a <= -533 -tzy inc -245 if wl != -2038 -i dec 992 if as > 151 -c inc -400 if a == -523 -wl dec 317 if qun < 1933 -azg dec 174 if tzy < -1067 -vb dec -780 if vb < 302 -udh dec 273 if ne < -1166 -obc inc -669 if wl <= -2354 -as dec 843 if k >= -1064 -as inc 902 if kxm < 944 -qun inc -154 if i >= 69 -j dec -894 if azg > -2334 -as inc 233 if w > -1140 -xjo dec 14 if xjo >= 940 -sdw dec 999 if tzy != -1066 -qun inc -351 if wl > -2363 -kxm inc -503 if qet >= 3230 -kxm dec -843 if bx != -1003 -obc dec -318 if sdw > -3187 -wl inc -243 if n >= -564 -a inc -873 if sdw < -3179 -bx dec 602 if wl >= -2601 -wui dec 237 if c >= 145 -wui inc -999 if qun >= 1420 -w dec 329 if bx != -1599 -a inc -550 if xbh > -735 -ebu inc 359 if azg != -2328 -tzy inc 965 if tzy >= -1067 -wui inc -608 if c >= 141 -vjx inc -168 if as <= 447 -qun dec -183 if qet < 3241 -xbh inc -456 if tzy <= -1069 -j dec 581 if j != 1110 -qun inc 677 if udh >= -173 -udh dec 783 if xjo > 924 -kxm inc 775 if w == -1132 -k dec -961 if v == -440 -qet dec 970 if skh != -753 -qet dec 566 if vb >= 1064 -sdw inc -639 if j == 1110 -ebu dec -22 if kxm <= 2051 -as dec 9 if tzy == -1072 -w inc -513 if obc < 1083 -k dec 669 if sdw <= -3822 -obc inc -795 if c >= 142 -n inc -980 if bx == -1599 -obc inc 176 if qet <= 1697 -j inc 517 if tzy != -1065 -wui inc 394 if qun != 2276 -tzy dec -833 if ne == -1170 -eh dec 112 if k < -88 -wui inc -648 if udh > -964 -wl dec 918 if w < -1125 -qun dec 846 if skh >= -755 -sdw dec 287 if tzy == -1064 -udh inc 902 if as != 443 -skh dec 793 if ebu > -777 -w dec 689 if j > 1621 -j dec 415 if azg == -2326 -obc dec -869 if k > -101 -c dec -524 if eh == 353 -j dec 519 if a > -1949 -n inc -811 if xbh > -1193 -udh dec 980 if qet == 1702 -iq inc 358 if qun == 1428 -w dec -719 if vb <= 1076 -wl inc -543 if vjx >= -2284 -vb inc -778 if wui == 517 -iq inc -611 if azg != -2330 -xbh dec 716 if azg < -2326 -obc inc 997 if tzy > -1067 -vb inc -645 if kxm <= 2058 -iq dec -703 if sdw != -3819 -xjo inc -766 if xjo < 924 -obc inc 345 if c > 670 -i dec 435 if qet > 1697 -kxm inc 895 if ne <= -1173 -kxm inc 387 if udh < -1041 -k dec 851 if wui <= 508 -vjx inc -957 if iq >= -26 -wui dec -102 if wui < 523 -ebu inc -441 if qet < 1710 -qet dec -774 if vjx < -3224 -skh inc -554 if qun >= 1431 -xbh dec -924 if sdw < -3816 -a dec 250 if qun <= 1438 -xjo dec -430 if wui != 619 -sdw inc -845 if kxm >= 2044 -udh dec 607 if a <= -2191 -w inc -940 if v >= -440 -w inc -224 if bx == -1599 -ne dec 856 if v != -441 -tzy inc 431 if vjx == -3233 -azg inc 370 if skh <= -2091 -tzy inc 530 if qet > 2468 -w inc 371 if vjx != -3233 -kxm inc 348 if azg < -1959 -n inc -611 if a <= -2190 -k inc 365 if c < 681 -kxm dec -734 if skh <= -2093 -n inc 243 if w == -2266 -skh inc 537 if j > 684 -j dec -127 if wl <= -4066 -n inc -903 if a > -2199 -udh inc 685 if kxm == 2785 -j inc 656 if v > -435 -vb dec 193 if bx == -1599 -eh inc -251 if ebu == -1210 -qun inc 882 if ebu > -1215 -k dec 705 if w == -2266 -xbh inc -92 if sdw != -4657 -w dec -689 if iq != -19 -qun inc 962 if sdw > -4671 -wui inc -476 if obc == 1504 -azg inc 946 if i > -360 -ebu inc 50 if n <= -3616 -iq inc -284 if a == -2196 -vjx inc -470 if v == -440 -w dec 888 if ebu < -1151 -a dec 369 if ebu <= -1153 -udh dec 3 if kxm > 2777 -qet dec -606 if tzy <= -106 -kxm inc -483 if sdw <= -4661 -vb dec 706 if tzy > -120 -udh inc 111 if kxm >= 2296 -iq dec 77 if xbh == -354 -tzy dec -534 if sdw != -4655 -tzy dec -300 if tzy >= 421 -ne dec 258 if skh <= -1552 -qet dec 363 if i == -357 -ebu dec -16 if bx != -1591 -eh inc -420 if a <= -2567 -qet inc 674 if azg >= -1962 -k inc 891 if azg != -1956 -ne dec 730 if wl < -4058 -ebu dec 497 if wui != 147 -udh inc -969 if j <= 699 -tzy dec 536 if eh != 101 -xjo inc -70 if tzy < 193 -xjo dec -873 if tzy < 188 -udh inc -923 if k != -442 -qet dec -56 if tzy != 193 -wui dec -982 if sdw < -4661 -iq dec 690 if qet > 3805 -azg inc -961 if i > -360 -udh dec 856 if wui != 1113 -bx inc -710 if j <= 701 -n inc 914 if i < -360 -eh dec -772 if qet != 3812 -ne dec 70 if vb < -470 -j dec -460 if i <= -355 -qun dec -837 if c != 674 -w inc 961 if azg <= -1948 -ebu dec -192 if k > -439 -w inc 795 if xbh >= -359 -wl inc 68 if v <= -436 -eh inc 555 if qun >= 3288 -vb inc 322 if eh != 95 -xjo inc 995 if sdw != -4669 -k dec 623 if w != -1388 -udh inc 533 if azg > -1960 -xbh dec 700 if ebu <= -1441 -xbh dec 570 if udh > -3070 -vb dec -434 if w == -1398 -as inc 173 if bx != -2300 -w inc 634 if bx == -2309 -vjx dec -719 if i <= -361 -w dec -796 if c <= 677 -i dec -410 if azg != -1956 -udh inc -738 if as != 602 -vjx inc -617 if ebu <= -1446 -ne dec -518 if ne == -3091 -vjx dec 135 if n == -2704 -wl dec 78 if tzy == 187 -tzy dec 753 if wl > -4075 -ebu dec 679 if c >= 683 -tzy dec -276 if w <= 34 -a dec 82 if wui < 1126 -skh inc 473 if azg < -1948 -udh inc -26 if tzy < -289 -xjo inc 407 if eh == 102 -i dec 909 if kxm >= 2306 -udh dec -97 if xjo > 3564 -tzy dec -858 if eh != 110 -ne inc -102 if c != 678 -iq dec -655 if iq >= -1063 -tzy dec -283 if obc <= 1497 -vjx dec 874 if udh < -3728 -xjo dec -521 if tzy > 576 -ne dec -532 if skh == -1086 -j dec 316 if i != -362 -sdw dec -256 if vjx >= -4612 -ebu dec -695 if v > -443 -azg dec 154 if k >= -1062 -vjx dec 933 if sdw <= -4399 -bx inc 696 if iq > -1069 -skh inc -130 if wui <= 1126 -eh dec -961 if c >= 669 -bx inc 482 if k >= -1061 -vb dec 177 if wui == 1121 -n dec 169 if i == -355 -eh dec 29 if xjo == 3558 -xjo inc 59 if xbh == -1624 -xjo inc 435 if wl <= -4074 -udh dec -642 if skh >= -1224 -iq dec 794 if udh != -3098 -eh dec -962 if c > 673 -wui inc 489 if as <= 613 -iq dec -353 if v <= -435 -iq inc -293 if n == -2704 -n dec -667 if vb > 102 -j dec 763 if eh == 2025 -kxm inc 100 if i >= -367 -tzy inc 757 if j <= 82 -i inc -902 if i != -359 -ne inc 3 if i < -1261 -vb dec 272 if qet != 3818 -skh dec -348 if j <= 76 -w dec 399 if eh == 2027 -skh inc 995 if c != 680 -wl inc 343 if a > -2653 -eh dec 628 if eh >= 2017 -w dec 544 if azg >= -2116 -bx inc 54 if xbh != -1624 -as dec -724 if vb == -165 -tzy dec 48 if vjx == -5543 -sdw inc -837 if as != 1333 -i inc 692 if obc != 1496 -k dec -395 if tzy > 1283 -ne dec -925 if vjx > -5549 -xbh dec -670 if wl > -3735 -obc dec 947 if wui >= 1619 -k dec -480 if sdw != -5245 -a inc -919 if vb > -158 -wui inc 8 if qet == 3812 -i inc -855 if eh == 1397 -azg inc -41 if j > 74 -xbh dec -945 if v > -431 -xjo dec -95 if iq >= -1802 -w dec -122 if kxm <= 2405 -xjo inc -721 if bx >= -1833 -xbh dec -182 if ebu < -751 -obc dec 694 if wui >= 1614 -tzy inc 755 if qet <= 3815 -vjx dec -537 if c < 682 -v dec 631 if qun > 3275 -j dec -573 if xjo >= 2895 -ebu dec 592 if xbh <= -776 -xjo dec -748 if skh == 128 -iq inc 30 if j < 657 -bx dec 693 if sdw <= -5240 -wui inc -953 if qet < 3817 -qet inc 969 if xjo > 2909 -as dec 963 if as < 1344 -wl inc -997 if as != 372 -xbh dec 514 if w <= -383 -tzy inc 343 if xjo <= 2905 -azg inc 470 if ne < -1725 -kxm dec 126 if bx >= -2527 -vjx dec -213 if c != 684 -wl dec -491 if as >= 377 -a dec -769 if azg <= -2114 -obc dec 576 if qun >= 3286 -udh inc 227 if obc != 805 -ne inc 528 if v < -1062 -as inc 124 if skh <= 135 -a inc -896 if skh <= 131 -k dec 949 if ebu == -754 -c dec -541 if iq > -1783 -wl dec -662 if udh > -2863 -xjo inc -41 if qun != 3284 -n dec -486 if iq > -1775 -vjx dec 982 if obc > 803 -kxm dec 349 if azg >= -2115 -ebu dec -19 if bx >= -2515 -xbh dec 199 if kxm < 1937 -ebu dec -907 if wl > -4066 -w inc 196 if bx == -2520 -bx inc -534 if udh > -2871 -skh inc 296 if iq < -1777 -azg inc 169 if v < -1063 -ne inc -187 if qet >= 3820 -qun dec -15 if skh != 130 -skh inc -909 if c < 1220 -obc dec 583 if obc < 812 -ebu dec -879 if qun < 3298 -a dec 818 if obc >= 219 -sdw dec 169 if as < 505 -as inc 971 if sdw != -5422 -wl dec 453 if a <= -4361 -a dec 584 if udh > -2866 -n dec 486 if w != -192 -w dec -423 if iq > -1784 -ebu inc 681 if as <= 1470 -skh dec -585 if sdw <= -5421 -qun dec -569 if n != -2038 -bx inc -705 if qun >= 3857 -w inc -198 if iq <= -1773 -ne inc -345 if k <= -2005 -vjx inc -368 if n > -2044 -eh dec -267 if v == -1071 -j inc 959 if c != 1222 -c dec -544 if ebu < 1718 -c dec -14 if xbh >= -1490 -eh dec -746 if as <= 1458 -azg dec 746 if tzy <= 2376 -a inc -306 if c >= 1781 -i inc 655 if azg == -2692 -a inc -201 if eh >= 1666 -bx inc 426 if qet == 3812 -n dec 234 if c < 1776 -azg dec -43 if qun < 3867 -a dec 527 if a == -4945 -iq dec 317 if qun != 3865 -iq dec -685 if ne >= -1547 -azg inc 309 if v == -1071 -as inc 269 if udh <= -2866 -a dec 764 if obc == 227 -eh inc 918 if qun > 3861 -udh dec 450 if wl <= -4509 -eh dec -56 if j <= 1615 -wui dec -557 if wl >= -4519 -skh dec 479 if bx > -3340 -skh dec 359 if kxm > 1917 -as dec -754 if xjo <= 2868 -eh inc -50 if wui >= 1213 -xjo dec 883 if j != 1606 -qet inc -687 if vjx < -6145 -k dec 899 if udh != -3318 -azg dec 242 if ebu != 1710 -w dec -837 if as == 2217 -ne dec 419 if obc > 225 -skh dec -258 if qet != 3820 -kxm dec -149 if azg != -2581 -qet inc 264 if tzy == 2381 -xjo dec -46 if qun <= 3866 -w dec -772 if ebu > 1705 -eh inc 7 if ne > -1955 -xbh dec 149 if vb > -159 -w inc 830 if xjo >= 2906 -xbh dec -341 if v < -1062 -obc dec -849 if w == 1633 -qet dec 632 if ne >= -1959 -j inc 599 if bx >= -3333 -ebu dec -326 if vjx != -6133 -i inc 752 if udh == -3313 -iq dec 305 if skh < -1366 -k dec 641 if eh == 2588 -vb inc -652 if eh < 2597 -skh inc -926 if v >= -1076 -j inc -59 if k > -3556 -wl dec 958 if wui < 1230 -obc inc 871 if xjo < 2919 -j inc -220 if k < -3540 -c dec -411 if qet >= 3806 -wl dec 874 if w < 1634 -skh dec 285 if udh <= -3306 -udh inc 627 if i != -1431 -bx dec -633 if xbh != -1140 -i inc -815 if wl >= -6354 -c inc 892 if qet > 3811 -wl inc 794 if azg != -2568 -obc inc 103 if skh < -2566 -k inc -188 if ebu < 2049 -k dec -356 if vjx != -6149 -sdw inc -314 if k > -3384 -wl inc 198 if j < 1934 -a inc -533 if i != -2251 -ne dec -231 if iq <= -1084 -ne inc -339 if tzy <= 2382 -kxm dec 641 if w != 1640 -iq dec 492 if skh <= -2567 -sdw dec -229 if obc >= 2047 -skh inc -194 if ebu <= 2041 -xjo inc 275 if azg >= -2583 -iq dec 826 if obc == 2053 -sdw dec -993 if kxm > 1444 -obc dec 15 if ebu == 2035 -skh inc 297 if c <= 3080 -sdw dec 748 if udh == -2684 -v inc 793 if c <= 3083 -obc dec -62 if qun >= 3861 -vjx inc -703 if xjo >= 3188 -wl dec 68 if ne >= -2077 -udh inc 199 if iq < -1579 -azg inc 991 if n == -2271 -bx inc -554 if vb != -812 -w dec -754 if kxm != 1445 -vb inc -301 if iq <= -1582 -udh inc 849 if wui < 1231 -qun dec 495 if xbh == -1144 -n dec -349 if w == 2387 -n inc 172 if wl < -5416 -wui inc -192 if wl <= -5426 -vb dec 676 if kxm != 1436 -n inc -365 if as >= 2224 -eh dec -938 if vb != -1492 -j dec -936 if j >= 1923 -eh inc -889 if qet != 3802 -tzy inc 629 if iq <= -1574 -bx dec -333 if c <= 3073 -j inc 118 if c <= 3085 -bx inc 217 if eh >= 2640 -xbh dec -587 if wl >= -5428 -kxm inc 9 if tzy != 3011 -qet inc 433 if c != 3074 -tzy dec 408 if obc > 2108 -ne inc -17 if vb >= -1502 -tzy dec -223 if azg == -1586 -azg dec -925 if azg >= -1580 -bx dec -645 if tzy >= 2823 -eh dec 870 if sdw > -6252 -obc dec -355 if udh != -1645 -ne inc -191 if obc != 2477 -c inc -88 if wl < -5417 -skh inc -36 if sdw > -6251 -w inc -404 if sdw <= -6247 -as inc 126 if vb <= -1491 -iq dec -456 if c != 2991 -skh dec -407 if v > -278 -a dec 621 if iq > -1135 -xjo dec -514 if kxm != 1447 -wui dec -912 if iq != -1124 -xjo dec 373 if c == 2982 -ne inc 61 if ebu != 2048 -qet inc -691 if iq == -1125 -as inc 553 if vjx > -6148 -qun inc -479 if qun == 3370 -tzy dec -851 if ebu == 2039 -xbh inc -52 if skh >= -2514 -udh dec -853 if wl == -5423 -udh dec 868 if i != -2245 -wl inc 665 if w < 1986 -qet inc -975 if w == 1983 -kxm dec 677 if kxm < 1446 -i dec 964 if j != 2978 -i dec 719 if a <= -7385 -w inc 142 if qun > 2887 -xbh inc 547 if sdw >= -6256 -ebu inc 102 if azg > -1592 -i inc -255 if v <= -272 -udh inc 681 if c < 2987 -a inc 535 if qun >= 2887 -udh dec -66 if xjo < 3707 -vjx inc -496 if j != 2985 -tzy inc -131 if v == -278 -wui inc 414 if azg >= -1579 -vb dec -579 if qun < 2896 -v inc -275 if kxm != 767 -vb inc -848 if w > 2127 -j dec -601 if vjx > -6641 -bx dec 311 if wl < -4756 -n dec -995 if kxm != 764 -iq inc -35 if sdw == -6247 -sdw inc 153 if v >= -271 -iq dec 219 if j == 3589 -tzy dec 183 if j > 3577 -a inc 193 if a > -6858 -qet inc -847 if xjo >= 3697 -iq dec -515 if n <= -755 -j inc -690 if j == 3581 -v dec -478 if a == -6662 -n inc 602 if wl < -4753 -xjo dec 532 if ne > -2213 -i inc 958 if bx != -3556 -k inc -587 if a <= -6662 -c dec -82 if eh > 1763 -vjx inc 668 if j < 2891 -ebu inc -357 if as < 2906 -n dec -283 if ne == -2216 -w dec 778 if iq <= -640 -vb dec 408 if ebu < 1784 -azg dec 271 if vjx != -6639 -udh dec -46 if ebu != 1784 -k dec 628 if azg >= -1592 -vb inc -962 if obc < 2467 -wl dec 408 if v != 198 -a dec 554 if vjx < -6631 -c inc 442 if udh > -1591 -i dec -417 if eh >= 1763 -qet dec -856 if c > 3519 -iq dec -144 if as < 2899 -sdw inc -229 if skh != -2507 -i dec -920 if i < -2800 -qet dec -244 if n != 138 -vb dec 811 if k != -4600 -k inc 560 if qet != 1976 -v dec 42 if w != 1342 -a inc -588 if skh > -2514 -qet inc 56 if obc < 2472 -i inc -870 if eh < 1770 -ebu dec -915 if w >= 1345 -xbh dec 455 if i <= -2752 -xbh dec 384 if xjo <= 3699 -wl inc -895 if xjo != 3692 -kxm inc -190 if sdw <= -6475 -vjx dec 450 if xjo != 3698 -skh dec 0 if skh > -2514 -xjo dec 896 if udh >= -1589 -udh inc 811 if k > -4587 -eh inc 520 if n != 130 -iq inc 873 if i == -2756 -eh dec -76 if skh == -2506 -ne inc -833 if wl <= -6057 -tzy inc -687 if xbh == -901 -n dec -232 if iq >= 223 -vjx inc -968 if qet == 2032 -as inc 503 if c == 3512 -a inc 952 if qun != 2892 -c dec -290 if wui >= 2128 -a dec -777 if wui != 2140 -qun inc -472 if tzy >= 2664 -vb inc -589 if qet < 2041 -tzy dec -548 if v > 153 -wui inc 152 if ebu <= 2706 -w dec 905 if tzy != 3224 -udh dec -241 if obc <= 2473 -v dec -532 if sdw <= -6473 -bx inc 818 if wui == 2281 -skh dec 547 if a != -6070 -qet inc 146 if a <= -6067 -n inc -528 if iq != 232 -qet dec -864 if ne < -3044 -qet inc -121 if azg < -1583 -i inc 363 if vjx > -7609 -k dec -105 if ne > -3040 -a inc 480 if i <= -2398 -udh inc 173 if ne == -3049 -n inc -712 if as < 3405 -j dec 597 if bx == -3565 -sdw inc -637 if vb < -2311 -qet dec -871 if obc == 2458 -tzy dec -927 if bx <= -3560 -xjo inc -471 if w == 442 -wl inc 976 if j < 2304 -tzy dec -505 if xbh <= -894 -a inc 929 if azg == -1586 -eh inc -265 if n < -877 -w dec -393 if obc < 2469 -a inc 406 if xjo > 2324 -c inc -437 if j < 2301 -a inc -589 if i <= -2399 -c inc -101 if obc < 2471 -iq inc -478 if iq <= 232 -xjo dec 635 if v >= 685 -w dec 485 if vjx == -7604 -wl dec 490 if eh >= 1571 -wl dec 923 if k == -4595 -azg inc -237 if bx == -3558 -azg dec 820 if vb >= -2322 -kxm inc -371 if qet < 2918 -i dec 405 if wl != -6507 -qun dec -596 if udh > -1178 -v dec 973 if wui == 2286 -as dec 840 if sdw <= -7121 -udh dec 373 if w <= 831 -ebu dec 372 if iq > -253 -n inc 469 if qet == 2916 -udh dec -123 if obc > 2457 -wui inc 517 if c != 3270 -wl dec -729 if kxm < 578 -vb dec 934 if wui >= 2800 -qet inc -307 if wui >= 2803 -sdw inc -935 if c <= 3266 -tzy dec 14 if w < 841 -k dec 167 if eh <= 1579 -j dec 438 if bx >= -3573 -obc dec -452 if azg >= -2415 -xjo dec -41 if ne > -3056 -qet inc -482 if qet != 2614 -obc dec 390 if bx >= -3571 -v inc 289 if azg <= -2410 -k dec -777 if azg <= -2397 -xjo dec 658 if azg <= -2406 -c dec -681 if ebu > 2332 -n dec 877 if ebu != 2334 -ne inc -602 if azg > -2410 -w inc -334 if eh == 1574 -c dec 64 if sdw < -8051 -bx inc -76 if udh > -1043 -vjx dec -169 if c >= 3263 -as inc 941 if vb != -3248 -i dec 131 if xjo < 1084 -as dec 222 if n <= -1750 -i inc -249 if wui < 2811 -obc dec 28 if tzy == 4635 -n inc -816 if xjo <= 1087 -obc dec 872 if qet >= 2624 -vjx inc -201 if ne == -3649 -eh dec 602 if iq >= -250 -w dec -596 if i != -3188 -w dec 212 if vjx < -7436 -xbh dec 523 if kxm == 577 -n inc 962 if v <= -281 -iq dec 30 if c <= 3268 -obc dec -300 if sdw == -8050 -vjx inc 125 if eh <= 984 -sdw inc -470 if j >= 1854 -vb inc 295 if udh >= -1045 -skh dec -79 if wui > 2795 -skh dec 307 if iq <= -272 -azg inc -74 if j != 1865 -qun inc 745 if as == 3182 -i dec -928 if wui < 2809 -obc inc 63 if wui >= 2800 -xjo inc 114 if ne < -3644 -qun dec -92 if as <= 3185 -obc inc -363 if w != 1211 -tzy inc 194 if ne == -3651 -xjo dec 569 if as < 3185 -i dec 295 if j >= 1848 -ne inc 946 if w == 1219 -skh dec -149 if j >= 1866 -kxm inc -579 if c != 3271 -a dec -979 if iq < -275 -xbh dec 281 if k == -3985 -xbh inc 88 if obc != 2207 -vjx dec 881 if udh <= -1042 -i inc 641 if qun < 3117 -vb dec -132 if vjx != -8192 -udh inc 952 if obc <= 2195 -ne dec 562 if iq > -287 -xbh inc 673 if wui <= 2800 -bx inc -737 if kxm != 8 -w inc -766 if wui >= 2798 -tzy dec 838 if vjx > -8198 -i inc 435 if obc != 2195 -a inc -582 if wui > 2796 -azg inc -87 if vjx == -8194 -udh dec 634 if ne >= -3274 -j dec 235 if kxm != -2 -v dec 143 if vb < -3114 -as inc 70 if bx > -4308 -w inc 864 if n < -1616 -bx inc 959 if n < -1604 -tzy dec 933 if i != -1469 -ne dec 369 if ebu > 2320 -v inc 387 if qet >= 2621 -qun inc 616 if k != -3985 -xbh dec 901 if skh != -3276 -k dec 770 if bx > -3347 -c inc 345 if azg > -2567 -sdw inc 485 if udh != -1672 -ebu dec 697 if xbh == -2515 -qun inc -223 if obc < 2203 -vb dec -329 if as == 3250 -i dec -828 if qet == 2614 -i dec 457 if ebu > 2317 -c inc 859 if vb >= -2794 -vjx dec -324 if xbh < -2519 -tzy dec 350 if sdw >= -8037 -wl dec -546 if a <= -4346 -ne dec -422 if vb <= -2784 -iq dec 933 if udh == -1682 -vb dec -354 if w < 461 -as inc 222 if ne == -3211 -i inc -488 if c == 4123 -v inc 466 if bx < -3338 -vb dec -779 if iq < -1208 -i inc -54 if i > -1581 -vb inc -124 if as > 3248 -qet inc -25 if i >= -1586 -ebu dec -572 if qet == 2589 -bx dec 699 if k >= -4763 -iq inc -184 if kxm != 2 -kxm dec 986 if xbh <= -2515 -j inc 904 if vb != -1773 -a dec 862 if vb == -1778 -wui inc -604 if ne >= -3223 -a dec 682 if qun == 2884 -qun inc -315 if iq <= -1395 -n dec -930 if qet < 2598 -n inc -532 if iq <= -1406 -w inc -921 if xjo > 618 -bx dec 728 if a > -5891 -skh dec 463 if sdw > -8038 -i inc -119 if c != 4128 -n inc 651 if ebu >= 2894 -xjo dec 978 if eh != 982 -i inc -948 if n == -28 -skh inc -459 if v < 41 -j inc 625 if kxm == -988 -skh inc 38 if k >= -4757 -eh inc 207 if eh > 968 -k dec 771 if sdw < -8027 -vjx dec 73 if qet <= 2592 -j dec -53 if iq >= -1403 -vb inc 952 if vjx <= -8263 -azg dec -345 if as > 3240 -w dec -802 if ebu <= 2901 -azg dec -861 if iq <= -1394 -xbh dec 160 if xbh > -2522 -vb dec 170 if wui != 2201 -xbh dec -607 if azg <= -1361 -obc inc -204 if as >= 3245 -n dec 717 if wl == -5769 -tzy inc -417 if qet < 2594 -qet inc 516 if kxm > -990 -tzy dec -355 if azg < -1356 -xbh inc 946 if eh >= 1192 -iq dec 221 if ebu <= 2904 -c inc -692 if vb > -1006 -xjo dec -599 if obc < 2004 -ne inc -255 if vb >= -1000 -vjx inc 144 if sdw != -8038 -tzy inc -905 if ne >= -3467 -j inc -71 if qet < 3108 -as inc 289 if skh == -4165 -i dec -621 if azg > -1371 -xjo dec 703 if w == 334 -wl inc 657 if azg < -1358 -n inc 152 if sdw < -8041 -skh inc 258 if vjx == -8123 -iq inc -613 if w >= 330 -azg dec -55 if azg < -1366 -w inc -504 if n == -745 -vjx inc -100 if kxm < -996 -j dec -699 if tzy > 3577 -wui inc -120 if i > -2038"; - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let mut state = ::std::collections::HashMap::new(); - - let mut max2 = 0; - - for line in input.split('\n') { - - let instruction = line.split_whitespace().collect::>(); - - let read = *state.get(instruction[4]).unwrap_or(&0); - let val = instruction[6].parse::().unwrap(); - let test = match instruction[5] { - ">" => read > val, - ">=" => read >= val, - "==" => read == val, - "<=" => read <= val, - "<" => read < val, - "!=" => read != val, - _ => panic!("unrecognized instruction"), - }; - - if test { - let change = match instruction[1] { - "inc" => instruction[2].parse::().unwrap(), - "dec" => -instruction[2].parse::().unwrap(), - _ => panic!("unrecognized action"), - }; - *state.entry(instruction[0].to_string()).or_insert(0) += change; - - if *state.entry(instruction[0].to_string()).or_insert(0) > max2 { - max2 = *state.entry(instruction[0].to_string()).or_insert(0); - } - } - } - - println!("part1: {:?}", state.iter().map(|(_k,v)| v).max().unwrap_or(&0)); - println!("part2: {:?}", max2); - - let worker_input = - input - .split('\n') - .enumerate() - .filter(|&(pos,_)| pos % peers == index) - .map(|(pos, line)| (pos, line.to_string())) - .collect::>(); - - worker.dataflow::<(),_,_>(|scope| { - - let data = scope.new_collection_from(worker_input).1; - - let edits = data.map(|(pos, line)| { - - // Each line has a read location with a condition, and a write location with an operation. - // E.g., - // - // kxm dec 986 if xbh <= -2515 - // obc inc 63 if wui >= 2800 - // xjo dec -599 if obc < 2004 - // ... - - let mut words = line.split_whitespace(); - - // Extract the write location and what we should add. - let dst_name = words.next().unwrap().to_string(); - let dst_flip = words.next() != Some("inc"); - let mut dst_diff = words.next().unwrap().parse::().unwrap(); - if dst_flip { dst_diff = -dst_diff; } - - words.next(); // Ignore the "if". - - // Extract read location, comparison, and value. - let src_name = words.next().unwrap().to_string(); - let src_cmp = words.next().unwrap().to_string(); - let src_val = words.next().unwrap().parse::().unwrap(); - - // (pos, (src_name, src_cmp, src_val), (dest_name, dest_diff)) - ((pos, src_name), ((src_cmp, src_val), (dst_name, dst_diff))) - }); - - // Our plan is to iteratively improve a set of transactions to commit, starting from none. - // In each iteration, we need to determine the value of each read location at the position - // associated with the transaction, which we will do with a prefix sum. Then, based on the - // value we get back, we (tentatively) accept transactions and proceed to the next round. - - // let reads = edits.map(|(pos, (src_name, _, _), _)| (pos, src_name)); - - let history = - edits - .filter(|_| false) - .map(|_| ((0, String::new()), 0)) - .iterate(|scope, valid| { - - let edits = edits.enter(scope); - - valid - .prefix_sum_at(edits.map(|(key,_)| key), 0, |_k,x,y| *x + *y) - .join(edits) - .filter(|&(_, sum, ((ref src_cmp, src_val), _))| match src_cmp.as_str() { - ">" => sum > src_val, - ">=" => sum >= src_val, - "==" => sum == src_val, - "<=" => sum <= src_val, - "<" => sum < src_val, - "!=" => sum != src_val, - _ => panic!("unrecognized instruction"), - }) - .map(|((pos, _), _, (_, (dst_name, dst_diff)))| ((pos, dst_name), dst_diff)) - .map(|x : ((usize, String), isize)| x) - .inspect_batch(|t,_xs| println!("{:?}", t)) - - }) - .consolidate(); - - // part1: Maximum value at the end. - history - .explode(|((_pos, dst_name), dst_diff)| Some((dst_name, dst_diff))) - .count() - .map(|(_key, cnt)| ((), cnt)) - .group(|_, input, output| output.push((*input[input.len()-1].0, 1))) - .consolidate() - .inspect(|x| println!("part1: {:?}", (x.0).1)); - - // part2: Maximum value at any point. - history - .prefix_sum(0, |_k,x,y| *x + *y) - .map(|(_, sum)| ((), sum)) - .group(|_, input, output| output.push((*input[input.len()-1].0, 1))) - .consolidate() - .inspect(|x| println!("part2: {:?}", (x.0).1)); - - }); - - }).unwrap(); -} diff --git a/advent_of_code_2017/src/bin/day_09.rs b/advent_of_code_2017/src/bin/day_09.rs deleted file mode 100644 index cfda8ed064..0000000000 --- a/advent_of_code_2017/src/bin/day_09.rs +++ /dev/null @@ -1,164 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/9 - -use timely::dataflow::Scope; -use timely::dataflow::operators::ToStream; - -use differential_dataflow::{AsCollection, Collection, Data}; -use differential_dataflow::lattice::Lattice; -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = r#"{{{{{{<,,!u!!!>"!>},<,!!'!>,,},<'{},{!>!!!>>,{{>}}}},{,},<>},{}},{{{{{{<}!>},,<>}}}},{<,!},<>,"{!!!!!><>},{{{{<}!>"e!>,<,!!!>!>!!!>!!!>,!!{!>},<}},<{!>},<>}}}}},{{{{,!!!>!!!>a!!!>,<,<}o!>,>,{{{>},{}},{}}},{<',,,},<>,{}},{{{!>},!>},,}}}},{{},<'!!!!!>"}!>},},,}},{},,},<,!!!>},}},{{{{}}}},{{{{{{}},{!>eaa!!!>!!u{{!!!>!!!>!!{!!!>!!!>e!>>}}},{{{}}},{<},!!!>i!}}i!>,{!>},!!!>!!,o!iu>,{{,,<>}}}},{{{!>},<,!!!!!>u!!i!!!i!!}"!>},<>},{},<>}}},{{}<},!!!>!!e>,<,<"a!>,},<}}},{{{{{{{<>},,},<>},{{},!!!>},},,!u>}},{,},,<"{"!!!!!>u!!!!oou}>}}},{{},}},{{{{{},,}}},{{'>,<"e,'!>,<>},{{<>},{}},{{{,}!!!>{!!e!!!>!!!>i!>},<}},{{{!{!!!>eoo,!>'!>!!oa'a">},{}},{{{{{,>},},<{!>,},}!<}!{!!'',!!!!!>>},uo!>,},},{{{{{<e>}},{{,a>}}}}},{<<>}}},{{},{,<{{!i!>!!!!!!{'",i">}}}},{{{!>}!!!>">}}},{{{<}'u!!{!'!!!!!!!>e!>,!>u'uiu>},{!u!!!>}{!!!>!>,<,>}},{!>>,<<'>},{{{},<'{!ee{'a!>},<'!<}>}},{{,},{,}}}}},{{},{{{eia!!!>'a}"!>,<}i>}},{{},!>"'!!!>,>},{{{,},,<,!>!>,},!!'>},<{{>},<{,,i"{!>},<<}},{{{},<<>}},{},"!!!!!>>},{{<"!>},},<>},{},}}},{{{},<{{!>,!!!>},},,a">},{{{!>,<}!!!>},},,>}}},{{{}},{<>,{}}}}},{{},{{},!>,<}!>},},{}}}},{{{{},{{{{<',<{>}},{{<>},{<,!>a!>!!!>'!!!>'u},!>},<""!!!>},<}!!>}},{{},{u!!e>,}}},{{,<"!>au!>!!>}},{,}}}},{{{{{{},{{},<,e!o,!>},<'!!!>!!!>!>,<},!>!!'!e>},{}},{{},,o!>},!}"!!e"!oa!>},},{{{},{}}}}},{{{{{},,{<{"i>}},{{},,"{!!'>,{}},{!!!!!!e!>i!>,},<,<{e{}"!!o,!!'a!>},i!{>},{},<,!!'!>},<{"}},{}},{{!!a!>>}}},{{{{},{},<"e,o'}e{!>,!!!'!>!>,<>}},u!!!>,},<,!o!>!oa,!>,},},,,,>},{,},<{!!!!'!!!>e!!,!oi>}},{{{<'>,{,,!!}!>>}}},{<,{<"!>},},i}!!e!>,,}},{}}},{{{{{!!"a!,a!>>},<,!>!!!!uu!!!!{!!!>,o',!!"e!!!>!>},,<{}>},<{!!!>!oi>},{{},{}}},{{<"!>,<>,,{"a!!!!!{!!!>!!!!!!!>!i{>},{{>}}},{{,},{<}>,{<{e>}},{{,},<'o'!>!!!}}o!!},{},}!!!>"!>,!!{e!!e>}}},{{{{},<"e"!>,,<,!>},<{u!>,>},{}},{{"}"!},{!o!u!!eeiua!!,!!!>e!!>}},{{,,<{'>},{<{,!!e{>,{},<},<{"}aa!>,<">}}}},{{{}},{{{{,<'!>!!!!}{!>,,<{!>,<<'!!<>}}}},{{{{{<>}}},{{}}},{{{<'ooeu!!{>,{}},{<}!>,},},!>,<{!>e!>},<>}},{},},{"!!a!!!>,!>},!a,<{u!!e'>,{}}}}},{{{{{,,<,ii!>}!!!u>},{{,<,"u,!!!>!>},<>}}},{},{{<{!>!>},<'!!i'!>,},},}'!!u>},{},{<>}}}},{},{{{i!!!>}!!'!>!>!!u,{!'!>},<"!!>}},{<{!!!>!!e!>},<<>}},{{{{}}},{<,e,!>!!!>,<<>,{{<}}}!'"a"'!>},<}}},{{<{'<},<'}!!!>u,!>!>!u!>,<>},{<'e!>e!a!>!!}iu!>>}}}},{{{{}},{{},{{<>,{}},{{{<"}!u"}a!!}!!!>e!>ua!!!>">},{{},}}}},{{<,!>,u"},<{>}}},{{!!a!!uo"!>},ae>}}},{},!!a{!!!>!'{>,{{{},,},},{,}},{{},<'o>}}}},{{{<}}>}}},{{{},{}!!!>a!>,<>,{}}},{!>!>},}}}}},{{{{{}}},{{<>},{{},},<'!>a>}}},{!!!>},},e>}},{<"{a!!u!!eaea>},{},<,!!!>'>,{}}}},{{{{}},<'i!i!!!'!>,<}u!!a},!!u!>>}}},{{{},{''{e!>,>,{{{{},{{},i!>},},{{},}!>!!!>,<<>},{ei<,o,!!,!o,a!a!!!>}<>}}}}},{}}}},{{<>},{i!!!>'!>!>,<>}}},{{{},{{<}}}},{{},<o!o!>},<{>,{<,e!>,<>}},{}}}},{{{{<u>},{},<>,{{}}}},{<,!>'iae!!!!{>,<"},{{<>},{},<>,a!>,"'!>!>},,<>},{<<,!!!>"i!>},<"o!>,,<}!!!!e,"o>,{<{!>e>,{<,'!>}!u!!!>{<{!!!!{!!<}!!!>!!!>">}}}}},{{},{{u!>},,{{,<,{,!>!!,au>}}}},{{aiui!!}!,"'a!!!>'!>u!>!>,<<>}}},{{,},{},u!>},,{}},{}},{{{{},,<,o!>},<"o!!{}!a>},{{,},{{a!!!ii!!!!!>e>}}}}},{{{{,},{<'!>,},<"uueoe!!a!>},<{!>},}}},{{<>},{{!!}iaaae!>!!!>!>},}}}}}},{{{{!i!!iea{!>},<}u!ae"!!i>},{<"}!!>}},{{{<{}},{{},!>},!>,eoo!!ui!>!!{!ii}>},{{{}},{{<},o"!>,a}!,'!>},<>},uue>}}},{}},{{!!>,},<{!>,<}oio!>,<>},{},<}}>,{{<{'>}}}},{{{<"!!!>'o!i!u,i>}},{o!>,<{!>},,"!>},<'e",{i}!>>,{}},{{,<'!>>,},!>},u}o!!!>'o{>},i}!<}},{{!!!>,,>},{{{<,'}},{},{{{,!!{'"!>},},>}}}}}}},{},{{{{{{,,<>}}},{{},{{{},{,<'u}}{!>a!!!>!>>}},,},{!!!!o''e!i!!!>o,>,{<',!!!>!!!!!>!>,u!>,<,,!!i!>!>},<>}}},{{{},!!!>},},o!>!,!!>}},{{{<'!!}'euiii!>}},{{{},{},<,!}!>,}},{{{,},,<{o!>e<>},{}}}},{<!>>}},{},,,{u!!!>>}}},{{{},{!!!>!>},<}!!"!>,!!!!!>!e>,}o!!!>u>},{{},<,!>,<<}}},{{{!>aaa'>},i'{<{}!>!!!>}e!>,},<>},{},,{{},{}}}}}}},{{{{<'!>},},"!!a!>,<>},{{},<,!!!>>}}},{},{,{{<<,i,!!!!!>,>}}}},{{{{{{<",eau'i{!!!>}>}},{{}}},{{<{!,}oi!>>}}},{{{<,>},{,},}},{},u,<>}}},{{!!!i!a'a''>},{{{{},<,u!>!oe'!!!!u{!o!,'>},},{{}},{{{{<,}}!!>,{"!ia!>,{"!>,}},{,},e'!!!,>}},{{{,<>},},!!{e!!o>},},<"!>},!!!uai>}},{},{<<,>}}}},{},{{{},{},{{<,!!!!io!u!>,!'!>,>}}},{{{{{<{ou,<>}},{{,>},{}}},{{{i!>>},{},{{<{!!>},,!!}}}},{},{{<}a,a!!>},!'"!>},,<,u>}},{{{}},{>},{{{,},!!!>,,<>},{{{<{<{>}}}},{{},,<>,!!i!!!>i!>,<{!>},<}!!!>,},{<{>,{,<}}},{}}}}}},{{{!!{!>}>},{{!,{{>},a{u,>},{},>}},{{{<,!!!>}o,u>}},{{,,},<'{u">,{,>,{<>}}},{{<>}}},{{<}}!>,!!}!o>},{!!!!}}},{{{{{<}ia!u!>i<{'!!'"u!!!>},<>}},{{!{!<'!!"u>}},{},<'a!>,,,!!!!!>!>,<>,{!!!>u!!!>!>,},o!>,<>}}}},{{{{{},<{!!!!'!>,<"!!!>u!!'>},{}},{<,{{<io""!>},<>},{{<'e!!!><<,!!!>,uei>}}}}},{},{{{o!!o,a"!>,<}!!>}},{{<>},{{<"""!!!e!i!u">,{<{">}}},{{<}!>!>i!>,}}}},{{<,!>,<!!e!!{uu!!!>>}}},{{{<},!>!o!!ao>,o!>a!!!>},!!">},{{{{{!i}{!!{!>},<"!>,<>}},{<""o"!!!>>}},{{i!},,<,',!ei}>,{!a{!>,,>}},{{},,!!!>!!!>},{eoeo!!i}e>},{{{{<,i'u!>},<>},{{,{{},<{ea!>,,<"}!!!>,<<>,{{},!>},<>}}},}}}},},},"!o{{'!!{}euu,}}}},{{},<"{}{}!!u!>i<>}}}},{{<,!>,}ae!>},<'',},},{<}!!!>{!>},!!!>!!!!,o!!},<>}},{,<","!!">,{<{'!!!!"{!!!>,,}}},{{},},},<,'!>}">,{e'!!e'a!>,,{,!!!>>}}},{{<,!!!!,a!!!>uo>}}}},{{{}u},<>}}}}},{{{'!>a>}},{{oi{!!a'{!!!>!>,>,,<}">},{<{!>!>,<>}},{{>,{},!>,}},{{{{{,>}}}},{}},{{,<}}u{ea!!!ia"u>,{!>},<"!>,<{>}}}},{}}},{{{{{{{{,<,aeu"!!!!'e!>,<,!e"!"!!!>!>,<,,>}},{{{}},{{{,,},},,<'>,{<{}u!iie!!ai!>,},<}}},{,<'!>},<,!>ii,!!}e'!o!>>,{{{},{<<"",!}}o!!!><},}!>},<,>}}}},{{{},>}}},{{{},<>},{},!>!>,<>,{,,!!!>">}}},{,<,>,{<}e!!!>e'!,u!!>}}}}},{{<uia>},{<"{!>,!>,<'"!o!>,,},<'!>},o!!!!'{>}}},{{<>},{}}},{{{a!{!a!!!!{ueo">},<"!!i'!>},!}{a!>},},<>},{!>},<}!>oo!!!>}}!!!>!>!>},{{<"}!!'i!>},<},a},!a!!<{,>,{}},{}}},{{{{,<>,},{,!>},,<,'}>}},{{{<>}}},{{{oo!!},!!!!!>i!>},,{!!,a'!!!>i<,<"!!!!!>!}i!!>}},{{{{!!e!>,>}},{u"!!!>!>!'!!e"!!!>!>,}}},{{{},<,!!o}i!>,<,!!<,!>,},<}'!>,<,u>},{,<,!"{ua{!!e!>,<'a!>,},,},!!'a!a'!>,<>}},{{{'>},{<'}!!u!>},}},{<"!!!!e}>}}}},{{{,{}},{{{!!!>}}!!}!>,<>}},<>},{<{!!o"!!i{ue,!>!!!>!!a,e"!{!i>}},{{{u!>}'!!!>u{>},{{,{}},{{{,!i!!u!!!!>,<>},},,},}}},{{{},<{!!u!>},!!!!e{},>},{,}!!'!!!>!i"!>},<}}},{}},{{,{}!>,!!!!!>!>},}}},{{>}}},{{<'!eo!!!>o!!!>},<>,{iio!>!>},<>}},{{{,<,<>}}}},{{{<<'>,{{}}},{<{i!!u,!!!>,i!>},'a>}},{{,<'iai},,>}},{{},{{<{!!!i<!!,,a>}},{"iu!>},<,,!!!>u!>},<'}ai{!>,<>,{<"!>,<>}}}},{{{{},{<,""!{ie}{>}},{{,<{}},{}},{{},!>,eo,}!!>,{{!>,}}}}},{{{{{{{u!!',o!!">}},{{},"!>,,<',!!!>},<>},<,e,!!!!oea"'!"">}},{{{<,{!>},<,!!!>!>,,<{!>!!ue!>},<,i'e>,{<}!!aea,}}},{},{!!!!!>},<>,<}{"},<"}eu{u<>}},{{{{},{{}},{}},{{<}!>!!a,!>!>,,<,!>i},<{!!!>ee!,<},{'<}!>>,{<>}},{{{<,!!!>},!ie>},{{},},<},,>}}}},{{{{,},,e",a{>}},{{{<"!!!!!>,},e>}}}},{{<"a>},{{!!!!!>!a!>,},},<'o!>},!>},<,e!>,<{ii!!>}},{{,!!'o"!>{!>,<,{!>,},{}}}},{{{},},<'!>,,!>},},<>},{},,{{},{"}e}e!>},!!!>!ee!>},>}}},{}},{{{{},{<"!!!!!>a!}ua>}},{{<'!!!>>,{<,!ao{,u!!!>,!!!>i!>,<>,{{{}}}}},{{},{{{{}}},{<{!!!>"!>},}},{!>},<},,<}},{}}},{{{<>},{{},<{'!!!!}'!!!>!!!>>}}},{{{{{},<>}}}},,},,}}},{{<"!>},!i!>,<{ue!!!!>,},},<{!u{!>},<>},{{!!!>!i!!,<},<!>,<"u>}},{{},<,>}},{{{!!,e!>,<,>},{<'ee'!!u!>},,}},{{<{'!>,,<},<>},<{!!e!"!{!}iea},<}"aa>}}},{}},{{{},<,!!!>}!>,,!!"},{{,!!i!!!>i,>},{}}}},{{}}},{{{{},},{!!}},},{{<>}},{}},{{<"!>!!!!!,e'!!},<>,{,>}},{{{!!}{o>}},<>}}},{{{{},{<<}!!!>,<},,},',i>}},{},{,<}uo,ueo!!!>,u!!"a!!!>>}},{},},!!!!!!!!,!>!!!!!>!>,,<{>},{{<}!!e!!!!!,!>},<}!>},<'o'!o},{}}},{{o!!!!!>o,!>!!o!!"!!!>,},{,,"}},{{},u!>!!>,{<>}},{{,<,,'!>},<}!!{>},{{{,<,!!'a!!!>},<"{{io!!!>!!>,{<,!i{!!'!>,<,!>!>,,"e"!!}!>},<{ae>}}}}},{{{ae}}}}},{{{u!!io!!!>!>>,<>},{},{,{u!!,'!!}!!!'>,{e!!!!,iu!!!!!>!>},a"{}!>},<>}}},{{{o!!a',>},!>!>{"{{!>,<}ioe'!!!!!>!i!!"!>,>},{{},!>},},{{{}},{!>,,>,{{,<',<,u>},'>}}}}},{{{{{{{e!!}!>u',i!!!>'!!{!}"}!!"e'>},,}}},{{<'>,<<{!!!>e'!!!>!!}"i!>,<>},{<eu!>a}!!!>u!!!>!!>,{{{{}}}}},{{{},{ia!{!!!>{>}}}}},{{{{{>,{!!o!!o'!>},,<{!>,}},{<'!!!!io>}}},{{<,,<>},{,>,{{{{'o!!!!!!u,u!>""!!a!>iu!!{!!>},{,!,o>}},{}},{'}e!!e}!!,!'!>},<{}!!!>!e>}}}},{{},<{,!!a!!!>},<>,{<"!>'!>!>'!!"!}>}},{{,},<{i!>,},!>},,},,},},}}}},{{{{,},<>},{}},{,<'}!>,<>,<,!!}{!!!e!!,>},{{{<!>!>,'!a!!!!"!>oai>},<},!!!>aiu!>o>}}},{{,!!o!,},{{},{},'{!>},<'"<}>,{<,!!!!>}}}},{{{,{a',o!>},<},{!,a>}},{{,<{!!o'u!a},<>}},{{,{<,>}},<>}},{}},{{{},},<,",!!i>,{<>}},{,{}},{{<'!!ai"!>,<{!>},<"!!!!!!>}}}},{{},{{{{<,!<,,'a,!>},,<}""{u">},{}},{},<,!>},}{',!>,}},{},{{}}},{!!!>}!>},},!>},<}>,{<,!>'a"!!!!e'>}}}},{{{{i>,,<{oi'e,"i!>!<>},{{},,<,au>},<,},},{{},,},<>}}}}},{{{{,},},<>}},{{},"!!!'{>},{<",e!!a!!{e>}},{<>}},{{{{u!!e!>,},}},{{{},{{{!!!>>},{}},{{{{}!{i!!,!}!!!"!>!}!!!>},<,a>},{}},{},},<'e!>},<}o>}}}}},{{{<{!!!a!!!!!!e{,o>},{{},{<'!u!>!>},},<,'!!!!{o}!!!e>}},{{{<>,!>,},<"!><<,>},{{<{,!>,!>!>},<<,"!!}!>e>},{<"!>,}}},{{{,{>},{,<{!>,!!i'i!>!>,<"o!!!>!i>}}},{{{},<{'e!>!!!>,,!>,!!!!!>,!!!>},<<<},{{},<}!!!>a!>},<}>},{{<{!>},},<{i}!!'>}}}}}},{{{{{,!!!>!>,!>},!>,}}},<,u!>,!"!!!>,{!!!>!!!>!!!>!!o!!!>>}},{}}},{}},{{{{{},<"">},},{i',e{!>},,,}},{}},{{{{{,{<"!>,{!!!>!!}!!!>!!!>>}}},{<'!!!>!>,}},{{{<'!>}i!iu!!!!!>!>},<,!>i'!!!>>},{<>}},{{},}}}},{{<}!!o},<<},a!>,"!e,{,'!!<>},a'<"'iu!>!!!>"!!!>u>}}},{{{{{{{<'!!!>},,<,},},{,u!>},,u{!>,<>,{}}}}},{{{{{},{<"!>}!>},}i{!!u{!!{<}"!>},<>}},{}},{{,<{a'!!!>!!!>>},!>!>},eo!>},<"!>},},{{},,<'a,>},,!!}a'!>,},,}}}},{{{{},{!>,!>!>},<"!>}'!!>}},{},{<,!>,<,a!>,!!!>e}e!>},<{o{'!!,<>,{<,o!!!,},,u>}}},{{},<>,{}},!!!>i!}!>},<'!>,},<}!>},,},{{},!>!>}iii!!!>},},,,<}!!{uo>}}},{{{},aa!!,>},{{<"!>},e!!oe'!,!!!>""!!!>!}i>,{{<},{<"<'!!ee"!>},},},>}}},!>},}},{<'<>,{},},}},{{<}!!e,{!>,<{!!ua!>},,{{>},{}}},}}}},{{{{{}},{<{u!!!>}!",,!!!>{'>,{}>,{{{}}}}}},{{},{{}},{},<'!!!!!>},<>}},{{{{{{<!uo>},{},{,,{}}},{{}}},{},{{{{{<"!!!>"<>,,{!!!>,e,>},{ua}!!!!eou!!{!!>}},{<<>,{<{}ei{!>},<"u}}">}},{{,!!!!!>,u!>,>},{{<}!}u!>},},!!!>>}}}},{{},{}},{{{{{<>},,,<"o'eu'!>,<'!>,}},{{{<,!!!{!'}!!,!!!!{!>,,<>},"!>'a!!!>,<'!>},<>}}},{{<,}!!i"a!!'u!>},},<,'}!},{,<'!!'!>},,>}},{{<}i"!>},<"ui>},{{}},{<"{!!io!,u!!!!!!'u!>,<>,{!>,}}}}},{{{},},<,i!,!>,!>},}},{,<}{!!!>},<>}},{{{{},{}}},{{},{,,},<'!!!><>}}}},{{{},,,,<>}},{{<{a!!!>}!!,!>,o!>,<>},{}},{,,<"!!!>!!i}!!!!o!>,<<,,,{{,<"{}i!>,<'aaaa}o,<",!!!>,<>}}}}},{{{,!>},e}'>}},{"!i!!a"o!>},,{'e!>}{<'!>,},,<"e>}},{{},<<}!>!!!!o}'!>,!!!>!>},,!>,,{{,}i>}}}}},{{!!>,<'{!!!!o'!!oe!!!},{{{},<>},{!>!>},}},{{{{}},{<}!!!>ooo{!!!>,},!!,}},{<>,{<,!oo,<>}},{}}},{<,!!!>,e!>,,,"e'<>,}!!!>aa!'!!{!>u{!>,<}!!!>!!o{!a>}}},{{{{},{{},},{{<'!!!>u'!>},}"o,!>},,<>},{{}}}},{{,<e!}o{>,},,'!!!'e!!!>>},{{<<>},},{{{"{!!!>},!aau!!!>'!<>,"!!!a'!!!>>},{}},{{<"{'!>!"}i!!!>eu'i}>}},{,!!!>!>},,a}!>,},<{>}}}},{{{{},<>},},<',<>},{u!!<,<'!>,<,>}},{<}u>},{}}},{{u!!{!>!!}>,{{{{{<">},{{},{,!!!>,}}},{<!!}ee!!!>>}},{<,!!!}!>},}},{},}}},{{},{{},{,},}'{!>!>},<>}}},{{{>}}},{{{}},{{}}}}},{{{}},{{{e'{"!>},<>},{{<,a!!!i!!aoo,>}}},{{{},ao!!!!',!!!>o"!!!e!>,<>}},{a}>},{<,oeo>}},{}}},{{{{}},{<,!>},<>},{{,<}a<"!!!>>,{!a!{e!!i!!,,,}}{o}ue},>}}}},{{<,!>},,},{{<}<<',ou!!!,}u!>},,},>}},{{},{},<},<}}u}{>}}}}},{{{{{!>},,!>o!>!>},<'!>!!!!oe!a!{o!!!>}u>},{{,,i!!!>>,{}},{{},{}}}},{{{!{a>,{<"!>},i'!>!>},!>,u!e>}},{{<>}},{<<}}!>},,<{<>,{}}},{}},{{{{{},<>}},,<"i''!!!>!>'"u!>!!!>!!!>>},{},!>},<}u'!!!!u,{,}},{{}}},{{{{{<<'!>},<,!!!!!!oua{!>,>},{{,,!>},<'!>},},,,!>!!!>!!!>!!!>>},{{{<},,<>},>}},{{<<<,<'<>}}},{{},<'!!ei!!aa},!>o!>},}}},{{e!>},},a">},{}},{}}}},{}}},{{{<>}},{<<"!>},a!!!!}!!!!!>!>,<'e},{{<,e!a!!!!,i!!!>},<"!>},<}>}}},{{{!!!>!!"!>,<,!!!>!>},},,,<'!!">},{{{!!{}>},{,'a!>!>},,},!>},},<"''ua},"!!{>}},{,{,e!>},<<"!!!!!!e!>!!'u'!!!!'ea{>}}},{{},<'i"!a,!a!<<'},<},{}}}}}},{{{{{<,!>},,uu!!aoa}>},{<>,{<',iee!!'>}},{{{<,!>,>,i!>{i>},{<"!!!",,i,>}},{}}},{{{<>,{}}},{{},{{{<},ie,{!'>,},},<>}}},{},!>},,e!>},<{!>,{{},<>}}}}},{{{,},<>},{{!!!>a{!>},<}{uiau,!,>,,},<,!>o!>},,},<}!<,oo>},<>},{}},{{<''e!>,!!,>,{{,},,!!!!!>!>,},,<>},{{{a>},{<{!ou>}}}}}},{>,<"!>",uu{!!!!e!>,<>}}},{{{},{{{{{},{"{!>},,''i!>},},}},{{{!>'}!>,,,},<>,,,a,}i!!},<>}}},{{!!!>!>,}}},{{{{<{}{!>},a>}},{}}},{{<,},},},},,}},{!!!>},,<>}},{{{{!!!>'!!{!!!>!a!!!>!>,<'i>}},{},<'au!a!>,<,i'>}},{!!a}'!"!>,<"o!!!!i<>,!!!>!>},"},<,!>,!>>},{{{},<'u'},,<,o!!!>{!>},}}},{{{'!>,,'o!!!>a{!!,<>,{{<}!>'a{aa{{>,{{},!,},!!o>}}},{{'e}iee{u>}}}}},{{{<>}},{{<>}},{{{},"!'!>a>}}}}},{{<'!>,'!>'e'>}}},{{{{},{<}i!"eo!>"ui{!>},<"">},{{u!>!>,!"!!"!!u>},<,}!>,<>}},{{{{>,{{},{}}},{{{},{}},{{{{},{}}},{<',u,!!!!!!!!!!!>{}!!i!>,<}}>}}},{{<'!!!,!!!>}!!!>!>,,<}"!!a!!>}}},{{{ii!!!!,<'u">},{}},{{{<!e}}!>>}},{,>,{}}},{},}oa!!!>>,{<}!>!{!>,,},,<>,{,<'!>},<}!!a"!!{'>}}}},{,<"o!{}a>}},{<>},{{{}},{{,'!>},<'!}!!auo>},{{}}},{{}}}},{{{},{{{'a!}{},<,!!{!>},"!oa!>,>}},{{},{!!a<>}}},{{}},{{{{},{<{!!!>!!{!>!!!>!!e>,{{<,!>!!!>!!,}>}}},{a,<<"<'!>a!!!e>,{!!'}!"!!!>'!!!!,!!{!ea!!!!!!{'!>},<{{{>}}},{{{<>}},},oe{!!"'!>,u!>,},e>}}},{{{,{<>}}},{{{,<}},!!ou}e!}},{u>},{{}}},{{{},!i!!{!!!}!!!>!>!!i!!"!o!>oia{e}>},{,{}},{{{}},{e"!!!>!!!>ui!!"u!>},>},{}}}}}},{{{u!>,i,!>},},{<}>}},{{}}}}},{{{{!,i'!!<'uee>}},{{!>,<',ai!!u!!!!!>!">},,,},{{!!!!!>!!!>!!!>!!!>!!!,!>,<,>,{{}}}}}},{{{{<'i"a{!!!>!,i!u!>!>},}},{<{!!"ii!>},<},u!>,,{a"{!>,<{!>,<>}},{{{{{},},{{},!>,"!a"u!>},<>}},{{}}},{{},<''!a!u>},{<>,{,<>}}},{{{{}}},{{},<>}}},{{,<>,{}},{{{<"!>,!e'u'!>},<{'>},<{uiaa}!!!{!>oo!!>}},{{,},'!!!>!"{!i>}}}}}"#; - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let worker_input = - input - .chars() - .enumerate() - .filter(|&(pos,_)| pos % peers == index) - .collect::>(); - - worker.dataflow::<(),_,_>(|scope| { - - let input = scope.new_collection_from(worker_input).1; - - // We will use parallel prefix to determine which characters are valid. - // The "state" at any position seems to be a cross product of - // - // { next_invalid, garbage } - // - // where the first bool indicates that the next character should be ignored, - // and the second bool indicates that we are in a garbage scope. We will - // encode this as the values 0 .. 4, where - // - // 0: valid, non-garbage - // 1: valid, garbage - // 2: invalid, non-garbage - // 3: invalid, garbage - // - // Each character initially describes a substring of length one, but we will - // build up the state transition for larger substrings, iteratively. - - let transitions = - input - .map(|(pos, character)| - (pos, match character { - '<' => [1, 1, 0, 1], // start garbage, if not ignored. - '>' => [0, 0, 0, 1], // end any started garbage, if not ignored. - '!' => [2, 3, 0, 1], // start/consume ignore bit; don't change garbage. - _ => [0, 1, 0, 1], // consume ignore bit, don't change garbage. - }) - ); - - // determine the transitions for intervals of positions, then the state starting from zero. - let ranges = pp_aggregate(transitions, |t1, t2| [t2[t1[0]], t2[t1[1]], t2[t1[2]], t2[t1[3]]]); - let values = pp_broadcast(ranges, 0, [0, 1, 2, 3], |state, trans| trans[*state]); - - // line up (position, symbol, state). - let symbols_state = input.join(values); - - // restrict the positions down to those that are neither '!' nor themselves cancelled. - let active = symbols_state.filter(|&(_, symbol, state)| symbol != '!' && (state == 0 || state == 1)); - - // part 1: accumulate for each '}' its depth. - let parens = active.filter(|&(_, symbol, state)| state == 0 && (symbol == '{' || symbol == '}')); - let depths = parens.map(|(pos, symbol, _)| (pos, if symbol == '{' { 1 } else { -1 })); - let ranges = pp_aggregate(depths, |sum1, sum2| sum1 + sum2); - let values = pp_broadcast(ranges, 0, 0, |sum1, sum2| sum1 + sum2); - - parens - .filter(|&(_pos, symbol, _)| symbol == '}') - .map(|(pos, symbol, _)| (pos, symbol)) - .join(values) - .explode(|(_pos, _sym, sum)| Some(((), sum))) - .consolidate() - .inspect(|x| println!("part1: {:?}", x.2)); - - // part 2: count garbage symbols except the closing '>'. - active - .filter(|&(_, symbol, state)| state == 1 && symbol != '>') - .map(|_| ()) - .consolidate() - .inspect(|x| println!("part2: {:?}", x.2)); - }); - - }).unwrap(); -} - -/// Accumulate data in `collection` into all powers-of-two intervals containing them. -fn pp_aggregate(collection: VecCollection, combine: F) -> VecCollection -where - G: Scope, - D: Data, - F: Fn(D, &D) -> D + 'static, -{ - // initial ranges are at each index, and with width 2^0. - let unit_ranges = collection.map(|(index, data)| ((index, 0), data)); - - unit_ranges - .iterate(|scope, ranges| - - // Each available range, of size less than usize::MAX, advertises itself as the range - // twice as large, aligned to integer multiples of its size. Each range, which may contain at - // most two elements, then summarizes itself using the `combine` function. Finally, we re-add - // the initial `unit_ranges` intervals, so that the set of ranges grows monotonically. - - ranges - .filter(|&((_pos, log), _)| log < 64) - .map(|((pos, log), data)| ((pos & !(1 << log), log + 1), (pos, data))) - .group(move |_, input, output| { - let mut result = (input[0].0).1.clone(); - if input.len() > 1 { result = combine(result, &(input[1].0).1); } - output.push((result, 1)); - }) - .concat(unit_ranges.enter(scope)) - ) -} - -/// Produces the accumulated values at each of the `usize` locations in `aggregates` (and others). -fn pp_broadcast( - ranges: VecCollection, - seed: B, - zero: D, - combine: F) -> VecCollection -where - G: Scope, - D: Data, - B: Data+::std::hash::Hash, - F: Fn(&B, &D) -> B + 'static, -{ - // Each range proposes an empty first child, to provide for its second child if it has no sibling. - // This is important if we want to reconstruct - let zero_ranges = - ranges - .map(move |((pos, log),_)| ((pos, if log > 0 { log - 1 } else { 0 }), zero.clone())) - .antijoin(ranges.map(|((pos, log),_)| (pos, log))); - - let aggregates = ranges.concat(zero_ranges); - - let init_state = - Some(((0, seed), Default::default(), 1)) - .to_stream(&mut aggregates.scope()) - .as_collection(); - - init_state - .iterate(|scope, state| { - aggregates - .filter(|&((_, log),_)| log < 64) // the log = 64 interval doesn't help us here (overflows). - .enter(scope) - .map(|((pos, log), data)| (pos, (log, data))) - .join_map(state, move |&pos, &(log, ref data), state| (pos + (1 << log), combine(state, data))) - .concat(init_state.enter(scope)) - .distinct() - }) - .consolidate() -} diff --git a/advent_of_code_2017/src/bin/day_10.rs b/advent_of_code_2017/src/bin/day_10.rs deleted file mode 100644 index fb998f636f..0000000000 --- a/advent_of_code_2017/src/bin/day_10.rs +++ /dev/null @@ -1,64 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/8 - -use differential_dataflow::VecCollection; -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = "212,254,178,237,2,0,1,54,167,92,117,125,255,61,159,164"; - // let input = "225,171,131,2,35,5,0,13,1,246,54,97,255,98,254,110"; - // let input = ""; - // let input = "AoC 2017"; - // let input = "1,2,3"; - // let input = "1,2,4"; - - timely::execute_from_args(std::env::args(), move |worker| { - - // let parsed = input.split(',').map(|x| x.parse::().unwrap()).collect::>(); - // let part1 = knot_step(parsed.iter().cloned(), 1); - // println!("part1: {:?}", (part1[0] as usize) * (part1[1] as usize)); - - let mut bytes = input.as_bytes().iter().cloned().collect::>(); - bytes.push(17); - bytes.push(31); - bytes.push(73); - bytes.push(47); - bytes.push(23); - let part2 = knot_step(bytes.iter().cloned(), 64); - - print!("part2: "); - for byte in 0 .. 16 { - let mut result = 0; - for step in 0 .. 16 { - result ^= part2[16 * byte + step]; - } - print!("{:02x}", result); - } - println!(); - - }).unwrap(); -} - -fn knot_step+Clone>(iter: I, rounds: usize) -> Vec { - - let mut state = (0 .. 256u16).map(|x| x as u8).collect::>(); - let mut cursor = 0; - let mut step = 0; - - for _ in 0 .. rounds { - for width in iter.clone() { - let width = width as usize; - for swap in 0 .. width / 2 { - state.swap((cursor + swap) % 256, (cursor + width - swap - 1) % 256); - } - cursor = (cursor + width + step) % 256; - step += 1; - } - } - - state -} diff --git a/advent_of_code_2017/src/bin/day_11.rs b/advent_of_code_2017/src/bin/day_11.rs deleted file mode 100644 index 657fc00e74..0000000000 --- a/advent_of_code_2017/src/bin/day_11.rs +++ /dev/null @@ -1,64 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/11 - -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; -use differential_dataflow::difference::DiffPair; - -use differential_dataflow::algorithms::prefix_sum::PrefixSum; - -fn main() { - - let input = "s,se,ne,ne,ne,ne,ne,ne,ne,n,sw,sw,nw,sw,n,nw,nw,sw,nw,nw,nw,nw,sw,nw,nw,nw,nw,s,nw,nw,sw,nw,sw,sw,sw,nw,sw,sw,sw,sw,sw,sw,sw,s,sw,sw,sw,sw,se,sw,s,s,sw,s,ne,nw,nw,s,n,s,sw,s,sw,nw,se,s,s,s,s,s,nw,s,nw,s,s,se,se,se,se,se,se,s,se,s,s,se,ne,se,se,se,se,se,ne,ne,se,se,se,se,se,ne,se,se,se,sw,sw,se,ne,s,ne,se,sw,n,sw,ne,ne,se,se,ne,se,ne,se,se,se,se,sw,ne,se,se,ne,se,sw,se,ne,se,ne,s,ne,ne,ne,ne,s,se,ne,ne,ne,s,ne,nw,ne,s,ne,ne,s,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,n,ne,ne,ne,n,n,se,ne,ne,ne,ne,n,ne,ne,n,nw,ne,sw,ne,ne,n,n,ne,sw,n,ne,n,s,n,n,ne,sw,ne,ne,s,n,n,n,n,se,ne,ne,n,n,n,ne,n,n,n,n,n,n,n,nw,n,s,n,se,n,n,n,nw,n,n,n,n,nw,n,n,n,n,se,sw,n,nw,n,nw,n,ne,sw,n,ne,n,s,n,n,n,nw,nw,n,n,n,n,n,n,n,n,nw,nw,nw,n,nw,ne,n,nw,n,nw,nw,nw,nw,nw,nw,n,nw,s,nw,n,nw,sw,nw,ne,nw,sw,nw,nw,n,nw,nw,nw,sw,nw,nw,nw,n,sw,nw,nw,nw,nw,nw,nw,nw,nw,nw,n,nw,n,nw,se,nw,nw,nw,nw,nw,se,nw,nw,nw,nw,nw,s,s,nw,nw,nw,sw,nw,nw,nw,nw,n,nw,se,nw,nw,sw,nw,sw,s,sw,nw,s,nw,sw,nw,nw,nw,n,nw,n,nw,sw,n,nw,nw,nw,sw,nw,n,s,nw,nw,nw,se,s,se,nw,sw,s,nw,sw,nw,sw,se,ne,nw,nw,se,nw,nw,sw,sw,nw,nw,sw,s,nw,s,nw,nw,nw,sw,nw,nw,sw,nw,nw,sw,nw,sw,s,nw,nw,sw,sw,se,sw,nw,nw,sw,n,nw,sw,sw,sw,sw,sw,sw,s,nw,sw,sw,sw,s,nw,nw,sw,nw,sw,nw,sw,s,sw,sw,s,sw,sw,ne,s,sw,sw,se,sw,sw,sw,sw,sw,sw,se,nw,sw,sw,sw,sw,nw,nw,sw,nw,sw,sw,sw,sw,sw,sw,s,sw,se,sw,se,nw,sw,sw,sw,sw,sw,sw,s,ne,nw,sw,s,sw,nw,sw,s,s,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,nw,sw,sw,n,sw,sw,sw,sw,sw,sw,ne,s,ne,sw,sw,s,sw,sw,sw,sw,sw,ne,sw,sw,s,nw,nw,sw,se,s,sw,n,n,sw,sw,se,sw,sw,sw,sw,sw,sw,se,n,ne,sw,sw,ne,s,s,s,sw,s,sw,s,sw,n,sw,s,s,se,s,sw,sw,se,s,sw,n,n,sw,sw,s,sw,s,s,sw,nw,s,sw,s,s,ne,s,s,n,s,sw,s,s,s,s,sw,s,ne,n,s,s,nw,ne,sw,s,s,n,s,s,n,s,sw,s,s,sw,s,s,s,ne,s,sw,s,sw,ne,s,sw,sw,s,ne,n,s,sw,s,s,nw,sw,s,s,sw,s,s,ne,s,s,s,s,s,s,s,s,s,sw,se,s,se,s,se,ne,se,s,s,s,sw,sw,s,s,sw,s,s,se,s,s,s,s,s,s,s,s,s,s,n,s,s,s,nw,s,s,s,s,ne,s,se,se,ne,s,s,s,ne,s,s,s,s,s,s,s,n,se,s,s,se,se,s,n,s,s,n,sw,se,n,s,s,ne,s,se,s,s,se,s,s,s,s,se,s,s,se,se,se,nw,s,s,s,s,se,n,s,se,s,n,s,s,s,s,s,s,s,se,se,s,se,n,se,sw,se,s,se,n,se,s,n,nw,sw,s,sw,se,sw,se,s,ne,s,s,s,se,sw,se,s,s,s,sw,nw,ne,s,s,s,nw,se,s,sw,sw,se,s,se,se,se,se,s,se,s,s,n,sw,nw,se,se,ne,s,se,s,s,nw,s,s,se,se,se,s,n,se,se,se,s,s,se,ne,se,s,ne,nw,nw,s,n,n,nw,se,s,s,se,s,se,se,se,s,s,s,se,s,se,s,ne,s,n,s,sw,ne,se,s,se,se,se,se,se,s,se,se,se,s,n,se,ne,se,se,se,se,s,se,s,s,se,nw,se,s,s,se,se,n,se,se,se,se,se,se,se,s,se,se,se,nw,se,se,s,se,se,s,se,se,se,se,s,s,n,sw,se,ne,se,se,se,s,sw,se,ne,se,se,se,se,se,s,se,nw,se,se,se,se,se,n,se,s,se,n,se,se,se,se,se,se,nw,s,se,se,s,se,se,se,se,n,nw,se,se,se,sw,se,sw,ne,se,se,se,se,se,se,se,se,se,se,se,se,se,se,ne,nw,se,se,ne,se,se,se,nw,se,se,sw,se,se,se,sw,se,se,se,se,se,se,se,se,nw,se,se,se,se,se,se,se,se,se,se,ne,se,sw,se,se,ne,se,se,s,se,se,ne,ne,se,se,se,se,se,se,se,se,s,se,nw,sw,se,se,se,nw,se,ne,s,se,ne,nw,se,nw,se,se,se,se,ne,sw,ne,se,se,se,se,sw,se,ne,se,s,ne,nw,ne,ne,se,n,se,se,se,sw,ne,se,se,nw,sw,se,se,se,se,ne,s,nw,n,ne,ne,ne,se,se,nw,ne,se,ne,se,se,se,nw,ne,ne,se,se,se,nw,ne,ne,se,nw,ne,se,s,ne,ne,ne,se,se,ne,n,se,se,n,se,se,se,se,ne,sw,se,ne,ne,se,se,ne,se,se,sw,ne,sw,ne,se,s,se,n,ne,se,nw,se,se,se,ne,se,sw,ne,sw,se,ne,se,se,se,ne,nw,ne,ne,ne,ne,ne,ne,se,se,se,se,n,nw,sw,se,ne,se,n,ne,s,se,n,ne,se,se,ne,sw,ne,se,ne,s,ne,ne,se,se,ne,ne,n,ne,ne,ne,s,ne,ne,ne,se,sw,ne,ne,ne,se,ne,s,se,nw,nw,ne,se,ne,ne,n,se,se,s,ne,se,ne,ne,se,ne,ne,nw,ne,n,se,ne,se,se,ne,ne,ne,s,ne,s,ne,ne,ne,se,ne,n,nw,sw,se,ne,ne,nw,s,se,ne,se,ne,ne,ne,ne,ne,n,ne,sw,ne,s,se,ne,ne,se,ne,se,se,ne,ne,se,sw,n,ne,s,sw,s,ne,ne,ne,ne,ne,sw,ne,se,se,sw,ne,ne,ne,ne,ne,ne,ne,se,ne,ne,se,se,ne,ne,nw,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,se,ne,ne,sw,ne,se,sw,s,ne,ne,ne,s,s,ne,ne,n,ne,se,ne,ne,n,ne,ne,ne,ne,sw,ne,ne,ne,sw,sw,ne,ne,ne,ne,ne,sw,ne,ne,ne,ne,se,ne,ne,ne,ne,ne,ne,se,ne,sw,nw,ne,ne,ne,n,ne,ne,ne,ne,nw,nw,sw,n,ne,ne,nw,ne,ne,ne,ne,nw,ne,nw,ne,ne,ne,n,ne,ne,ne,sw,ne,n,sw,nw,ne,ne,n,ne,ne,s,ne,ne,ne,ne,ne,ne,ne,ne,n,n,ne,ne,se,nw,ne,n,sw,ne,ne,ne,ne,ne,ne,n,ne,ne,ne,ne,ne,nw,ne,ne,ne,se,s,ne,n,ne,ne,ne,ne,se,n,n,ne,ne,ne,n,s,n,ne,n,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,se,ne,sw,n,nw,s,ne,nw,s,ne,n,ne,ne,ne,ne,n,se,ne,ne,ne,ne,ne,se,n,nw,ne,ne,n,ne,ne,n,ne,n,ne,ne,ne,n,ne,se,ne,ne,ne,sw,ne,ne,ne,ne,n,ne,ne,ne,n,n,ne,ne,ne,se,n,ne,ne,ne,ne,ne,ne,ne,n,ne,ne,s,ne,ne,ne,ne,ne,se,se,nw,n,n,nw,ne,ne,n,ne,ne,ne,s,ne,ne,ne,n,nw,s,nw,n,n,nw,n,se,ne,ne,ne,nw,ne,ne,ne,ne,ne,sw,n,ne,ne,ne,ne,n,ne,n,se,ne,n,n,ne,sw,ne,n,ne,n,ne,n,ne,ne,n,ne,n,ne,n,ne,nw,ne,ne,n,ne,sw,sw,n,ne,n,ne,ne,ne,ne,ne,ne,ne,ne,nw,nw,s,ne,n,ne,nw,n,ne,ne,n,n,sw,nw,n,ne,ne,n,n,ne,ne,ne,ne,ne,n,nw,ne,n,ne,ne,ne,ne,n,n,s,ne,se,s,ne,sw,ne,n,sw,n,ne,n,n,n,nw,n,nw,n,se,ne,ne,ne,n,ne,n,ne,sw,ne,n,ne,n,n,sw,ne,nw,n,ne,ne,n,ne,n,n,se,s,n,n,n,n,ne,sw,ne,n,se,se,se,n,s,n,n,n,n,n,ne,n,ne,n,sw,ne,n,ne,n,ne,n,ne,n,sw,s,n,n,ne,ne,n,n,n,s,se,n,se,n,ne,n,n,n,n,n,se,sw,ne,n,n,n,n,n,n,se,n,s,nw,sw,ne,n,n,ne,n,n,n,n,n,ne,ne,n,n,ne,n,ne,nw,n,ne,ne,ne,ne,n,n,nw,nw,nw,n,n,n,nw,ne,ne,n,nw,nw,ne,se,se,n,sw,ne,ne,ne,n,n,n,ne,nw,nw,n,nw,n,n,n,nw,n,n,nw,sw,n,se,n,s,n,n,n,ne,n,n,n,ne,n,n,n,n,n,nw,n,n,n,ne,n,n,n,se,n,n,n,se,n,n,n,n,n,n,s,n,n,n,n,ne,n,n,n,n,n,n,n,n,sw,n,ne,s,ne,n,n,sw,n,n,n,se,n,ne,n,s,n,se,sw,n,n,n,ne,n,n,n,n,ne,n,s,n,n,se,n,n,s,n,n,n,n,sw,n,n,n,sw,n,s,sw,n,n,n,ne,n,n,n,n,se,n,sw,n,n,n,n,n,n,n,n,n,se,n,n,n,se,n,ne,n,n,n,n,n,sw,n,se,n,n,n,n,n,n,n,nw,n,n,n,n,n,n,n,n,s,n,nw,n,n,n,n,n,n,n,n,n,n,n,n,s,n,n,n,n,nw,se,n,n,n,nw,n,n,se,nw,nw,n,n,n,se,n,n,n,n,n,nw,n,n,n,ne,s,nw,n,se,se,se,ne,ne,n,n,n,n,nw,n,n,nw,n,nw,n,n,n,n,nw,n,se,n,n,n,n,n,n,nw,n,n,n,n,s,n,n,nw,n,n,nw,n,n,n,se,nw,n,n,sw,s,n,n,ne,s,n,n,n,n,n,sw,n,n,n,n,n,nw,s,n,nw,s,n,n,n,nw,nw,nw,n,nw,sw,n,nw,n,n,n,se,nw,nw,n,n,n,nw,n,n,n,n,nw,nw,n,n,sw,nw,n,n,nw,n,n,n,ne,n,n,nw,nw,n,n,n,n,se,s,s,ne,n,n,se,n,n,sw,nw,n,nw,n,nw,n,nw,n,ne,n,n,s,sw,nw,n,n,n,nw,ne,nw,nw,n,n,n,ne,nw,n,n,n,n,n,nw,n,n,nw,nw,sw,nw,n,n,n,n,n,n,n,n,n,s,nw,nw,nw,s,n,nw,n,n,nw,n,nw,n,n,n,n,nw,n,sw,n,s,s,nw,ne,n,n,nw,n,nw,sw,n,n,ne,n,n,ne,n,n,n,sw,nw,n,nw,s,nw,s,s,nw,n,nw,n,n,n,se,s,s,nw,n,n,n,nw,n,n,nw,nw,sw,nw,n,n,n,nw,nw,se,n,nw,n,nw,s,nw,n,n,nw,ne,s,nw,n,s,nw,n,nw,ne,n,nw,nw,n,n,se,s,n,n,sw,nw,n,nw,n,nw,nw,ne,nw,n,n,nw,nw,nw,nw,nw,n,nw,nw,n,n,nw,nw,s,nw,n,se,n,se,n,n,nw,nw,n,nw,n,n,nw,nw,se,n,n,n,se,se,nw,n,nw,s,n,n,n,ne,nw,ne,nw,s,nw,nw,n,nw,nw,n,se,n,nw,nw,nw,nw,nw,nw,ne,sw,s,n,ne,nw,nw,n,nw,n,n,n,n,n,n,n,se,nw,nw,nw,nw,n,n,n,se,nw,sw,nw,se,n,sw,n,nw,nw,nw,se,n,s,nw,ne,nw,nw,s,n,ne,nw,s,nw,nw,n,n,nw,nw,nw,n,nw,nw,nw,nw,n,sw,sw,nw,n,nw,n,n,nw,ne,se,n,nw,nw,n,n,nw,nw,s,n,n,n,n,n,n,sw,nw,s,nw,s,nw,n,ne,nw,nw,n,nw,nw,nw,n,n,nw,nw,sw,nw,nw,nw,nw,nw,nw,nw,nw,n,nw,nw,nw,s,nw,nw,n,nw,nw,n,nw,nw,sw,n,n,nw,nw,se,nw,n,nw,n,s,nw,n,n,s,nw,nw,n,nw,nw,nw,nw,nw,nw,n,nw,nw,nw,nw,n,n,nw,nw,nw,sw,nw,nw,nw,nw,ne,nw,n,nw,ne,se,nw,n,n,nw,nw,n,n,n,nw,ne,n,nw,nw,nw,se,nw,nw,nw,nw,nw,se,nw,nw,s,n,nw,n,nw,n,nw,nw,sw,n,n,nw,nw,ne,nw,n,n,nw,n,nw,nw,nw,se,ne,n,n,nw,n,s,nw,n,nw,ne,ne,nw,nw,nw,nw,n,n,nw,nw,nw,nw,n,nw,nw,nw,nw,nw,nw,nw,nw,nw,ne,nw,n,n,nw,nw,n,nw,se,sw,n,n,nw,s,nw,nw,n,nw,nw,nw,nw,nw,n,nw,se,n,nw,nw,s,nw,nw,nw,n,nw,nw,nw,nw,nw,nw,n,ne,nw,nw,nw,nw,nw,nw,se,n,nw,nw,s,s,n,nw,sw,n,nw,nw,n,nw,se,nw,nw,nw,n,nw,s,nw,nw,nw,nw,se,nw,n,nw,s,nw,nw,nw,nw,ne,n,se,ne,nw,nw,n,nw,nw,nw,nw,nw,nw,nw,sw,nw,ne,nw,ne,nw,nw,sw,nw,nw,nw,s,n,nw,nw,nw,nw,nw,nw,nw,sw,nw,nw,nw,nw,nw,nw,s,nw,nw,nw,nw,nw,nw,n,nw,ne,nw,nw,nw,nw,nw,sw,nw,s,nw,nw,s,nw,sw,s,nw,nw,nw,nw,nw,nw,nw,s,s,nw,nw,nw,se,nw,nw,ne,nw,nw,se,nw,nw,nw,nw,nw,ne,nw,s,nw,sw,s,sw,n,nw,sw,nw,nw,nw,sw,nw,nw,n,nw,nw,nw,nw,nw,nw,nw,nw,se,sw,nw,nw,n,n,nw,sw,nw,nw,n,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,sw,nw,nw,nw,nw,nw,nw,se,nw,nw,n,sw,nw,se,n,sw,nw,nw,nw,nw,s,nw,nw,nw,nw,nw,nw,nw,nw,nw,se,ne,sw,ne,s,nw,nw,nw,nw,ne,nw,nw,nw,nw,nw,nw,se,nw,sw,nw,se,nw,nw,nw,nw,sw,nw,nw,nw,nw,nw,nw,nw,nw,sw,sw,nw,nw,nw,nw,sw,nw,nw,nw,s,sw,sw,sw,sw,nw,sw,sw,nw,se,nw,nw,nw,n,nw,nw,nw,n,nw,sw,nw,nw,nw,nw,s,nw,nw,nw,ne,nw,nw,ne,nw,nw,sw,n,nw,nw,nw,sw,nw,nw,nw,nw,nw,sw,sw,nw,s,sw,ne,nw,nw,n,nw,nw,nw,nw,sw,nw,sw,nw,n,nw,nw,nw,nw,nw,s,nw,sw,nw,nw,s,nw,sw,sw,nw,sw,nw,nw,sw,sw,nw,nw,sw,ne,n,nw,ne,sw,s,nw,sw,nw,se,n,nw,sw,nw,nw,nw,nw,nw,nw,nw,sw,sw,sw,sw,sw,sw,nw,nw,s,sw,nw,nw,sw,nw,nw,s,s,sw,nw,nw,sw,s,nw,n,nw,nw,nw,nw,nw,nw,ne,sw,ne,nw,nw,nw,nw,sw,nw,se,nw,sw,nw,nw,nw,nw,nw,sw,nw,nw,nw,sw,nw,s,sw,nw,nw,nw,nw,nw,sw,ne,n,nw,nw,se,nw,sw,nw,ne,nw,nw,nw,sw,sw,n,nw,nw,n,sw,ne,nw,se,sw,se,sw,sw,nw,nw,sw,nw,se,sw,s,n,nw,sw,sw,n,sw,n,sw,n,sw,nw,sw,sw,nw,sw,nw,ne,nw,n,nw,nw,se,nw,nw,sw,nw,sw,s,nw,sw,nw,sw,nw,nw,sw,nw,sw,nw,n,nw,n,se,nw,ne,nw,nw,sw,sw,nw,sw,nw,nw,n,nw,nw,sw,nw,n,sw,sw,se,sw,nw,sw,nw,nw,nw,sw,sw,sw,nw,nw,sw,nw,sw,nw,s,se,n,sw,ne,nw,sw,sw,sw,sw,nw,nw,nw,nw,sw,se,sw,nw,ne,sw,nw,sw,nw,nw,nw,se,nw,sw,nw,sw,nw,nw,sw,sw,nw,n,sw,nw,nw,sw,nw,nw,sw,nw,sw,sw,sw,sw,nw,sw,sw,sw,sw,se,nw,nw,sw,nw,sw,sw,se,nw,nw,nw,nw,nw,nw,s,sw,sw,sw,nw,nw,n,nw,nw,nw,sw,nw,sw,sw,ne,ne,s,nw,se,nw,sw,nw,nw,nw,nw,sw,nw,nw,nw,ne,ne,sw,nw,nw,nw,nw,nw,ne,sw,nw,nw,sw,nw,nw,se,sw,nw,nw,nw,sw,n,sw,sw,sw,ne,nw,nw,sw,nw,nw,nw,sw,nw,sw,nw,n,nw,n,nw,ne,ne,nw,nw,sw,nw,sw,sw,sw,nw,sw,se,nw,nw,nw,sw,sw,sw,sw,nw,sw,nw,sw,nw,sw,sw,sw,sw,sw,se,nw,nw,nw,sw,sw,sw,nw,nw,nw,nw,sw,sw,sw,n,nw,nw,sw,sw,ne,nw,sw,nw,sw,nw,sw,n,nw,sw,nw,sw,s,s,sw,nw,nw,sw,nw,nw,sw,ne,sw,se,sw,nw,nw,sw,nw,nw,n,nw,nw,nw,sw,nw,sw,nw,se,sw,se,sw,sw,sw,se,sw,sw,s,nw,sw,nw,nw,ne,nw,sw,sw,sw,sw,nw,nw,sw,n,sw,sw,sw,se,nw,ne,ne,sw,nw,se,nw,sw,s,nw,s,sw,nw,n,s,sw,s,sw,sw,sw,nw,nw,sw,nw,s,se,sw,n,sw,sw,sw,sw,sw,sw,ne,nw,sw,se,sw,s,nw,sw,sw,nw,ne,nw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,nw,se,nw,sw,nw,sw,sw,sw,sw,sw,sw,sw,nw,nw,sw,nw,sw,sw,sw,sw,ne,sw,s,sw,nw,ne,sw,nw,nw,sw,sw,sw,sw,sw,nw,sw,nw,sw,s,nw,sw,sw,nw,nw,nw,sw,sw,ne,sw,sw,sw,sw,nw,sw,sw,se,sw,sw,sw,n,nw,nw,sw,n,nw,sw,ne,nw,sw,sw,sw,sw,nw,nw,nw,nw,sw,nw,nw,s,sw,nw,nw,sw,sw,ne,sw,sw,sw,sw,s,se,sw,sw,sw,n,nw,ne,nw,nw,sw,sw,s,se,s,sw,nw,nw,nw,sw,sw,se,nw,nw,sw,sw,nw,sw,sw,nw,sw,nw,sw,se,sw,sw,nw,s,nw,nw,n,sw,ne,nw,s,sw,sw,sw,sw,s,sw,nw,se,n,sw,nw,sw,sw,sw,sw,sw,sw,s,nw,nw,ne,n,sw,sw,sw,sw,sw,nw,nw,sw,nw,nw,nw,sw,nw,n,sw,se,sw,sw,sw,sw,sw,sw,nw,sw,s,nw,sw,sw,sw,sw,se,sw,n,ne,sw,sw,sw,sw,se,sw,sw,nw,n,ne,sw,se,ne,sw,sw,sw,nw,ne,s,sw,sw,nw,sw,sw,nw,nw,sw,sw,s,sw,sw,sw,sw,sw,sw,se,nw,sw,sw,sw,sw,se,sw,sw,sw,sw,sw,n,sw,sw,sw,nw,se,sw,sw,se,sw,sw,nw,sw,sw,sw,sw,sw,ne,nw,sw,n,sw,sw,nw,sw,sw,sw,sw,ne,sw,se,s,sw,n,sw,sw,sw,sw,sw,sw,s,sw,sw,sw,sw,nw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,se,nw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,ne,n,nw,ne,sw,sw,sw,sw,sw,sw,ne,sw,sw,sw,ne,sw,sw,ne,sw,sw,nw,sw,sw,nw,sw,sw,se,sw,sw,sw,nw,sw,sw,n,sw,sw,sw,sw,sw,ne,ne,sw,sw,s,sw,sw,sw,sw,sw,sw,sw,se,sw,sw,se,sw,ne,sw,sw,sw,se,s,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,nw,nw,sw,sw,ne,sw,sw,sw,sw,se,sw,sw,n,sw,sw,sw,sw,s,sw,sw,sw,s,sw,sw,sw,sw,se,sw,sw,sw,s,sw,sw,ne,sw,sw,sw,ne,se,sw,sw,sw,sw,sw,sw,nw,s,sw,s,sw,sw,sw,sw,sw,sw,n,sw,sw,n,sw,sw,sw,se,sw,sw,sw,sw,sw,sw,s,s,sw,ne,sw,n,sw,s,sw,nw,sw,sw,sw,ne,sw,sw,nw,sw,sw,ne,sw,sw,sw,sw,sw,ne,sw,sw,sw,sw,sw,sw,se,sw,sw,sw,sw,sw,sw,sw,sw,sw,s,sw,sw,sw,sw,sw,sw,se,sw,s,sw,sw,sw,sw,sw,sw,sw,se,sw,s,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,nw,sw,nw,sw,sw,sw,se,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,s,sw,nw,sw,sw,se,sw,sw,sw,nw,sw,nw,sw,sw,sw,sw,sw,sw,s,sw,s,sw,sw,sw,sw,sw,sw,s,sw,sw,nw,sw,sw,sw,sw,sw,s,sw,s,n,sw,sw,sw,nw,sw,ne,sw,sw,sw,sw,sw,s,sw,nw,sw,n,s,sw,s,sw,n,se,sw,sw,sw,sw,sw,sw,sw,n,sw,n,sw,n,s,sw,nw,sw,sw,s,sw,sw,n,sw,sw,sw,nw,sw,sw,s,sw,sw,sw,sw,sw,sw,sw,sw,s,s,se,se,sw,sw,sw,sw,sw,sw,sw,se,s,sw,sw,sw,s,sw,n,sw,sw,sw,sw,sw,sw,sw,sw,sw,s,sw,nw,sw,sw,sw,sw,s,ne,ne,sw,ne,sw,se,sw,nw,sw,sw,sw,sw,sw,s,nw,s,sw,s,sw,sw,sw,sw,n,n,sw,se,n,sw,sw,sw,sw,sw,sw,ne,s,ne,s,sw,sw,sw,sw,s,sw,sw,nw,s,sw,sw,se,sw,sw,s,nw,sw,sw,sw,s,ne,sw,sw,sw,n,n,sw,sw,sw,nw,sw,s,ne,sw,sw,sw,sw,s,s,s,nw,s,s,sw,ne,s,sw,sw,sw,s,nw,sw,sw,sw,s,sw,se,s,s,s,s,sw,s,sw,sw,sw,sw,sw,sw,s,sw,s,sw,s,sw,ne,sw,sw,se,sw,sw,s,sw,s,sw,s,se,s,sw,sw,s,s,sw,sw,s,sw,sw,sw,sw,s,s,sw,ne,sw,n,s,n,se,sw,s,sw,s,sw,n,ne,sw,se,sw,ne,sw,s,s,s,sw,nw,sw,sw,s,sw,sw,sw,s,nw,sw,sw,n,sw,sw,sw,n,ne,s,sw,sw,nw,sw,nw,sw,s,n,s,ne,sw,s,s,s,n,nw,sw,sw,sw,n,nw,s,sw,sw,sw,se,s,sw,sw,sw,se,sw,ne,ne,sw,sw,s,sw,sw,s,n,sw,nw,sw,sw,sw,s,nw,s,s,sw,sw,s,sw,sw,s,n,sw,s,sw,s,s,s,s,s,s,s,s,se,ne,s,ne,sw,sw,s,s,sw,sw,s,nw,s,sw,sw,sw,sw,s,n,s,nw,sw,sw,sw,sw,sw,s,sw,s,s,s,ne,se,s,sw,sw,sw,sw,sw,sw,s,s,se,sw,sw,s,s,sw,sw,sw,se,sw,s,sw,se,sw,s,nw,sw,se,sw,sw,ne,sw,s,s,sw,s,s,nw,sw,sw,s,se,sw,s,s,sw,ne,s,sw,s,s,s,sw,s,sw,s,sw,s,sw,sw,ne,s,s,s,s,sw,nw,ne,s,sw,sw,s,sw,sw,s,nw,s,s,se,ne,n,sw,sw,sw,sw,s,sw,s,sw,se,s,sw,se,sw,s,sw,sw,sw,sw,sw,sw,s,se,sw,sw,se,nw,sw,sw,sw,s,ne,sw,s,sw,sw,s,se,sw,nw,n,sw,sw,nw,sw,sw,sw,sw,sw,ne,n,s,s,sw,sw,sw,n,s,s,s,ne,sw,ne,nw,sw,s,s,se,ne,n,ne,sw,sw,sw,sw,se,sw,sw,sw,sw,sw,sw,sw,s,s,sw,s,s,nw,s,s,ne,sw,s,sw,sw,s,s,s,s,s,s,sw,s,sw,s,sw,s,s,s,s,sw,ne,sw,s,s,n,s,s,n,sw,s,s,sw,s,sw,s,sw,sw,sw,sw,n,s,sw,sw,s,sw,s,ne,ne,sw,s,nw,s,s,se,s,sw,sw,sw,sw,s,s,sw,sw,sw,s,n,sw,s,s,sw,s,s,sw,sw,sw,n,sw,sw,sw,s,s,sw,sw,s,sw,s,sw,sw,nw,s,sw,sw,sw,s,sw,sw,s,sw,sw,s,sw,s,s,s,s,sw,sw,sw,s,s,sw,sw,n,s,nw,sw,sw,n,sw,s,s,s,s,n,sw,sw,s,sw,sw,s,s,s,s,s,s,s,sw,sw,s,se,s,s,sw,s,s,sw,nw,s,s,sw,s,s,s,s,sw,s,sw,sw,sw,s,ne,sw,sw,s,s,s,s,nw,s,s,sw,s,sw,s,s,sw,s,s,s,s,s,s,sw,sw,s,se,nw,s,sw,sw,s,sw,s,s,sw,sw,s,s,s,s,s,sw,sw,s,s,s,s,sw,s,sw,sw,sw,n,ne,s,s,s,sw,sw,sw,s,s,s,s,s,ne,se,ne,s,ne,s,sw,s,sw,sw,sw,s,nw,sw,n,sw,sw,ne,se,sw,s,sw,s,se,s,n,n,s,s,s,ne,s,sw,s,s,s,sw,sw,s,s,s,s,s,s,sw,sw,sw,sw,s,sw,s,sw,sw,s,s,sw,se,s,sw,s,s,nw,s,s,s,sw,s,sw,sw,s,nw,s,sw,nw,s,sw,s,se,s,s,s,s,s,nw,s,s,n,s,nw,s,s,sw,nw,s,s,sw,s,s,s,s,sw,s,s,s,n,sw,s,s,ne,se,s,nw,s,sw,sw,n,s,ne,s,s,ne,sw,s,s,sw,s,sw,s,sw,nw,s,n,sw,s,n,sw,s,sw,s,s,nw,s,sw,n,sw,s,n,sw,ne,s,sw,sw,nw,s,sw,s,nw,s,sw,s,sw,s,s,sw,ne,s,s,s,sw,s,sw,ne,sw,ne,sw,n,s,s,s,s,s,sw,s,nw,s,nw,s,nw,se,s,sw,sw,n,s,s,s,sw,ne,s,sw,s,ne,sw,s,s,s,ne,s,s,s,s,nw,s,s,se,s,s,s,sw,s,s,s,s,s,s,n,s,ne,s,sw,s,se,se,sw,ne,s,s,n,sw,s,s,s,sw,n,n,n,s,s,s,sw,ne,sw,s,s,s,nw,s,s,s,s,s,sw,sw,s,n,s,s,se,s,s,s,s,s,s,s,sw,s,s,s,sw,s,s,s,s,s,s,nw,n,s,s,s,s,s,s,nw,s,sw,se,s,s,s,sw,s,sw,s,sw,s,se,se,s,s,nw,n,s,s,s,s,s,se,s,sw,se,s,se,s,nw,s,s,s,ne,nw,sw,s,sw,sw,nw,sw,s,n,sw,s,sw,s,s,s,s,se,s,s,nw,n,s,s,s,nw,se,sw,n,se,s,s,s,s,s,n,s,s,s,s,s,s,s,s,s,s,se,s,sw,nw,s,s,s,sw,ne,s,sw,s,s,s,s,s,se,s,s,s,ne,s,s,ne,s,s,s,s,s,s,s,ne,s,s,s,s,s,se,se,ne,sw,s,n,n,n,s,s,s,s,s,n,s,se,s,s,ne,n,s,s,s,ne,s,s,s,ne,se,nw,s,s,nw,s,s,s,s,s,s,s,s,s,se,s,s,sw,s,ne,s,s,sw,s,s,s,sw,s,s,s,s,s,s,s,s,s,s,s,s,s,sw,ne,s,s,s,nw,s,s,s,s,s,s,s,s,s,nw,s,n,s,s,s,s,s,s,s,s,nw,s,s,s,s,s,s,s,s,nw,s,s,s,s,s,se,s,ne,s,se,s,s,s,s,s,ne,s,s,s,s,s,nw,s,s,sw,se,se,s,s,s,s,s,s,s,s,se,nw,s,s,nw,s,s,s,s,s,s,s,s,s,s,s,s,s,se,s,s,ne,s,sw,s,n,s,s,s,s,s,sw,s,nw,s,s,nw,n,s,s,s,se,s,s,ne,n,s,s,s,ne,s,s,s,s,s,sw,ne,se,n,s,n,n,ne,ne,ne,s,se,sw,se,se,sw,ne,se,se,se,se,se,n,se,s,s,se,se,sw,n,s,s,s,se,se,s,s,s,s,s,sw,s,s,s,s,s,sw,s,s,sw,n,se,sw,n,sw,sw,sw,s,sw,sw,sw,se,nw,se,sw,sw,sw,nw,s,nw,sw,n,sw,nw,ne,s,se,nw,nw,sw,s,nw,sw,ne,se,nw,sw,nw,nw,nw,sw,nw,sw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,n,n,nw,n,n,nw,nw,ne,n,n,sw,nw,se,ne,n,nw,n,nw,n,nw,n,n,nw,s,ne,nw,sw,n,nw,nw,n,se,n,nw,n,nw,n,s,n,n,n,n,n,ne,n,n,n,ne,n,n,n,n,n,n,n,n,ne,n,ne,n,n,n,ne,nw,n,ne,n,ne,ne,n,n,n,s,n,n,ne,ne,n,n,ne,n,sw,n,ne,ne,s,ne,ne,sw,se,n,sw,ne,nw,sw,ne,ne,ne,sw,nw,s,ne,s,ne,s,ne,ne,ne,ne,ne,n,ne,ne,ne,ne,ne,ne,ne,ne,se,ne,ne,ne,ne,nw,se,s,ne,se,ne,nw,ne,ne,ne,n,ne,ne,ne,se,se,ne,ne,se,se,ne,sw,se,ne,se,ne,ne,se,se,se,se,se,nw,ne,ne,ne,s,se,ne,ne,s,sw,sw,ne,ne,ne,ne,se,nw,se,ne,n,ne,se,sw,ne,s,se,se,se,se,se,se,se,se,se,se,se,se,se,se,se,se,se,s,se,se,ne,se,ne,n,nw,n,se,se,n,s,se,n,se,se,se,se,se,se,se,se,se,se,se,sw,n,se,se,se,se,se,se,se,se,ne,ne,se,se,se,se,nw,se,ne,se,n,nw,s,n,se,se,se,se,se,se,se,ne,n,se,se,se,sw,sw,sw,se,s,se,s,se,se,se,s,se,se,s,se,se,s,ne,s,se,se,s,se,s,s,n,s,se,sw,se,s,s,sw,se,se,s,sw,ne,se,s,n,se,nw,se,nw,sw,s,n,s,s,s,s,s,s,se,sw,s,se,s,s,s,s,sw,s,s,s,nw,s,s,s,s,s,se,s,se,s,s,s,nw,s,s,se,nw,s,nw,s,nw,nw,n,se,s,s,s,s,s,s,s,s,sw,s,s,s,n,s,s,n,sw,sw,s,s,s,s,n,se,s,n,nw,ne,s,s,s,ne,s,s,s,s,ne,s,s,s,se,s,s,sw,ne,n,ne,nw,sw,s,s,sw,s,s,nw,s,s,s,s,s,s,s,s,s,sw,sw,nw,sw,s,s,s,n,s,s,sw,s,sw,s,s,s,ne,sw,sw,s,sw,s,nw,ne,s,nw,ne,s,s,s,s,s,s,n,s,sw,s,sw,sw,ne,s,s,s,ne,se,s,s,s,sw,sw,se,sw,se,sw,sw,nw,s,nw,s,sw,s,nw,sw,s,sw,sw,s,s,sw,s,sw,s,s,sw,s,s,s,sw,sw,sw,s,s,se,n,s,s,se,s,s,sw,sw,s,sw,s,sw,s,sw,sw,s,nw,s,s,nw,sw,sw,n,nw,n,nw,sw,sw,s,sw,sw,sw,sw,s,se,sw,s,sw,sw,sw,se,ne,sw,s,s,sw,sw,se,sw,ne,sw,sw,sw,sw,sw,sw,sw,ne,sw,sw,sw,sw,sw,sw,s,sw,sw,n,s,sw,sw,nw,sw,sw,sw,sw,ne,s,sw,sw,sw,nw,sw,sw,sw,sw,sw,sw,ne,nw,sw,nw,s,sw,sw,sw,se,s,sw,sw,sw,sw,nw,sw,sw,sw,sw,sw,sw,nw,sw,s,nw,sw,sw,nw,nw,nw,sw,sw,sw,sw,sw,se,sw,sw,sw,sw,n,nw,nw,sw,se,se,se,sw,sw,sw,ne,nw,nw,sw,nw,n,n,s,n,sw,sw,sw,sw,n,se,sw,ne,sw,nw,sw,sw,sw,nw,sw,sw,sw,nw,sw,sw,sw,nw,nw,n,sw,sw,sw,nw,se,nw,sw,nw,sw,sw,sw,sw,nw,s,nw,sw,s,sw,sw,nw,ne,nw,se,sw,se,nw,sw,nw,nw,sw,sw,sw,sw,sw,nw,nw,sw,s,nw,sw,nw,nw,nw,nw,nw,nw,se,sw,se,sw,nw,nw,se,sw,sw,nw,nw,sw,nw,nw,nw,sw,nw,sw,nw,sw,nw,se,sw,nw,sw,sw,sw,nw,sw,sw,sw,sw,sw,sw,nw,nw,nw,nw,nw,sw,sw,n,nw,nw,s,sw,sw,nw,se,nw,n,nw,nw,nw,nw,nw,nw,n,ne,nw,sw,s,nw,sw,nw,nw,s,nw,sw,sw,nw,nw,sw,sw,n,sw,nw,nw,nw,ne,nw,nw,nw,nw,nw,nw,ne,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,s,se,sw,nw,nw,nw,n,nw,n,nw,nw,nw,sw,nw,ne,sw,nw,nw,nw,sw,nw,sw,nw,sw,n,nw,sw,nw,nw,nw,n,se,nw,ne,nw,sw,nw,nw,nw,nw,nw,nw,nw,nw,nw,se,nw,nw,nw,ne,sw,nw,nw,nw,nw,nw,nw,ne,nw,sw,s,nw,nw,nw,nw,nw,n,ne,sw,nw,nw,nw,se,nw,nw,nw,nw,nw,sw,nw,nw,n,nw,sw,nw,s,ne,nw,ne,nw,nw,nw,nw,n,nw,nw,n,nw,nw,nw,sw,nw,nw,nw,ne,nw,nw,nw,se,sw,nw,n,nw,nw,n,se,n,nw,n,s,nw,nw,sw,nw,sw,nw,ne,n,nw,n,ne,sw,ne,nw,nw,nw,nw,n,n,nw,nw,nw,nw,sw,s,nw,nw,n,nw,nw,nw,n,ne,nw,nw,nw,nw,n,se,n,nw,n,n,n,n,n,nw,ne,nw,s,nw,se,n,nw,nw,nw,nw,sw,nw,n,nw,nw,nw,nw,ne,se,nw,ne,nw,nw,se,se,nw,sw,nw,nw,nw,se,n,n,nw,n,nw,nw,n,n,n,nw,nw,nw,n,n,n,se,nw,sw,n,nw,nw,nw,nw,n,nw,nw,n,nw,nw,n,n,n,ne,sw,nw,n,nw,nw,n,nw,nw,se,nw,n,nw,n,s,nw,nw,nw,n,n,nw,n,n,nw,nw,sw,n,nw,s,n,n,n,nw,nw,n,nw,n,n,nw,nw,sw,n,n,se,nw,nw,n,nw,n,n,nw,s,nw,n,nw,n,se,n,n,n,ne,nw,nw,n,sw,n,n,n,n,n,nw,nw,n,n,s,ne,n,n,n,nw,nw,n,n,n,n,sw,n,s,ne,n,nw,n,n,n,n,sw,n,nw,n,nw,nw,ne,n,nw,n,n,n,n,n,n,nw,n,n,nw,nw,se,ne,n,nw,n,n,nw,n,n,nw,n,n,n,sw,nw,n,s,nw,n,n,n,n,n,n,se,n,s,n,n,n,n,nw,nw,n,n,s,n,n,n,nw,nw,n,nw,n,n,sw,n,n,n,nw,ne,n,n,n,n,nw,n,nw,n,nw,s,n,n,nw,n,n,nw,sw,n,n,ne,ne,n,n,ne,n,n,s,ne,n,n,n,n,n,n,n,n,sw,n,n,n,n,n,n,n,sw,n,n,n,n,n,n,n,n,n,sw,n,n,n,n,n,sw,n,n,n,n,n,ne,n,n,n,n,se,n,n,n,n,n,n,s,se,n,n,n,n,sw,nw,n,n,n,n,n,nw,n,n,n,n,n,n,se,n,n,n,n,n,n,nw,n,n,s,n,n,n,n,nw,n,n,n,n,n,n,sw,n,ne,n,n,sw,n,n,n,n,se,n,n,ne,n,n,n,n,n,s,se,n,n,n,n,se,ne,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,se,n,ne,n,n,n,n,n,n,ne,n,ne,n,n,ne,ne,ne,nw,s,s,n,sw,n,se,n,se,n,ne,n,n,n,n,ne,n,n,n,n,n,ne,n,ne,n,ne,n,sw,ne,ne,s,n,n,n,n,n,n,n,n,n,s,n,ne,n,n,s,sw,ne,nw,n,n,n,ne,n,ne,ne,s,se,n,n,n,n,ne,n,se,n,n,n,n,n,ne,ne,n,ne,ne,n,ne,n,n,ne,n,n,ne,n,nw,n,ne,n,s,n,n,ne,se,sw,n,n,se,ne,n,ne,ne,ne,n,n,n,n,n,n,n,n,sw,nw,n,n,n,n,n,ne,ne,s,se,n,sw,ne,n,se,ne,nw,ne,ne,ne,n,n,n,ne,ne,sw,n,n,n,sw,n,n,ne,n,n,n,se,s,ne,s,ne,ne,ne,se,n,n,sw,n,n,ne,n,s,ne,nw,nw,ne,n,n,n,s,s,n,ne,sw,ne,ne,ne,ne,s,n,ne,ne,ne,ne,sw,ne,n,n,n,n,n,s,ne,ne,ne,ne,se,s,n,n,nw,n,n,n,n,s,s,n,ne,n,n,s,n,ne,ne,n,n,n,ne,n,ne,ne,ne,ne,ne,ne,ne,ne,sw,n,nw,s,ne,ne,n,n,n,ne,n,n,n,ne,sw,nw,se,n,ne,ne,ne,se,n,ne,ne,sw,n,ne,n,n,n,n,ne,sw,ne,ne,n,ne,ne,n,se,ne,ne,se,ne,ne,nw,sw,ne,ne,n,n,ne,sw,ne,n,ne,ne,n,ne,ne,n,ne,ne,ne,ne,ne,n,n,ne,ne,n,ne,ne,ne,ne,se,s,se,ne,n,ne,n,ne,ne,sw,ne,n,ne,ne,n,ne,ne,nw,ne,ne,n,nw,ne,se,ne,ne,ne,ne,ne,sw,nw,ne,ne,ne,ne,ne,ne,ne,n,ne,n,ne,sw,ne,sw,ne,n,ne,se,ne,ne,ne,ne,sw,ne,ne,ne,se,ne,ne,ne,ne,ne,sw,ne,ne,ne,ne,s,ne,ne,n,n,ne,ne,se,ne,ne,s,ne,ne,n,ne,ne,n,ne,se,ne,ne,n,sw,ne,ne,ne,n,ne,sw,ne,ne,nw,ne,ne,ne,n,ne,ne,ne,ne,s,se,ne,ne,ne,se,ne,n,ne,ne,ne,ne,s,ne,ne,ne,ne,ne,nw,ne,ne,ne,ne,ne,nw,ne,ne,nw,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,nw,sw,ne,ne,ne,ne,ne,n,ne,ne,ne,ne,ne,se,ne,sw,ne,sw,ne,ne,ne,ne,ne,ne,ne,ne,s,sw,nw,ne,ne,nw,nw,ne,ne,se,ne,ne,ne,ne,s,ne,ne,ne,ne,ne,ne,ne,ne,se,se,ne,ne,ne,sw,ne,ne,se,ne,ne,ne,se,ne,ne,ne,ne,ne,ne,ne,ne,ne,se,ne,ne,ne,se,s,nw,ne,ne,ne,ne,n,se,ne,sw,s,ne,ne,ne,ne,s,n,ne,ne,ne,se,s,nw,ne,ne,se,ne,ne,ne,ne,nw,ne,ne,ne,ne,ne,n,se,ne,s,ne,ne,ne,ne,se,ne,n,n,ne,ne,ne,ne,ne,ne,sw,ne,ne,ne,ne,ne,ne,s,ne,ne,ne,sw,s,sw,sw,ne,s,ne,ne,se,s,se,ne,ne,ne,ne,ne,nw,ne,ne,ne,ne,ne,ne,se,ne,ne,ne,ne,se,ne,n,se,se,ne,s,ne,ne,ne,s,ne,ne,se,ne,ne,ne,se,ne,ne,ne,ne,se,ne,ne,se,n,se,se,ne,ne,nw,ne,s,ne,se,ne,ne,ne,se,s,se,ne,se,se,ne,se,ne,ne,se,se,ne,ne,se,sw,ne,nw,ne,se,se,ne,se,ne,se,ne,nw,ne,s,ne,sw,ne,se,ne,ne,ne,ne,ne,sw,sw,ne,se,sw,ne,se,ne,se,ne,se,ne,ne,se,sw,se,ne,ne,ne,se,s,ne,ne,ne,ne,ne,ne,ne,n,se,ne,ne,se,ne,sw,se,se,ne,sw,n,se,se,se,se,sw,ne,ne,se,ne,ne,ne,ne,nw,ne,ne,ne,ne,se,se,se,ne,se,se,ne,ne,ne,se,ne,ne,se,ne,ne,ne,nw,ne,ne,ne,ne,se,se,ne,ne,se,ne,ne,se,ne,s,n,se,ne,ne,se,ne,ne,ne,ne,se,se,se,ne,nw,ne,ne,ne,se,se,se,ne,se,ne,se,ne,ne,n,ne,ne,ne,ne,ne,se,se,se,sw,se,ne,se,ne,n,ne,ne,ne,se,ne,se,sw,n,ne,n,ne,se,se,nw,ne,n,nw,ne,ne,ne,ne,ne,ne,ne,ne,se,se,se,ne,ne,s,se,nw,se,ne,ne,s,se,se,ne,sw,ne,se,se,s,se,ne,se,sw,n,ne,ne,se,nw,ne,ne,ne,n,ne,ne,se,ne,ne,ne,se,se,se,ne,se,ne,nw,ne,s,ne,se,ne,ne,se,se,ne,se,ne,se,sw,ne,sw,ne,se,ne,ne,ne,se,se,ne,ne,ne,se,ne,n,se,s,se,ne,ne,n,se,se,se,ne,se,se,se,se,ne,ne,se,se,se,se,ne,se,se,se,ne,n,se,se,se,nw,s,ne,nw,ne,ne,ne,se,se,se,se,se,ne,se,se,n,se,ne,n,ne,sw,ne,ne,se,se,se,se,n,se,n,ne,ne,se,se,se,ne,se,se,ne,se,se,se,nw,se,s,s,se,nw,s,ne,se,nw,ne,ne,se,se,s,se,se,se,ne,ne,se,ne,ne,ne,se,se,se,nw,se,ne,se,ne,nw,se,ne,nw,ne,se,ne,se,se,se,ne,ne,se,se,ne,se,se,se,se,se,se,ne,ne,ne,ne,se,se,se,se,nw,sw,se,ne,se,se,se,se,s,ne,se,nw,ne,se,nw,ne,se,se,se,se,ne,nw,n,se,ne,se,se,nw,n,sw,se,ne,ne,se,nw,n,se,se,se,s,s,ne,se,se,se,se,se,n,ne,se,se,se,se,se,sw,ne,se,se,se,se,se,s,ne,se,se,se,nw,se,se,n,se,se,ne,se,se,se,ne,se,se,nw,se,se,nw,ne,se,se,se,ne,se,se,n,se,se,n,se,se,s,se,se,se,se,ne,se,se,se,se,sw,sw,se,nw,se,se,se,se,se,se,se,se,se,nw,n,se,se,se,s,se,se,se,se,se,se,se,se,s,se,ne,se,se,se,se,se,nw,se,s,se,se,n,se,se,se,s,se,se,s,ne,se,se,se,ne,se,se,nw,se,se,se,nw,se,se,nw,n,nw,se,se,se,se,ne,se,se,se,se,se,se,se,n,se,se,se,se,se,se,nw,se,se,se,se,se,nw,se,nw"; - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let worker_input = - input - .split(',') - .enumerate() - .filter(|&(pos,_)| pos % peers == index) - .map(|(pos, step)| - (pos, match step { - "n" => ( 2, 0), - "s" => (-2, 0), - "ne" => ( 1, 1), - "se" => (-1, 1), - "nw" => ( 1,-1), - "sw" => (-1,-1), - _ => panic!("unreachable"), - })) - .collect::>(); - - worker.dataflow::<(),_,_>(|scope| { - - let data = scope.new_collection_from(worker_input).1; - - // part 1: accumulate all the steps, then determine the distance. - data.explode(|(_pos, (step_y, step_x))| Some(((), DiffPair::new(step_y, step_x)))) - .consolidate() - .inspect(|x| println!("part1: {:?}", hex_distance((x.2).element1, (x.2).element2))); - - // part 2: use prefix sum to determine the distance at each step, then maximize. - data.map(|(pos, x_y)| ((pos,()), x_y)) - .prefix_sum((0, 0), |_,a,b| (a.0+b.0, a.1+b.1)) - .map(|(_pos, (x,y))| ((), hex_distance(x,y))) - .group(|&(), input, output| output.push((*input[input.len()-1].0, 1))) - .inspect(|x| println!("part2: {:?}", (x.0).1)); - }); - - }).unwrap(); -} - - -// each step e/w is mandatory, but comes with a free half-step n/s. -fn hex_distance(mut n: isize, mut e: isize) -> isize { - if n < 0 { n = -n; } - if e < 0 { e = -e; } - e + ::std::cmp::max(0, n - e) -} diff --git a/advent_of_code_2017/src/bin/day_12.rs b/advent_of_code_2017/src/bin/day_12.rs deleted file mode 100644 index 238b7bd51b..0000000000 --- a/advent_of_code_2017/src/bin/day_12.rs +++ /dev/null @@ -1,2061 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/11 - -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = "0 <-> 46, 1376 -1 <-> 1465, 1889 -2 <-> 609, 1578 -3 <-> 3, 1003, 1133, 1887 -4 <-> 467, 1282 -5 <-> 5, 460, 1059, 1812 -6 <-> 235, 1318, 1556 -7 <-> 885, 1143, 1400 -8 <-> 8, 1102 -9 <-> 1349 -10 <-> 1711 -11 <-> 1717 -12 <-> 663, 1968 -13 <-> 1374 -14 <-> 55, 732, 926 -15 <-> 255, 1133 -16 <-> 645 -17 <-> 180, 1507 -18 <-> 401 -19 <-> 531 -20 <-> 20 -21 <-> 467 -22 <-> 1376, 1825 -23 <-> 1163 -24 <-> 93, 365, 383 -25 <-> 46 -26 <-> 1280 -27 <-> 27 -28 <-> 1001 -29 <-> 1506, 1659 -30 <-> 680, 1569 -31 <-> 121, 172, 684 -32 <-> 1331 -33 <-> 527, 668, 1471 -34 <-> 473 -35 <-> 790, 1789 -36 <-> 797 -37 <-> 1832 -38 <-> 1151, 1703 -39 <-> 382 -40 <-> 183, 333, 1032, 1405, 1587, 1649 -41 <-> 589, 965 -42 <-> 515, 1466 -43 <-> 599 -44 <-> 220, 1533 -45 <-> 656 -46 <-> 0, 25, 918, 1267 -47 <-> 262, 1084, 1590 -48 <-> 856 -49 <-> 49 -50 <-> 1604, 1650 -51 <-> 233 -52 <-> 1975 -53 <-> 141, 296 -54 <-> 54 -55 <-> 14, 1483 -56 <-> 738, 1632 -57 <-> 698, 1089 -58 <-> 133, 144, 1577 -59 <-> 917 -60 <-> 60, 694, 846 -61 <-> 1386 -62 <-> 264 -63 <-> 1875 -64 <-> 1028 -65 <-> 83, 86, 1767, 1876 -66 <-> 120 -67 <-> 363 -68 <-> 565 -69 <-> 69 -70 <-> 1414, 1542 -71 <-> 782, 1149, 1918, 1944, 1951, 1974 -72 <-> 72 -73 <-> 73 -74 <-> 77 -75 <-> 81 -76 <-> 519, 1266 -77 <-> 74, 77 -78 <-> 833, 1408, 1690 -79 <-> 492 -80 <-> 614, 1505 -81 <-> 75, 81, 105, 595, 1035 -82 <-> 440 -83 <-> 65 -84 <-> 106, 1907 -85 <-> 508, 1397, 1811 -86 <-> 65, 86, 112 -87 <-> 682, 1872 -88 <-> 1201 -89 <-> 1297 -90 <-> 592, 1873 -91 <-> 1288, 1447 -92 <-> 788, 1269, 1987 -93 <-> 24, 97, 608 -94 <-> 1138 -95 <-> 1668 -96 <-> 1608 -97 <-> 93, 1446 -98 <-> 580 -99 <-> 220 -100 <-> 1165, 1623 -101 <-> 1588 -102 <-> 1706, 1820 -103 <-> 1187 -104 <-> 561 -105 <-> 81, 1419 -106 <-> 84, 1055 -107 <-> 140, 222 -108 <-> 438, 1194 -109 <-> 109, 1739 -110 <-> 1217, 1968 -111 <-> 650, 1213 -112 <-> 86 -113 <-> 250, 1380 -114 <-> 248, 1172, 1254 -115 <-> 115 -116 <-> 713 -117 <-> 319, 389 -118 <-> 1892, 1914 -119 <-> 227 -120 <-> 66, 314, 350, 580 -121 <-> 31, 1369, 1375 -122 <-> 952, 1657 -123 <-> 143, 1153 -124 <-> 1124, 1173 -125 <-> 125 -126 <-> 1178 -127 <-> 1406, 1966 -128 <-> 620, 1493 -129 <-> 541, 1095 -130 <-> 1813 -131 <-> 616 -132 <-> 132, 1142 -133 <-> 58, 163, 375 -134 <-> 1288, 1503 -135 <-> 534, 763 -136 <-> 552 -137 <-> 137, 762, 900 -138 <-> 1791 -139 <-> 502, 1768 -140 <-> 107, 1150, 1346 -141 <-> 53, 1415 -142 <-> 1361 -143 <-> 123, 729, 966, 1087, 1091 -144 <-> 58, 1007, 1379 -145 <-> 1183 -146 <-> 543, 1569 -147 <-> 600 -148 <-> 735 -149 <-> 828, 1558 -150 <-> 442, 1096 -151 <-> 228, 748 -152 <-> 1076, 1951 -153 <-> 1577 -154 <-> 1829 -155 <-> 376, 469, 789, 940, 1294 -156 <-> 365, 1287 -157 <-> 157 -158 <-> 1372 -159 <-> 504 -160 <-> 1542 -161 <-> 190 -162 <-> 978 -163 <-> 133, 671, 1173 -164 <-> 776 -165 <-> 437 -166 <-> 231, 573, 1924 -167 <-> 1661 -168 <-> 1189 -169 <-> 169, 907 -170 <-> 230, 553 -171 <-> 909 -172 <-> 31, 234, 883 -173 <-> 1062 -174 <-> 174, 1688 -175 <-> 597, 751, 1515, 1599 -176 <-> 1302, 1435 -177 <-> 177 -178 <-> 427, 1148 -179 <-> 1196, 1390 -180 <-> 17, 847 -181 <-> 528, 1956 -182 <-> 482 -183 <-> 40 -184 <-> 184 -185 <-> 307, 1339, 1555 -186 <-> 703, 1198 -187 <-> 1656 -188 <-> 1342 -189 <-> 1742 -190 <-> 161, 237, 416, 590 -191 <-> 907 -192 <-> 482, 798, 1709 -193 <-> 805, 1320 -194 <-> 308, 989 -195 <-> 316, 518, 728 -196 <-> 848, 1239, 1335 -197 <-> 681, 683, 1965, 1977 -198 <-> 1028 -199 <-> 1126, 1808, 1953 -200 <-> 655, 921 -201 <-> 733 -202 <-> 1002, 1137, 1422 -203 <-> 529, 1127 -204 <-> 697, 1656 -205 <-> 1249 -206 <-> 608 -207 <-> 669 -208 <-> 241 -209 <-> 1190 -210 <-> 503 -211 <-> 1017 -212 <-> 567, 932, 1673 -213 <-> 432 -214 <-> 1097, 1180 -215 <-> 715 -216 <-> 426, 610, 1517 -217 <-> 1638 -218 <-> 1453 -219 <-> 219, 1033 -220 <-> 44, 99, 1874 -221 <-> 221, 1466 -222 <-> 107, 1014 -223 <-> 495 -224 <-> 503, 992 -225 <-> 800 -226 <-> 697, 1294 -227 <-> 119, 733, 1186 -228 <-> 151, 948, 984, 1359 -229 <-> 1039 -230 <-> 170, 1825, 1954 -231 <-> 166, 894 -232 <-> 580 -233 <-> 51, 835, 1247 -234 <-> 172, 588, 739 -235 <-> 6, 812 -236 <-> 1150 -237 <-> 190, 1065, 1157 -238 <-> 1930 -239 <-> 345, 584, 1731 -240 <-> 1514 -241 <-> 208, 556, 784, 1992 -242 <-> 242 -243 <-> 1666, 1760 -244 <-> 437, 1394 -245 <-> 306, 1175 -246 <-> 1032 -247 <-> 522, 709, 1565, 1611 -248 <-> 114, 248, 862, 1863 -249 <-> 887, 1066 -250 <-> 113 -251 <-> 251 -252 <-> 427, 1583 -253 <-> 328 -254 <-> 618, 680, 1370, 1442 -255 <-> 15, 1516, 1637 -256 <-> 470, 1532, 1678, 1809 -257 <-> 448, 1263, 1434, 1587 -258 <-> 519 -259 <-> 296, 1877 -260 <-> 311 -261 <-> 1841 -262 <-> 47, 1111 -263 <-> 969 -264 <-> 62, 264, 1347 -265 <-> 1657 -266 <-> 1360 -267 <-> 494 -268 <-> 1498 -269 <-> 956, 1258 -270 <-> 270, 532 -271 <-> 400, 813, 1500 -272 <-> 1777 -273 <-> 1768 -274 <-> 835, 1432 -275 <-> 750 -276 <-> 298, 1749 -277 <-> 1256, 1285 -278 <-> 1720 -279 <-> 903 -280 <-> 941 -281 <-> 315, 1356 -282 <-> 1293 -283 <-> 667, 802 -284 <-> 663, 1223 -285 <-> 1732 -286 <-> 493 -287 <-> 584, 1823 -288 <-> 365, 906 -289 <-> 618, 1777 -290 <-> 479, 988 -291 <-> 794 -292 <-> 304, 769, 944, 1448, 1735 -293 <-> 516, 1295 -294 <-> 406 -295 <-> 1279 -296 <-> 53, 259, 585, 1128 -297 <-> 1047, 1899 -298 <-> 276, 543 -299 <-> 1268, 1528 -300 <-> 993, 1384 -301 <-> 1323, 1984 -302 <-> 919, 923, 1611, 1962 -303 <-> 1172 -304 <-> 292 -305 <-> 1857 -306 <-> 245, 1044, 1699 -307 <-> 185, 1138 -308 <-> 194 -309 <-> 1054 -310 <-> 310, 1428, 1438 -311 <-> 260, 1291 -312 <-> 1316 -313 <-> 441 -314 <-> 120, 1865, 1967 -315 <-> 281, 673, 711 -316 <-> 195, 1083, 1969 -317 <-> 317, 508 -318 <-> 688 -319 <-> 117 -320 <-> 1174 -321 <-> 822, 978, 1042, 1373, 1980 -322 <-> 368, 1932 -323 <-> 1192 -324 <-> 1239 -325 <-> 607, 704, 1871 -326 <-> 634, 1916 -327 <-> 940, 1605 -328 <-> 253, 328, 636 -329 <-> 722, 1528 -330 <-> 1448 -331 <-> 771, 820 -332 <-> 1580 -333 <-> 40, 1785 -334 <-> 1992 -335 <-> 1064, 1713 -336 <-> 560, 1746, 1979 -337 <-> 988 -338 <-> 974, 1689, 1694 -339 <-> 1468 -340 <-> 555 -341 <-> 426, 1068, 1976 -342 <-> 1662 -343 <-> 799, 860 -344 <-> 743, 1109, 1547 -345 <-> 239, 781, 1734, 1963 -346 <-> 445, 1218, 1736 -347 <-> 502, 1560 -348 <-> 739, 1700 -349 <-> 417 -350 <-> 120, 887 -351 <-> 533, 537 -352 <-> 1075 -353 <-> 506, 1098, 1248 -354 <-> 354, 666 -355 <-> 1320 -356 <-> 464, 487, 1954 -357 <-> 603, 1444, 1552 -358 <-> 1273, 1623 -359 <-> 1308, 1659 -360 <-> 1648 -361 <-> 361, 1822 -362 <-> 362, 692 -363 <-> 67, 606, 1127 -364 <-> 364 -365 <-> 24, 156, 288, 424, 1017 -366 <-> 1006, 1434 -367 <-> 372, 1413 -368 <-> 322 -369 <-> 1194 -370 <-> 1272 -371 <-> 1551 -372 <-> 367 -373 <-> 1077 -374 <-> 1869 -375 <-> 133 -376 <-> 155 -377 <-> 1373 -378 <-> 982, 1730 -379 <-> 556, 1999 -380 <-> 1208, 1405 -381 <-> 976, 1506, 1855 -382 <-> 39, 1639 -383 <-> 24, 894, 1215 -384 <-> 1124, 1350 -385 <-> 385, 417, 697, 845 -386 <-> 491, 712, 817, 1550 -387 <-> 1347 -388 <-> 404 -389 <-> 117, 1156, 1190 -390 <-> 1344 -391 <-> 679, 931, 989 -392 <-> 396, 690, 1694 -393 <-> 618, 1497, 1803 -394 <-> 398, 1462 -395 <-> 1230, 1417 -396 <-> 392, 1412 -397 <-> 818, 1176, 1951 -398 <-> 394, 1651, 1945 -399 <-> 1496 -400 <-> 271, 1372, 1779, 1893 -401 <-> 18, 1382 -402 <-> 1726, 1864 -403 <-> 1917 -404 <-> 388, 1071 -405 <-> 1026 -406 <-> 294, 1354 -407 <-> 1721, 1934 -408 <-> 1523, 1600 -409 <-> 923 -410 <-> 410 -411 <-> 856, 1190, 1568 -412 <-> 714, 1423 -413 <-> 736 -414 <-> 953, 1631 -415 <-> 1282 -416 <-> 190, 659 -417 <-> 349, 385 -418 <-> 556, 912 -419 <-> 1304 -420 <-> 656 -421 <-> 1230 -422 <-> 422, 542 -423 <-> 779, 1260 -424 <-> 365, 1595 -425 <-> 958, 1134, 1495 -426 <-> 216, 341, 887 -427 <-> 178, 252, 1609 -428 <-> 428, 1257 -429 <-> 1020 -430 <-> 602 -431 <-> 539 -432 <-> 213, 938, 1633 -433 <-> 629, 1705 -434 <-> 640 -435 <-> 447, 1694 -436 <-> 1487 -437 <-> 165, 244, 1661 -438 <-> 108, 565, 966 -439 <-> 663 -440 <-> 82, 492 -441 <-> 313, 441 -442 <-> 150, 442, 1970 -443 <-> 868, 1665 -444 <-> 662, 823 -445 <-> 346, 1043, 1660 -446 <-> 691, 708 -447 <-> 435, 1182 -448 <-> 257, 1608 -449 <-> 1771, 1959 -450 <-> 893, 1299 -451 <-> 1578 -452 <-> 1607, 1725 -453 <-> 533, 651, 1271 -454 <-> 1366 -455 <-> 1677 -456 <-> 870, 1935 -457 <-> 750 -458 <-> 465, 1859 -459 <-> 728 -460 <-> 5 -461 <-> 1070, 1937 -462 <-> 1201, 1277 -463 <-> 568 -464 <-> 356, 1412 -465 <-> 458, 1368, 1613, 1980 -466 <-> 1385, 1993 -467 <-> 4, 21, 1345 -468 <-> 468, 707, 1721 -469 <-> 155, 676, 1008 -470 <-> 256, 667 -471 <-> 1552 -472 <-> 503, 1468 -473 <-> 34, 473, 1638 -474 <-> 531 -475 <-> 1163, 1379 -476 <-> 797 -477 <-> 995 -478 <-> 1258, 1441 -479 <-> 290, 1257 -480 <-> 1903 -481 <-> 703, 1339 -482 <-> 182, 192 -483 <-> 500, 759, 1077 -484 <-> 833 -485 <-> 672, 828 -486 <-> 661, 1784 -487 <-> 356 -488 <-> 688, 930 -489 <-> 489, 579 -490 <-> 490 -491 <-> 386, 1580, 1715 -492 <-> 79, 440, 767, 1872 -493 <-> 286, 1538 -494 <-> 267, 1674, 1902 -495 <-> 223, 1655 -496 <-> 572 -497 <-> 532, 1038, 1401 -498 <-> 498, 1241 -499 <-> 614 -500 <-> 483, 654, 1862, 1952 -501 <-> 933, 1957 -502 <-> 139, 347, 1629 -503 <-> 210, 224, 472, 720, 1948 -504 <-> 159, 1113 -505 <-> 832, 913, 1707 -506 <-> 353, 559, 1320 -507 <-> 1870 -508 <-> 85, 317, 722 -509 <-> 1301, 1348, 1873 -510 <-> 640, 1882 -511 <-> 511 -512 <-> 1300 -513 <-> 1679, 1731 -514 <-> 896, 1009 -515 <-> 42, 1056 -516 <-> 293 -517 <-> 517, 1112, 1704 -518 <-> 195 -519 <-> 76, 258, 1247, 1782 -520 <-> 661, 731, 1949 -521 <-> 1179, 1762 -522 <-> 247 -523 <-> 668, 916, 1197 -524 <-> 714, 1228, 1304 -525 <-> 1479 -526 <-> 1895 -527 <-> 33 -528 <-> 181, 528 -529 <-> 203, 763, 1184, 1227, 1615 -530 <-> 1169 -531 <-> 19, 474, 1297, 1411, 1883 -532 <-> 270, 497, 1630, 1821, 1868 -533 <-> 351, 453 -534 <-> 135, 1272 -535 <-> 997, 1049 -536 <-> 718, 1242 -537 <-> 351, 1762 -538 <-> 1165 -539 <-> 431, 953, 1273 -540 <-> 1062, 1362, 1554 -541 <-> 129 -542 <-> 422, 1713 -543 <-> 146, 298 -544 <-> 544 -545 <-> 942, 1030, 1904 -546 <-> 1553, 1598 -547 <-> 974 -548 <-> 845, 1479 -549 <-> 1333 -550 <-> 598 -551 <-> 740, 1861 -552 <-> 136, 1347, 1523 -553 <-> 170, 915, 1603 -554 <-> 1421 -555 <-> 340, 760, 1836 -556 <-> 241, 379, 418, 590 -557 <-> 648 -558 <-> 904, 1670 -559 <-> 506, 1576, 1920 -560 <-> 336, 1057, 1652 -561 <-> 104, 1329, 1590 -562 <-> 1297, 1322, 1702 -563 <-> 1319 -564 <-> 1331 -565 <-> 68, 438, 1990 -566 <-> 1031, 1240 -567 <-> 212, 1146, 1436 -568 <-> 463, 1093 -569 <-> 1311, 1520 -570 <-> 1065, 1893 -571 <-> 1421 -572 <-> 496, 587, 1082, 1537 -573 <-> 166, 1556 -574 <-> 1240 -575 <-> 575 -576 <-> 1157 -577 <-> 1592 -578 <-> 826 -579 <-> 489, 986, 1458 -580 <-> 98, 120, 232 -581 <-> 1296, 1597 -582 <-> 1439 -583 <-> 1125, 1536 -584 <-> 239, 287, 1152, 1743, 1834 -585 <-> 296, 1189 -586 <-> 952 -587 <-> 572, 780, 1829 -588 <-> 234, 1071, 1470 -589 <-> 41, 1752 -590 <-> 190, 556 -591 <-> 1023 -592 <-> 90, 1225, 1408 -593 <-> 852, 1831 -594 <-> 1760 -595 <-> 81 -596 <-> 1566 -597 <-> 175 -598 <-> 550, 765, 946, 1543 -599 <-> 43, 1292, 1386, 1554 -600 <-> 147, 1592 -601 <-> 1025, 1586 -602 <-> 430, 1028, 1522, 1812 -603 <-> 357, 873 -604 <-> 940 -605 <-> 739, 1361 -606 <-> 363, 630, 1828 -607 <-> 325 -608 <-> 93, 206 -609 <-> 2 -610 <-> 216 -611 <-> 961, 1002 -612 <-> 1193 -613 <-> 892, 1090 -614 <-> 80, 499, 1436 -615 <-> 615, 1284 -616 <-> 131, 1680, 1765 -617 <-> 1017 -618 <-> 254, 289, 393, 1308 -619 <-> 1514 -620 <-> 128, 1698 -621 <-> 691 -622 <-> 1844 -623 <-> 811, 1323 -624 <-> 745, 1429 -625 <-> 959 -626 <-> 1830 -627 <-> 933 -628 <-> 860, 1261, 1378, 1890 -629 <-> 433, 1232 -630 <-> 606, 1764 -631 <-> 1836, 1986 -632 <-> 806, 1297 -633 <-> 717, 1539 -634 <-> 326, 1646 -635 <-> 1203, 1985 -636 <-> 328 -637 <-> 1894 -638 <-> 1984 -639 <-> 1669 -640 <-> 434, 510, 996, 1683 -641 <-> 844, 1166 -642 <-> 816, 1865, 1953 -643 <-> 1511 -644 <-> 863, 1652 -645 <-> 16, 1097, 1316, 1794 -646 <-> 786 -647 <-> 647 -648 <-> 557, 1236 -649 <-> 649 -650 <-> 111 -651 <-> 453, 888, 1207 -652 <-> 795, 936, 1747 -653 <-> 669 -654 <-> 500, 1620 -655 <-> 200, 1799 -656 <-> 45, 420, 893, 1682 -657 <-> 744 -658 <-> 1106, 1293, 1493 -659 <-> 416 -660 <-> 1700 -661 <-> 486, 520, 1067 -662 <-> 444 -663 <-> 12, 284, 439, 1627, 1922 -664 <-> 726, 920, 1174 -665 <-> 679 -666 <-> 354 -667 <-> 283, 470 -668 <-> 33, 523 -669 <-> 207, 653, 1740, 1806 -670 <-> 1565, 1684 -671 <-> 163 -672 <-> 485 -673 <-> 315 -674 <-> 1161, 1617, 1714 -675 <-> 1954 -676 <-> 469, 1160, 1325, 1389 -677 <-> 1664 -678 <-> 1827 -679 <-> 391, 665 -680 <-> 30, 254, 750 -681 <-> 197 -682 <-> 87, 1751 -683 <-> 197, 1724 -684 <-> 31, 866 -685 <-> 713 -686 <-> 1911 -687 <-> 1226 -688 <-> 318, 488, 688, 1705 -689 <-> 1127, 1343, 1769 -690 <-> 392 -691 <-> 446, 621, 1241 -692 <-> 362, 1073 -693 <-> 758, 1524, 1971 -694 <-> 60, 1095 -695 <-> 695 -696 <-> 696, 1341 -697 <-> 204, 226, 385, 824 -698 <-> 57, 698 -699 <-> 1219, 1429, 1566 -700 <-> 935, 1487 -701 <-> 826, 1197 -702 <-> 1710 -703 <-> 186, 481 -704 <-> 325, 704 -705 <-> 1607 -706 <-> 1353, 1818 -707 <-> 468 -708 <-> 446, 945 -709 <-> 247 -710 <-> 1750 -711 <-> 315 -712 <-> 386 -713 <-> 116, 685, 1250, 1662 -714 <-> 412, 524 -715 <-> 215, 833 -716 <-> 1195 -717 <-> 633, 737 -718 <-> 536, 1633 -719 <-> 1286, 1538 -720 <-> 503, 1492, 1917 -721 <-> 786, 1602 -722 <-> 329, 508, 1251 -723 <-> 1074, 1166 -724 <-> 1715 -725 <-> 1455 -726 <-> 664, 927, 1121 -727 <-> 1279 -728 <-> 195, 459 -729 <-> 143, 1929 -730 <-> 785, 1269, 1826 -731 <-> 520, 1907 -732 <-> 14, 860 -733 <-> 201, 227, 733 -734 <-> 734 -735 <-> 148, 1455, 1771 -736 <-> 413, 1377, 1455 -737 <-> 717, 1262, 1777 -738 <-> 56 -739 <-> 234, 348, 605 -740 <-> 551, 790 -741 <-> 1995 -742 <-> 1435, 1768, 1814 -743 <-> 344 -744 <-> 657, 1857 -745 <-> 624, 1283, 1745 -746 <-> 1220 -747 <-> 1253 -748 <-> 151 -749 <-> 1571 -750 <-> 275, 457, 680 -751 <-> 175, 1379, 1849 -752 <-> 1577 -753 <-> 842, 919 -754 <-> 754 -755 <-> 1609, 1941 -756 <-> 756, 1451 -757 <-> 1192, 1412 -758 <-> 693, 1667 -759 <-> 483 -760 <-> 555 -761 <-> 1389, 1641 -762 <-> 137, 1280 -763 <-> 135, 529, 1558 -764 <-> 1239 -765 <-> 598, 1420 -766 <-> 1726 -767 <-> 492 -768 <-> 1697 -769 <-> 292 -770 <-> 882 -771 <-> 331, 971, 1794 -772 <-> 772, 809, 1365 -773 <-> 1127 -774 <-> 956, 981 -775 <-> 1756 -776 <-> 164, 1843 -777 <-> 1224, 1252 -778 <-> 778 -779 <-> 423 -780 <-> 587, 1295 -781 <-> 345 -782 <-> 71 -783 <-> 1424, 1962 -784 <-> 241 -785 <-> 730, 1307, 1706 -786 <-> 646, 721 -787 <-> 1445 -788 <-> 92, 1336 -789 <-> 155, 1203 -790 <-> 35, 740 -791 <-> 1155 -792 <-> 1818 -793 <-> 1541 -794 <-> 291, 794, 840, 1460 -795 <-> 652, 1911 -796 <-> 796 -797 <-> 36, 476, 910, 1075 -798 <-> 192, 1898 -799 <-> 343, 905 -800 <-> 225, 1334, 1488 -801 <-> 1768 -802 <-> 283, 1104, 1870 -803 <-> 1484 -804 <-> 804 -805 <-> 193, 1331 -806 <-> 632 -807 <-> 830 -808 <-> 1059 -809 <-> 772, 1226 -810 <-> 810 -811 <-> 623 -812 <-> 235, 1145, 1416 -813 <-> 271, 1572 -814 <-> 1257, 1886 -815 <-> 1695 -816 <-> 642 -817 <-> 386 -818 <-> 397, 1692 -819 <-> 1551 -820 <-> 331, 1177 -821 <-> 1496 -822 <-> 321 -823 <-> 444, 1120, 1625 -824 <-> 697 -825 <-> 970 -826 <-> 578, 701 -827 <-> 1720 -828 <-> 149, 485 -829 <-> 1775 -830 <-> 807, 1592, 1740 -831 <-> 1578 -832 <-> 505, 899, 1664 -833 <-> 78, 484, 715, 916, 1054, 1403 -834 <-> 1435 -835 <-> 233, 274 -836 <-> 1355, 1364 -837 <-> 1032 -838 <-> 1675, 1680 -839 <-> 881, 1730 -840 <-> 794 -841 <-> 1250 -842 <-> 753 -843 <-> 1241, 1330, 1628 -844 <-> 641 -845 <-> 385, 548 -846 <-> 60 -847 <-> 180 -848 <-> 196, 848 -849 <-> 849 -850 <-> 850 -851 <-> 1392, 1439 -852 <-> 593, 1151, 1421 -853 <-> 1212, 1574 -854 <-> 1051, 1065 -855 <-> 866, 1390 -856 <-> 48, 411 -857 <-> 1018, 1526 -858 <-> 1273 -859 <-> 1541 -860 <-> 343, 628, 732, 1385 -861 <-> 1916 -862 <-> 248, 1924 -863 <-> 644, 1467 -864 <-> 911 -865 <-> 1115, 1667 -866 <-> 684, 855 -867 <-> 885, 1594 -868 <-> 443 -869 <-> 959, 1449 -870 <-> 456, 1601, 1916 -871 <-> 886 -872 <-> 872, 1695 -873 <-> 603 -874 <-> 1396 -875 <-> 1897 -876 <-> 1315 -877 <-> 1602 -878 <-> 1578, 1969 -879 <-> 1977 -880 <-> 1158 -881 <-> 839 -882 <-> 770, 1136, 1390, 1544 -883 <-> 172 -884 <-> 1789 -885 <-> 7, 867 -886 <-> 871, 886 -887 <-> 249, 350, 426 -888 <-> 651 -889 <-> 1768 -890 <-> 1066, 1998 -891 <-> 891 -892 <-> 613, 942 -893 <-> 450, 656 -894 <-> 231, 383, 1485 -895 <-> 1689 -896 <-> 514 -897 <-> 1395, 1873 -898 <-> 1957 -899 <-> 832 -900 <-> 137, 1238, 1634, 1640 -901 <-> 1563, 1633 -902 <-> 911, 1312 -903 <-> 279, 1066, 1337 -904 <-> 558 -905 <-> 799 -906 <-> 288 -907 <-> 169, 191 -908 <-> 908 -909 <-> 171, 983, 1309 -910 <-> 797, 1540 -911 <-> 864, 902, 1303 -912 <-> 418 -913 <-> 505, 940, 1835 -914 <-> 914 -915 <-> 553 -916 <-> 523, 833 -917 <-> 59, 1532 -918 <-> 46, 1176, 1864 -919 <-> 302, 753 -920 <-> 664 -921 <-> 200, 922, 1088, 1622 -922 <-> 921 -923 <-> 302, 409 -924 <-> 924 -925 <-> 925, 1103 -926 <-> 14, 1013 -927 <-> 726, 1725 -928 <-> 1722 -929 <-> 1088, 1932 -930 <-> 488, 1719 -931 <-> 391, 1750 -932 <-> 212, 1258 -933 <-> 501, 627 -934 <-> 1146, 1693 -935 <-> 700, 1713 -936 <-> 652, 1530 -937 <-> 1012 -938 <-> 432 -939 <-> 959 -940 <-> 155, 327, 604, 913, 1012 -941 <-> 280, 1087, 1288 -942 <-> 545, 892, 1222 -943 <-> 1828 -944 <-> 292 -945 <-> 708 -946 <-> 598 -947 <-> 1540, 1593 -948 <-> 228 -949 <-> 1104 -950 <-> 950 -951 <-> 1834 -952 <-> 122, 586, 952, 1356, 1771, 1909 -953 <-> 414, 539, 1876 -954 <-> 980, 1199, 1578, 1815 -955 <-> 955 -956 <-> 269, 774, 956, 1023 -957 <-> 1690 -958 <-> 425, 1041 -959 <-> 625, 869, 939 -960 <-> 960 -961 <-> 611 -962 <-> 1188, 1594 -963 <-> 1824 -964 <-> 1391, 1982 -965 <-> 41, 1332, 1656 -966 <-> 143, 438, 1131, 1607 -967 <-> 967 -968 <-> 1737 -969 <-> 263, 1243 -970 <-> 825, 1089, 1125, 1988 -971 <-> 771 -972 <-> 1657 -973 <-> 973 -974 <-> 338, 547 -975 <-> 975, 1213 -976 <-> 381, 1860 -977 <-> 1235, 1300 -978 <-> 162, 321, 1736 -979 <-> 979 -980 <-> 954, 1493, 1521 -981 <-> 774 -982 <-> 378, 1687 -983 <-> 909, 1581 -984 <-> 228 -985 <-> 1318 -986 <-> 579, 989 -987 <-> 1525, 1975 -988 <-> 290, 337, 1488 -989 <-> 194, 391, 986 -990 <-> 1047 -991 <-> 1276 -992 <-> 224, 1900 -993 <-> 300, 1677, 1921 -994 <-> 1914 -995 <-> 477, 1459, 1717 -996 <-> 640 -997 <-> 535, 1639 -998 <-> 1834 -999 <-> 1164, 1352, 1819 -1000 <-> 1000 -1001 <-> 28, 1001 -1002 <-> 202, 611 -1003 <-> 3 -1004 <-> 1714 -1005 <-> 1326, 1494, 1543 -1006 <-> 366 -1007 <-> 144, 1557 -1008 <-> 469, 1029 -1009 <-> 514, 1039 -1010 <-> 1860 -1011 <-> 1649, 1845 -1012 <-> 937, 940 -1013 <-> 926 -1014 <-> 222, 1223 -1015 <-> 1800 -1016 <-> 1527, 1561 -1017 <-> 211, 365, 617, 1452 -1018 <-> 857, 1018 -1019 <-> 1156, 1427, 1489 -1020 <-> 429, 1087 -1021 <-> 1197, 1773 -1022 <-> 1861 -1023 <-> 591, 956, 1846 -1024 <-> 1024 -1025 <-> 601, 1782 -1026 <-> 405, 1026, 1050 -1027 <-> 1335 -1028 <-> 64, 198, 602 -1029 <-> 1008 -1030 <-> 545 -1031 <-> 566 -1032 <-> 40, 246, 837 -1033 <-> 219, 1495 -1034 <-> 1079, 1190, 1301, 1444, 1579 -1035 <-> 81 -1036 <-> 1621 -1037 <-> 1605 -1038 <-> 497, 1514 -1039 <-> 229, 1009, 1382, 1965 -1040 <-> 1116, 1596 -1041 <-> 958 -1042 <-> 321, 1171 -1043 <-> 445 -1044 <-> 306 -1045 <-> 1432 -1046 <-> 1965 -1047 <-> 297, 990, 1047 -1048 <-> 1599 -1049 <-> 535 -1050 <-> 1026 -1051 <-> 854 -1052 <-> 1410 -1053 <-> 1819 -1054 <-> 309, 833 -1055 <-> 106, 1744 -1056 <-> 515, 1919 -1057 <-> 560, 1374, 1469, 1559 -1058 <-> 1519, 1786 -1059 <-> 5, 808 -1060 <-> 1275, 1380, 1838 -1061 <-> 1951 -1062 <-> 173, 540, 1167 -1063 <-> 1086 -1064 <-> 335 -1065 <-> 237, 570, 854 -1066 <-> 249, 890, 903, 1854 -1067 <-> 661 -1068 <-> 341 -1069 <-> 1202, 1370, 1844 -1070 <-> 461 -1071 <-> 404, 588, 1575 -1072 <-> 1797 -1073 <-> 692 -1074 <-> 723, 1074 -1075 <-> 352, 797 -1076 <-> 152 -1077 <-> 373, 483 -1078 <-> 1291 -1079 <-> 1034 -1080 <-> 1915 -1081 <-> 1081, 1510 -1082 <-> 572, 1981 -1083 <-> 316 -1084 <-> 47 -1085 <-> 1243 -1086 <-> 1063, 1086, 1551 -1087 <-> 143, 941, 1020, 1480 -1088 <-> 921, 929 -1089 <-> 57, 970 -1090 <-> 613 -1091 <-> 143 -1092 <-> 1092 -1093 <-> 568, 1573 -1094 <-> 1458 -1095 <-> 129, 694 -1096 <-> 150, 1164 -1097 <-> 214, 645, 1354, 1462, 1723 -1098 <-> 353 -1099 <-> 1272 -1100 <-> 1386 -1101 <-> 1332 -1102 <-> 8 -1103 <-> 925 -1104 <-> 802, 949 -1105 <-> 1105, 1304 -1106 <-> 658, 1212, 1674 -1107 <-> 1642, 1858 -1108 <-> 1135, 1509 -1109 <-> 344, 1184 -1110 <-> 1562 -1111 <-> 262, 1214, 1426, 1794 -1112 <-> 517 -1113 <-> 504, 1113, 1490, 1545 -1114 <-> 1670 -1115 <-> 865, 1115, 1636 -1116 <-> 1040 -1117 <-> 1486 -1118 <-> 1145 -1119 <-> 1393, 1406 -1120 <-> 823, 1120, 1518 -1121 <-> 726, 1121 -1122 <-> 1375 -1123 <-> 1123 -1124 <-> 124, 384, 1827, 1853 -1125 <-> 583, 970 -1126 <-> 199 -1127 <-> 203, 363, 689, 773, 1341, 1602 -1128 <-> 296, 1610 -1129 <-> 1562 -1130 <-> 1476 -1131 <-> 966 -1132 <-> 1389 -1133 <-> 3, 15 -1134 <-> 425 -1135 <-> 1108, 1970 -1136 <-> 882 -1137 <-> 202 -1138 <-> 94, 307, 1287 -1139 <-> 1139 -1140 <-> 1484, 1658 -1141 <-> 1361 -1142 <-> 132 -1143 <-> 7, 1143 -1144 <-> 1357 -1145 <-> 812, 1118 -1146 <-> 567, 934 -1147 <-> 1763 -1148 <-> 178, 1779 -1149 <-> 71 -1150 <-> 140, 236, 1699 -1151 <-> 38, 852, 1807 -1152 <-> 584, 1906 -1153 <-> 123 -1154 <-> 1435, 1703 -1155 <-> 791, 1303 -1156 <-> 389, 1019 -1157 <-> 237, 576, 1790 -1158 <-> 880, 1653 -1159 <-> 1836 -1160 <-> 676, 1376 -1161 <-> 674 -1162 <-> 1874 -1163 <-> 23, 475 -1164 <-> 999, 1096 -1165 <-> 100, 538 -1166 <-> 641, 723 -1167 <-> 1062 -1168 <-> 1168, 1927 -1169 <-> 530, 1748, 1775, 1995 -1170 <-> 1521 -1171 <-> 1042 -1172 <-> 114, 303, 1687 -1173 <-> 124, 163, 1298 -1174 <-> 320, 664 -1175 <-> 245 -1176 <-> 397, 918 -1177 <-> 820 -1178 <-> 126, 1265 -1179 <-> 521, 1926 -1180 <-> 214 -1181 <-> 1313 -1182 <-> 447, 1837 -1183 <-> 145, 1299, 1578, 1869 -1184 <-> 529, 1109, 1816 -1185 <-> 1494, 1972 -1186 <-> 227, 1220 -1187 <-> 103, 1688 -1188 <-> 962 -1189 <-> 168, 585 -1190 <-> 209, 389, 411, 1034, 1206 -1191 <-> 1191, 1477, 1639 -1192 <-> 323, 757, 1461 -1193 <-> 612, 1193 -1194 <-> 108, 369 -1195 <-> 716, 1392 -1196 <-> 179 -1197 <-> 523, 701, 1021 -1198 <-> 186 -1199 <-> 954 -1200 <-> 1562 -1201 <-> 88, 462, 1297 -1202 <-> 1069 -1203 <-> 635, 789 -1204 <-> 1204, 1563 -1205 <-> 1205, 1219 -1206 <-> 1190 -1207 <-> 651 -1208 <-> 380 -1209 <-> 1758 -1210 <-> 1469 -1211 <-> 1475, 1998 -1212 <-> 853, 1106, 1836 -1213 <-> 111, 975, 1216, 1932 -1214 <-> 1111, 1709 -1215 <-> 383 -1216 <-> 1213 -1217 <-> 110, 1394 -1218 <-> 346 -1219 <-> 699, 1205 -1220 <-> 746, 1186 -1221 <-> 1664 -1222 <-> 942, 1672, 1946 -1223 <-> 284, 1014 -1224 <-> 777, 1278, 1655 -1225 <-> 592 -1226 <-> 687, 809 -1227 <-> 529 -1228 <-> 524 -1229 <-> 1229 -1230 <-> 395, 421 -1231 <-> 1628 -1232 <-> 629 -1233 <-> 1732 -1234 <-> 1813 -1235 <-> 977, 1883 -1236 <-> 648, 1539, 1708 -1237 <-> 1977 -1238 <-> 900 -1239 <-> 196, 324, 764 -1240 <-> 566, 574, 1516, 1531 -1241 <-> 498, 691, 843 -1242 <-> 536, 1780 -1243 <-> 969, 1085, 1771, 1800 -1244 <-> 1637 -1245 <-> 1460 -1246 <-> 1483, 1911 -1247 <-> 233, 519 -1248 <-> 353, 1440 -1249 <-> 205, 1890 -1250 <-> 713, 841, 1702 -1251 <-> 722, 1882 -1252 <-> 777 -1253 <-> 747, 1659 -1254 <-> 114 -1255 <-> 1512, 1593 -1256 <-> 277 -1257 <-> 428, 479, 814 -1258 <-> 269, 478, 932 -1259 <-> 1901, 1920 -1260 <-> 423, 1752 -1261 <-> 628, 1328 -1262 <-> 737 -1263 <-> 257, 1943 -1264 <-> 1837 -1265 <-> 1178, 1958 -1266 <-> 76 -1267 <-> 46 -1268 <-> 299, 1409 -1269 <-> 92, 730 -1270 <-> 1687 -1271 <-> 453, 1457 -1272 <-> 370, 534, 1099 -1273 <-> 358, 539, 858 -1274 <-> 1503 -1275 <-> 1060, 1275 -1276 <-> 991, 1551 -1277 <-> 462 -1278 <-> 1224, 1906 -1279 <-> 295, 727, 1737 -1280 <-> 26, 762 -1281 <-> 1825 -1282 <-> 4, 415 -1283 <-> 745, 1813 -1284 <-> 615 -1285 <-> 277, 1285 -1286 <-> 719, 1302 -1287 <-> 156, 1138 -1288 <-> 91, 134, 941 -1289 <-> 1289 -1290 <-> 1418, 1750 -1291 <-> 311, 1078, 1291, 1582 -1292 <-> 599 -1293 <-> 282, 658, 1681, 1983 -1294 <-> 155, 226 -1295 <-> 293, 780, 1362 -1296 <-> 581, 1643 -1297 <-> 89, 531, 562, 632, 1201 -1298 <-> 1173 -1299 <-> 450, 1183, 1299, 1382, 1722 -1300 <-> 512, 977, 1903 -1301 <-> 509, 1034 -1302 <-> 176, 1286, 1561, 1843 -1303 <-> 911, 1155, 1850 -1304 <-> 419, 524, 1105 -1305 <-> 1472 -1306 <-> 1615 -1307 <-> 785, 1440 -1308 <-> 359, 618, 1850 -1309 <-> 909, 1984 -1310 <-> 1400 -1311 <-> 569, 1726 -1312 <-> 902, 1830 -1313 <-> 1181, 1673, 1945 -1314 <-> 1725 -1315 <-> 876, 1687 -1316 <-> 312, 645 -1317 <-> 1496, 1770 -1318 <-> 6, 985 -1319 <-> 563, 1999 -1320 <-> 193, 355, 506 -1321 <-> 1436 -1322 <-> 562 -1323 <-> 301, 623 -1324 <-> 1757 -1325 <-> 676, 1888 -1326 <-> 1005, 1348 -1327 <-> 1731 -1328 <-> 1261, 1464, 1718 -1329 <-> 561 -1330 <-> 843 -1331 <-> 32, 564, 805 -1332 <-> 965, 1101 -1333 <-> 549, 1666 -1334 <-> 800 -1335 <-> 196, 1027, 1534 -1336 <-> 788 -1337 <-> 903 -1338 <-> 1439 -1339 <-> 185, 481 -1340 <-> 1340 -1341 <-> 696, 1127 -1342 <-> 188, 1636 -1343 <-> 689 -1344 <-> 390, 1368 -1345 <-> 467, 1345 -1346 <-> 140 -1347 <-> 264, 387, 552, 1691 -1348 <-> 509, 1326 -1349 <-> 9, 1829 -1350 <-> 384 -1351 <-> 1408 -1352 <-> 999 -1353 <-> 706, 1910 -1354 <-> 406, 1097 -1355 <-> 836 -1356 <-> 281, 952 -1357 <-> 1144, 1666, 1701 -1358 <-> 1358, 1422 -1359 <-> 228, 1359 -1360 <-> 266, 1360 -1361 <-> 142, 605, 1141, 1364 -1362 <-> 540, 1295, 1604 -1363 <-> 1686, 1996 -1364 <-> 836, 1361, 1554 -1365 <-> 772, 1472 -1366 <-> 454, 1366 -1367 <-> 1367 -1368 <-> 465, 1344 -1369 <-> 121 -1370 <-> 254, 1069 -1371 <-> 1371 -1372 <-> 158, 400 -1373 <-> 321, 377 -1374 <-> 13, 1057, 1546 -1375 <-> 121, 1122 -1376 <-> 0, 22, 1160 -1377 <-> 736 -1378 <-> 628 -1379 <-> 144, 475, 751 -1380 <-> 113, 1060 -1381 <-> 1649 -1382 <-> 401, 1039, 1299 -1383 <-> 1383 -1384 <-> 300, 1384 -1385 <-> 466, 860, 1818 -1386 <-> 61, 599, 1100, 1386 -1387 <-> 1387 -1388 <-> 1685 -1389 <-> 676, 761, 1132 -1390 <-> 179, 855, 882 -1391 <-> 964 -1392 <-> 851, 1195, 1553 -1393 <-> 1119 -1394 <-> 244, 1217, 1973 -1395 <-> 897 -1396 <-> 874, 1922 -1397 <-> 85 -1398 <-> 1730, 1905 -1399 <-> 1735, 1879, 1885 -1400 <-> 7, 1310, 1570 -1401 <-> 497 -1402 <-> 1402 -1403 <-> 833, 1931 -1404 <-> 1943 -1405 <-> 40, 380, 1407, 1456 -1406 <-> 127, 1119, 1502 -1407 <-> 1405 -1408 <-> 78, 592, 1351 -1409 <-> 1268, 1662 -1410 <-> 1052, 1618 -1411 <-> 531 -1412 <-> 396, 464, 757 -1413 <-> 367, 1481 -1414 <-> 70 -1415 <-> 141 -1416 <-> 812 -1417 <-> 395, 1417 -1418 <-> 1290, 1430, 1852 -1419 <-> 105, 1762 -1420 <-> 765 -1421 <-> 554, 571, 852 -1422 <-> 202, 1358, 1729 -1423 <-> 412, 1665 -1424 <-> 783, 1927 -1425 <-> 1584 -1426 <-> 1111 -1427 <-> 1019 -1428 <-> 310 -1429 <-> 624, 699, 1459 -1430 <-> 1418, 1588 -1431 <-> 1518 -1432 <-> 274, 1045, 1839 -1433 <-> 1717 -1434 <-> 257, 366 -1435 <-> 176, 742, 834, 1154, 1507 -1436 <-> 567, 614, 1321 -1437 <-> 1572, 1732 -1438 <-> 310 -1439 <-> 582, 851, 1338, 1751, 1763 -1440 <-> 1248, 1307 -1441 <-> 478 -1442 <-> 254 -1443 <-> 1566 -1444 <-> 357, 1034, 1844 -1445 <-> 787, 1481, 1821 -1446 <-> 97 -1447 <-> 91 -1448 <-> 292, 330 -1449 <-> 869, 1748 -1450 <-> 1581, 1648 -1451 <-> 756, 1742 -1452 <-> 1017 -1453 <-> 218, 1499 -1454 <-> 1454 -1455 <-> 725, 735, 736, 1668 -1456 <-> 1405 -1457 <-> 1271 -1458 <-> 579, 1094 -1459 <-> 995, 1429, 1848 -1460 <-> 794, 1245 -1461 <-> 1192 -1462 <-> 394, 1097 -1463 <-> 1693 -1464 <-> 1328 -1465 <-> 1, 1901 -1466 <-> 42, 221, 1513 -1467 <-> 863 -1468 <-> 339, 472 -1469 <-> 1057, 1210 -1470 <-> 588 -1471 <-> 33 -1472 <-> 1305, 1365, 1872 -1473 <-> 1473 -1474 <-> 1540, 1700 -1475 <-> 1211 -1476 <-> 1130, 1718 -1477 <-> 1191 -1478 <-> 1478 -1479 <-> 525, 548 -1480 <-> 1087 -1481 <-> 1413, 1445, 1740 -1482 <-> 1522 -1483 <-> 55, 1246 -1484 <-> 803, 1140 -1485 <-> 894 -1486 <-> 1117, 1486 -1487 <-> 436, 700 -1488 <-> 800, 988 -1489 <-> 1019, 1685 -1490 <-> 1113 -1491 <-> 1546 -1492 <-> 720, 1834 -1493 <-> 128, 658, 980 -1494 <-> 1005, 1185, 1535 -1495 <-> 425, 1033, 1727 -1496 <-> 399, 821, 1317 -1497 <-> 393 -1498 <-> 268, 1863 -1499 <-> 1453, 1499 -1500 <-> 271, 1647 -1501 <-> 1733 -1502 <-> 1406, 1574, 1960 -1503 <-> 134, 1274 -1504 <-> 1504 -1505 <-> 80, 1711 -1506 <-> 29, 381 -1507 <-> 17, 1435 -1508 <-> 1508, 1774 -1509 <-> 1108 -1510 <-> 1081 -1511 <-> 643, 1562, 1772, 1920 -1512 <-> 1255 -1513 <-> 1466 -1514 <-> 240, 619, 1038 -1515 <-> 175, 1748 -1516 <-> 255, 1240 -1517 <-> 216, 1716, 1936 -1518 <-> 1120, 1431 -1519 <-> 1058, 1729 -1520 <-> 569 -1521 <-> 980, 1170 -1522 <-> 602, 1482 -1523 <-> 408, 552 -1524 <-> 693, 1714 -1525 <-> 987, 1525 -1526 <-> 857, 1805 -1527 <-> 1016 -1528 <-> 299, 329 -1529 <-> 1630, 1736 -1530 <-> 936, 1712, 1908 -1531 <-> 1240 -1532 <-> 256, 917 -1533 <-> 44 -1534 <-> 1335 -1535 <-> 1494 -1536 <-> 583 -1537 <-> 572 -1538 <-> 493, 719 -1539 <-> 633, 1236 -1540 <-> 910, 947, 1474, 1741 -1541 <-> 793, 859, 1793 -1542 <-> 70, 160, 1542 -1543 <-> 598, 1005 -1544 <-> 882 -1545 <-> 1113 -1546 <-> 1374, 1491, 1716 -1547 <-> 344 -1548 <-> 1548 -1549 <-> 1549 -1550 <-> 386 -1551 <-> 371, 819, 1086, 1276 -1552 <-> 357, 471 -1553 <-> 546, 1392 -1554 <-> 540, 599, 1364 -1555 <-> 185 -1556 <-> 6, 573 -1557 <-> 1007 -1558 <-> 149, 763 -1559 <-> 1057, 1559 -1560 <-> 347 -1561 <-> 1016, 1302 -1562 <-> 1110, 1129, 1200, 1511 -1563 <-> 901, 1204, 1964 -1564 <-> 1564 -1565 <-> 247, 670 -1566 <-> 596, 699, 1443 -1567 <-> 1929 -1568 <-> 411 -1569 <-> 30, 146, 1571 -1570 <-> 1400, 1776 -1571 <-> 749, 1569 -1572 <-> 813, 1437, 1676 -1573 <-> 1093, 1573 -1574 <-> 853, 1502 -1575 <-> 1071 -1576 <-> 559, 1842 -1577 <-> 58, 153, 752 -1578 <-> 2, 451, 831, 878, 954, 1183 -1579 <-> 1034 -1580 <-> 332, 491 -1581 <-> 983, 1450, 1942 -1582 <-> 1291, 1824 -1583 <-> 252, 1998 -1584 <-> 1425, 1584 -1585 <-> 1851 -1586 <-> 601, 1877 -1587 <-> 40, 257, 1713 -1588 <-> 101, 1430 -1589 <-> 1589 -1590 <-> 47, 561 -1591 <-> 1605 -1592 <-> 577, 600, 830 -1593 <-> 947, 1255 -1594 <-> 867, 962 -1595 <-> 424 -1596 <-> 1040, 1687 -1597 <-> 581, 1619 -1598 <-> 546, 1778 -1599 <-> 175, 1048 -1600 <-> 408, 1938 -1601 <-> 870 -1602 <-> 721, 877, 1127 -1603 <-> 553, 1955 -1604 <-> 50, 1362 -1605 <-> 327, 1037, 1591 -1606 <-> 1875, 1887 -1607 <-> 452, 705, 966 -1608 <-> 96, 448 -1609 <-> 427, 755 -1610 <-> 1128 -1611 <-> 247, 302 -1612 <-> 1612 -1613 <-> 465 -1614 <-> 1841 -1615 <-> 529, 1306 -1616 <-> 1849 -1617 <-> 674 -1618 <-> 1410, 1758 -1619 <-> 1597 -1620 <-> 654, 1778 -1621 <-> 1036, 1779 -1622 <-> 921, 1851 -1623 <-> 100, 358 -1624 <-> 1728 -1625 <-> 823 -1626 <-> 1743 -1627 <-> 663 -1628 <-> 843, 1231 -1629 <-> 502 -1630 <-> 532, 1529 -1631 <-> 414 -1632 <-> 56, 1632 -1633 <-> 432, 718, 901 -1634 <-> 900, 1857 -1635 <-> 1675, 1925 -1636 <-> 1115, 1342, 1912 -1637 <-> 255, 1244 -1638 <-> 217, 473 -1639 <-> 382, 997, 1191 -1640 <-> 900 -1641 <-> 761 -1642 <-> 1107 -1643 <-> 1296, 1643 -1644 <-> 1945 -1645 <-> 1997 -1646 <-> 634 -1647 <-> 1500 -1648 <-> 360, 1450 -1649 <-> 40, 1011, 1381, 1958 -1650 <-> 50 -1651 <-> 398 -1652 <-> 560, 644 -1653 <-> 1158, 1749 -1654 <-> 1654 -1655 <-> 495, 1224 -1656 <-> 187, 204, 965 -1657 <-> 122, 265, 972 -1658 <-> 1140, 1658, 1718, 1744 -1659 <-> 29, 359, 1253 -1660 <-> 445, 1978 -1661 <-> 167, 437 -1662 <-> 342, 713, 1409 -1663 <-> 1758, 1937 -1664 <-> 677, 832, 1221, 1788 -1665 <-> 443, 1423 -1666 <-> 243, 1333, 1357, 1666 -1667 <-> 758, 865, 1896 -1668 <-> 95, 1455 -1669 <-> 639, 1686, 1761 -1670 <-> 558, 1114, 1670 -1671 <-> 1769 -1672 <-> 1222 -1673 <-> 212, 1313 -1674 <-> 494, 1106 -1675 <-> 838, 1635 -1676 <-> 1572 -1677 <-> 455, 993 -1678 <-> 256 -1679 <-> 513 -1680 <-> 616, 838, 1928 -1681 <-> 1293 -1682 <-> 656, 1881 -1683 <-> 640, 1827 -1684 <-> 670 -1685 <-> 1388, 1489 -1686 <-> 1363, 1669 -1687 <-> 982, 1172, 1270, 1315, 1596, 1913 -1688 <-> 174, 1187 -1689 <-> 338, 895 -1690 <-> 78, 957, 1764 -1691 <-> 1347 -1692 <-> 818 -1693 <-> 934, 1463 -1694 <-> 338, 392, 435 -1695 <-> 815, 872 -1696 <-> 1696 -1697 <-> 768, 1697 -1698 <-> 620 -1699 <-> 306, 1150 -1700 <-> 348, 660, 1474 -1701 <-> 1357 -1702 <-> 562, 1250 -1703 <-> 38, 1154 -1704 <-> 517 -1705 <-> 433, 688, 1895 -1706 <-> 102, 785 -1707 <-> 505 -1708 <-> 1236 -1709 <-> 192, 1214 -1710 <-> 702, 1791, 1840 -1711 <-> 10, 1505 -1712 <-> 1530 -1713 <-> 335, 542, 935, 1587, 1923 -1714 <-> 674, 1004, 1524, 1793 -1715 <-> 491, 724, 1738 -1716 <-> 1517, 1546, 1891 -1717 <-> 11, 995, 1433 -1718 <-> 1328, 1476, 1658 -1719 <-> 930 -1720 <-> 278, 827, 1798 -1721 <-> 407, 468 -1722 <-> 928, 1299, 1754, 1939 -1723 <-> 1097 -1724 <-> 683 -1725 <-> 452, 927, 1314 -1726 <-> 402, 766, 1311 -1727 <-> 1495 -1728 <-> 1624, 1937 -1729 <-> 1422, 1519 -1730 <-> 378, 839, 1398 -1731 <-> 239, 513, 1327 -1732 <-> 285, 1233, 1437 -1733 <-> 1501, 1844 -1734 <-> 345, 1759 -1735 <-> 292, 1399 -1736 <-> 346, 978, 1529 -1737 <-> 968, 1279, 1737 -1738 <-> 1715, 1809 -1739 <-> 109 -1740 <-> 669, 830, 1481 -1741 <-> 1540 -1742 <-> 189, 1451 -1743 <-> 584, 1626 -1744 <-> 1055, 1658 -1745 <-> 745 -1746 <-> 336, 1957, 1997 -1747 <-> 652 -1748 <-> 1169, 1449, 1515 -1749 <-> 276, 1653, 1940 -1750 <-> 710, 931, 1290 -1751 <-> 682, 1439 -1752 <-> 589, 1260 -1753 <-> 1806 -1754 <-> 1722 -1755 <-> 1846 -1756 <-> 775, 1756 -1757 <-> 1324, 1757 -1758 <-> 1209, 1618, 1663 -1759 <-> 1734 -1760 <-> 243, 594 -1761 <-> 1669, 1878 -1762 <-> 521, 537, 1419 -1763 <-> 1147, 1439 -1764 <-> 630, 1690 -1765 <-> 616 -1766 <-> 1833 -1767 <-> 65 -1768 <-> 139, 273, 742, 801, 889, 1781 -1769 <-> 689, 1671 -1770 <-> 1317, 1770 -1771 <-> 449, 735, 952, 1243 -1772 <-> 1511 -1773 <-> 1021 -1774 <-> 1508 -1775 <-> 829, 1169 -1776 <-> 1570 -1777 <-> 272, 289, 737, 1950 -1778 <-> 1598, 1620 -1779 <-> 400, 1148, 1621 -1780 <-> 1242 -1781 <-> 1768 -1782 <-> 519, 1025 -1783 <-> 1836 -1784 <-> 486 -1785 <-> 333 -1786 <-> 1058 -1787 <-> 1858 -1788 <-> 1664 -1789 <-> 35, 884 -1790 <-> 1157 -1791 <-> 138, 1710, 1847 -1792 <-> 1792 -1793 <-> 1541, 1714 -1794 <-> 645, 771, 1111 -1795 <-> 1795 -1796 <-> 1966 -1797 <-> 1072, 1944 -1798 <-> 1720, 1834 -1799 <-> 655 -1800 <-> 1015, 1243 -1801 <-> 1801 -1802 <-> 1802 -1803 <-> 393 -1804 <-> 1967 -1805 <-> 1526 -1806 <-> 669, 1753 -1807 <-> 1151, 1844 -1808 <-> 199 -1809 <-> 256, 1738, 1918 -1810 <-> 1810, 1840 -1811 <-> 85 -1812 <-> 5, 602 -1813 <-> 130, 1234, 1283 -1814 <-> 742 -1815 <-> 954 -1816 <-> 1184 -1817 <-> 1817 -1818 <-> 706, 792, 1385 -1819 <-> 999, 1053 -1820 <-> 102 -1821 <-> 532, 1445 -1822 <-> 361 -1823 <-> 287 -1824 <-> 963, 1582 -1825 <-> 22, 230, 1281, 1861 -1826 <-> 730, 1826 -1827 <-> 678, 1124, 1683, 1880 -1828 <-> 606, 943 -1829 <-> 154, 587, 1349 -1830 <-> 626, 1312 -1831 <-> 593 -1832 <-> 37, 1832 -1833 <-> 1766, 1833 -1834 <-> 584, 951, 998, 1492, 1798 -1835 <-> 913 -1836 <-> 555, 631, 1159, 1212, 1783 -1837 <-> 1182, 1264 -1838 <-> 1060 -1839 <-> 1432 -1840 <-> 1710, 1810 -1841 <-> 261, 1614, 1867 -1842 <-> 1576 -1843 <-> 776, 1302 -1844 <-> 622, 1069, 1444, 1733, 1807 -1845 <-> 1011 -1846 <-> 1023, 1755 -1847 <-> 1791 -1848 <-> 1459 -1849 <-> 751, 1616 -1850 <-> 1303, 1308 -1851 <-> 1585, 1622 -1852 <-> 1418 -1853 <-> 1124 -1854 <-> 1066 -1855 <-> 381 -1856 <-> 1925 -1857 <-> 305, 744, 1634 -1858 <-> 1107, 1787, 1858 -1859 <-> 458 -1860 <-> 976, 1010 -1861 <-> 551, 1022, 1825 -1862 <-> 500 -1863 <-> 248, 1498 -1864 <-> 402, 918 -1865 <-> 314, 642 -1866 <-> 1866 -1867 <-> 1841, 1867 -1868 <-> 532 -1869 <-> 374, 1183, 1994 -1870 <-> 507, 802 -1871 <-> 325 -1872 <-> 87, 492, 1472 -1873 <-> 90, 509, 897 -1874 <-> 220, 1162, 1957 -1875 <-> 63, 1606 -1876 <-> 65, 953 -1877 <-> 259, 1586, 1907 -1878 <-> 1761, 1989 -1879 <-> 1399 -1880 <-> 1827 -1881 <-> 1682 -1882 <-> 510, 1251 -1883 <-> 531, 1235 -1884 <-> 1884 -1885 <-> 1399, 1885 -1886 <-> 814 -1887 <-> 3, 1606 -1888 <-> 1325 -1889 <-> 1 -1890 <-> 628, 1249 -1891 <-> 1716 -1892 <-> 118 -1893 <-> 400, 570 -1894 <-> 637, 1937 -1895 <-> 526, 1705 -1896 <-> 1667, 1991 -1897 <-> 875, 1976 -1898 <-> 798 -1899 <-> 297 -1900 <-> 992 -1901 <-> 1259, 1465 -1902 <-> 494, 1917 -1903 <-> 480, 1300 -1904 <-> 545 -1905 <-> 1398 -1906 <-> 1152, 1278 -1907 <-> 84, 731, 1877 -1908 <-> 1530 -1909 <-> 952 -1910 <-> 1353 -1911 <-> 686, 795, 1246 -1912 <-> 1636 -1913 <-> 1687 -1914 <-> 118, 994, 1914 -1915 <-> 1080, 1993 -1916 <-> 326, 861, 870 -1917 <-> 403, 720, 1902, 1933 -1918 <-> 71, 1809 -1919 <-> 1056 -1920 <-> 559, 1259, 1511 -1921 <-> 993 -1922 <-> 663, 1396 -1923 <-> 1713 -1924 <-> 166, 862 -1925 <-> 1635, 1856 -1926 <-> 1179 -1927 <-> 1168, 1424 -1928 <-> 1680, 1928 -1929 <-> 729, 1567 -1930 <-> 238, 1933 -1931 <-> 1403 -1932 <-> 322, 929, 1213 -1933 <-> 1917, 1930 -1934 <-> 407 -1935 <-> 456 -1936 <-> 1517 -1937 <-> 461, 1663, 1728, 1894, 1937 -1938 <-> 1600 -1939 <-> 1722 -1940 <-> 1749 -1941 <-> 755 -1942 <-> 1581, 1967 -1943 <-> 1263, 1404 -1944 <-> 71, 1797 -1945 <-> 398, 1313, 1644 -1946 <-> 1222, 1946 -1947 <-> 1998 -1948 <-> 503 -1949 <-> 520 -1950 <-> 1777 -1951 <-> 71, 152, 397, 1061 -1952 <-> 500 -1953 <-> 199, 642 -1954 <-> 230, 356, 675 -1955 <-> 1603 -1956 <-> 181 -1957 <-> 501, 898, 1746, 1874 -1958 <-> 1265, 1649 -1959 <-> 449 -1960 <-> 1502 -1961 <-> 1961 -1962 <-> 302, 783 -1963 <-> 345 -1964 <-> 1563 -1965 <-> 197, 1039, 1046 -1966 <-> 127, 1796 -1967 <-> 314, 1804, 1942 -1968 <-> 12, 110 -1969 <-> 316, 878 -1970 <-> 442, 1135 -1971 <-> 693 -1972 <-> 1185 -1973 <-> 1394, 1973 -1974 <-> 71 -1975 <-> 52, 987 -1976 <-> 341, 1897 -1977 <-> 197, 879, 1237 -1978 <-> 1660 -1979 <-> 336 -1980 <-> 321, 465 -1981 <-> 1082 -1982 <-> 964, 1982 -1983 <-> 1293 -1984 <-> 301, 638, 1309 -1985 <-> 635 -1986 <-> 631 -1987 <-> 92 -1988 <-> 970 -1989 <-> 1878, 1989 -1990 <-> 565 -1991 <-> 1896 -1992 <-> 241, 334 -1993 <-> 466, 1915 -1994 <-> 1869 -1995 <-> 741, 1169 -1996 <-> 1363 -1997 <-> 1645, 1746 -1998 <-> 890, 1211, 1583, 1947 -1999 <-> 379, 1319"; - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let worker_input = - input - .lines() - .enumerate() - .filter(|&(pos,_)| pos % peers == index) - .flat_map(|(_, line)| { - let mut words = line.split_whitespace(); - let source = words.next().unwrap().parse::().unwrap(); - words.next(); - words.map(move |neighbor| (source, neighbor.trim_matches(',').parse::().unwrap())) - }) - .collect::>(); - - worker.dataflow::<(),_,_>(|scope| { - - let edges = scope.new_collection_from(worker_input).1; - let nodes = edges.map(|(src, _tgt)| (src, src)).distinct(); - - let labels = - nodes - .iterate(|scope, label| { - let edges = edges.enter(scope); - let nodes = nodes.enter(scope); - label - .join_map(edges, |_src, &lbl, &tgt| (tgt, lbl)) - .concat(nodes) - .group(|_, input, output| output.push((*input[0].0, 1))) - }) - .map(|(_src, lbl)| lbl); - - labels - .filter(|&lbl| lbl == 0) - .consolidate() - .inspect(|x| println!("part1: {:?}", x.2)); - - labels - .distinct() - .map(|_| ()) - .consolidate() - .inspect(|x| println!("part2: {:?}", x.2)); - - }); - - }).unwrap(); -} diff --git a/advent_of_code_2017/src/bin/day_13.rs b/advent_of_code_2017/src/bin/day_13.rs deleted file mode 100644 index 54251b1356..0000000000 --- a/advent_of_code_2017/src/bin/day_13.rs +++ /dev/null @@ -1,93 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/13 - -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = "0: 4 -1: 2 -2: 3 -4: 4 -6: 6 -8: 5 -10: 6 -12: 6 -14: 6 -16: 12 -18: 8 -20: 9 -22: 8 -24: 8 -26: 8 -28: 8 -30: 12 -32: 10 -34: 8 -36: 12 -38: 10 -40: 12 -42: 12 -44: 12 -46: 12 -48: 12 -50: 14 -52: 14 -54: 12 -56: 12 -58: 14 -60: 14 -62: 14 -66: 14 -68: 14 -70: 14 -72: 14 -74: 14 -78: 18 -80: 14 -82: 14 -88: 18 -92: 17"; - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let worker_input = - input - .split('\n') - .map(|line| { - let mut words = line.split_whitespace(); - let start = words.next().unwrap().trim_matches(':').parse::().unwrap(); - let width = words.next().unwrap().parse::().unwrap(); - (start, width) - }) - .filter(move |&(pos,_)| pos % peers == index); - - worker.dataflow::<(),_,_>(|scope| { - - let data = scope.new_collection_from(worker_input).1; - - data.filter(|&(pos, wid)| pos % (2 * (wid-1)) == 0) - .explode(|(pos, wid)| Some(((), (pos * wid) as isize))) - .consolidate() - .inspect(|x| println!("part1: {:?}", x.2)); - - // remove redundant constraints - let data = data.map(|(pos, wid)| (pos % (2 * (wid-1)), wid)).distinct(); - - let limit = 10000000; - data.flat_map(move |(pos, wid)| (0..limit).filter(move |x| (x + pos) % (2 * (wid-1)) == 0)) - .distinct() - .negate() - .concat(scope.new_collection_from(0 .. limit).1) - .consolidate() - .inspect(|x| println!("part2: {:?}", x.0)); - }); - - }).unwrap(); -} diff --git a/advent_of_code_2017/src/bin/day_14.rs b/advent_of_code_2017/src/bin/day_14.rs deleted file mode 100644 index e6dd4f9583..0000000000 --- a/advent_of_code_2017/src/bin/day_14.rs +++ /dev/null @@ -1,95 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/8 - -use differential_dataflow::VecCollection; -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let input = "jzgqcdpd"; - - timely::execute_from_args(std::env::args(), move |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let worker_input = - (0 .. 128) - .filter(move |&pos| pos % peers == index); - - worker.dataflow::<(),_,_>(|scope| { - - let data = scope.new_collection_from(worker_input).1; - - let hashes = - data.flat_map(move |row| { - let string = format!("{}-{}", input, row); - let hash = knot_hash(&string); - // println!("{:?}: \t{:?}", row, hash); - - (0 .. 128) - .map(move |col| - if hash[col/8] & (1 << (7-(col % 8))) != 0 { - (row, col, '#') - } - else { - (row, col, '.') - } - ) - } - ); - - hashes - .filter(|&(_,_,symbol)| symbol == '#') - .map(|_| ()) - .consolidate() - .inspect(|x| println!("part1: {:?}", x.2)); - - // part two wants the number of connected components of hash regions. - - }); - - }).unwrap(); -} - -fn knot_hash(string: &str) -> Vec { - let mut bytes = string.as_bytes().iter().cloned().collect::>(); - bytes.push(17); - bytes.push(31); - bytes.push(73); - bytes.push(47); - bytes.push(23); - let hash = knot_step(bytes.iter().cloned(), 64); - - let mut result = vec![0u8; 16]; - - for byte in 0 .. 16 { - for step in 0 .. 16 { - result[byte] ^= hash[16 * byte + step]; - } - } - result -} - -fn knot_step+Clone>(iter: I, rounds: usize) -> Vec { - - let mut state = (0 .. 256u16).map(|x| x as u8).collect::>(); - let mut cursor = 0; - let mut step = 0; - - for _ in 0 .. rounds { - for width in iter.clone() { - let width = width as usize; - for swap in 0 .. width / 2 { - state.swap((cursor + swap) % 256, (cursor + width - swap - 1) % 256); - } - cursor = (cursor + width + step) % 256; - step += 1; - } - } - - state -} diff --git a/advent_of_code_2017/src/bin/day_15.rs b/advent_of_code_2017/src/bin/day_15.rs deleted file mode 100644 index a8c2a8d791..0000000000 --- a/advent_of_code_2017/src/bin/day_15.rs +++ /dev/null @@ -1,46 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/8 - -use differential_dataflow::VecCollection; -use differential_dataflow::input::Input; -use differential_dataflow::operators::*; - -fn main() { - - let mut a = 873u64; - let mut b = 583u64; - let mut equal = 0; - - let a_iter = (0 ..).map(move |_| { a = (a * 16807) % 2147483647; a }); - let b_iter = (0 ..).map(move |_| { b = (b * 48271) % 2147483647; b }); - - for (a,b) in a_iter.zip(b_iter).take(40_000_000) { - - if (a % 65536) == (b % 65536) { - equal += 1; - } - } - - println!("part1: {:?}", equal); - - - - let mut a = 873u64; - let mut b = 583u64; - let mut equal = 0; - - let a_iter = (0 ..).map(move |_| { a = (a * 16807) % 2147483647; a }).filter(|&x| x % 4 == 0); - let b_iter = (0 ..).map(move |_| { b = (b * 48271) % 2147483647; b }).filter(|&x| x % 8 == 0); - - for (a,b) in a_iter.zip(b_iter).take(5_000_000) { - - if (a % 65536) == (b % 65536) { - equal += 1; - } - } - - println!("part2: {:?}", equal); - -} diff --git a/advent_of_code_2017/src/bin/day_17.rs b/advent_of_code_2017/src/bin/day_17.rs deleted file mode 100644 index 958707e739..0000000000 --- a/advent_of_code_2017/src/bin/day_17.rs +++ /dev/null @@ -1,43 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; - -// taken from: https://adventofcode.com/2017/day/17 - -fn main() { - - let step = 382; - - // pointer[i] is the element after i in the sequence. - let mut pointer = vec![0]; - - for index in 1 .. 2018 { - let mut pos = index - 1; - for _ in 0 .. step { - pos = pointer[pos]; - } - - let next = pointer[pos]; - pointer.push(next); - pointer[pos] = index; - } - - println!("part1: {:?}", pointer[2017]); - - // Solution nicked from the internet. generalization of above works, just is slow. - // Because we now just look for a fixed location, we don't need to save any state; - // we can use the fact that "the value after 0" is always position one, because - // the zero value doesn't move (unlike all the other values). - let mut result = None; - let mut position = 0; - for index in 1 .. 50_000_000 { - position = (position + step) % index + 1; - if position == 1 { - result = Some(index); - } - } - - if let Some(value) = result { - println!("part2: {:?}", value); - } - -} \ No newline at end of file diff --git a/advent_of_code_2017/src/lib.rs b/advent_of_code_2017/src/lib.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/doop/Cargo.toml b/doop/Cargo.toml deleted file mode 100644 index e128fb4a96..0000000000 --- a/doop/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "doop" -version = "0.1.0" -authors = ["Frank McSherry "] -edition.workspace = true -rust-version.workspace = true -publish = false - -[lints] -workspace = true - -[dependencies] -timely = {workspace = true} -differential-dataflow = { workspace = true } diff --git a/doop/self-contained.dl b/doop/self-contained.dl deleted file mode 100644 index 3b2101c34e..0000000000 --- a/doop/self-contained.dl +++ /dev/null @@ -1,561 +0,0 @@ -// Main schema -.type Modifier -.type Type -.type PrimitiveType = Type -.type ReferenceType = Type -.type ArrayType = ReferenceType -.type ClassType = ReferenceType -.type InterfaceType = ReferenceType -.decl isType(?t:Type) -.decl isReferenceType(?t:ReferenceType) -.decl isArrayType(?t:ArrayType) -.decl isClassType(?t:ClassType) -.decl isInterfaceType(?t:InterfaceType) -.decl DirectSuperclass(?class:ClassType, ?superclass:ClassType) -.input DirectSuperclass(IO="file", filename="DirectSuperclass.facts", delimiter="\t") -.decl DirectSuperinterface(?ref:ReferenceType, ?interface:InterfaceType) -.input DirectSuperinterface(IO="file", filename="DirectSuperinterface.facts", delimiter="\t") -.decl ApplicationClass(?ref:ReferenceType) -.decl MainClass(?class:ClassType) -.input MainClass(IO="file", filename="MainClass.facts", delimiter="\t") -.type Field -.decl Field_DeclaringType(?field:Field, ?declaringClass:ReferenceType) -.type MethodDescriptor -.type Method -.decl Method_DeclaringType(?method:Method, ?declaringType:ReferenceType) -.decl Method_ReturnType(?method:Method, ?returnType:Type) -.decl Method_SimpleName(?method:Method, ?simpleName:symbol) -.decl Method_Params(?method:Method, ?params:symbol) -.decl Method_Descriptor(?method:Method, ?descriptor:MethodDescriptor) -.decl Method_Modifier(?mod:Modifier, ?method:Method) -.input Method_Modifier(IO="file", filename="Method-Modifier.facts", delimiter="\t") -.decl FormalParam(?index:number, ?method:Method, ?var:Var) -.input FormalParam(IO="file", filename="FormalParam.facts", delimiter="\t") -.decl ThisVar(?method:Method, ?var:Var) -.type Var -.decl Var_Type(?var:Var, ?type:Type) -.input Var_Type(IO="file", filename="Var-Type.facts", delimiter="\t") -.decl Var_DeclaringMethod(?var:Var, ?method:Method) -.type HeapAllocation -.decl HeapAllocation_Type(?heap:HeapAllocation, ?type:Type) -.decl MainMethodArgArray(?heap:HeapAllocation) -.decl MainMethodArgArrayContent(?heap:HeapAllocation) -.type Instruction -.decl Instruction_Method(?insn:Instruction, ?inMethod:Method) -.type FieldInstruction = Instruction -.type LoadInstanceField_Insn = FieldInstruction -.type StoreInstanceField_Insn = FieldInstruction -.type LoadStaticField_Insn = FieldInstruction -.type StoreStaticField_Insn = FieldInstruction -.type ArrayInstruction = Instruction -.type LoadArrayIndex_Insn = ArrayInstruction -.type StoreArrayIndex_Insn = ArrayInstruction -.type AssignInstruction = Instruction -.type AssignLocal_Insn = AssignInstruction -.type AssignCast_Insn = AssignInstruction -.type AssignHeapAllocation_Insn = AssignInstruction -.type ReturnInstruction = Instruction -.type ReturnNonvoid_Insn = ReturnInstruction -.type MethodInvocation = Instruction -.type VirtualMethodInvocation_Insn = MethodInvocation -.type StaticMethodInvocation_Insn = MethodInvocation -.decl isVirtualMethodInvocation_Insn(?insn:VirtualMethodInvocation_Insn) -.decl isStaticMethodInvocation_Insn(?insn:StaticMethodInvocation_Insn) -.decl FieldInstruction_Signature(?insn:FieldInstruction, ?sign:Field) -.decl LoadInstanceField_Base(?insn:LoadInstanceField_Insn, ?var:Var) -.decl LoadInstanceField_To(?insn:LoadInstanceField_Insn, ?var:Var) -.decl StoreInstanceField_From(?insn:StoreInstanceField_Insn, ?var:Var) -.decl StoreInstanceField_Base(?insn:StoreInstanceField_Insn, ?var:Var) -.decl LoadStaticField_To(?insn:LoadStaticField_Insn, ?var:Var) -.decl StoreStaticField_From(?insn:StoreStaticField_Insn, ?var:Var) -.decl ComponentType(?arrayType:ArrayType, ?componentType:Type) -.input ComponentType(IO="file", filename="ComponentType.facts", delimiter="\t") -.decl LoadArrayIndex_Base(?insn:LoadArrayIndex_Insn, ?var:Var) -.decl LoadArrayIndex_To(?insn:LoadArrayIndex_Insn, var:Var) -.decl StoreArrayIndex_From(?insn:StoreArrayIndex_Insn, ?var:Var) -.decl StoreArrayIndex_Base(?insn:StoreArrayIndex_Insn, ?var:Var) -.decl AssignInstruction_To(?insn:AssignInstruction, ?to:Var) -.decl AssignCast_From(?insn:AssignCast_Insn, ?from:Var) -.decl AssignCast_Type(?insn:AssignCast_Insn, ?type:Type) -.decl AssignLocal_From(?insn:AssignLocal_Insn, ?from:Var) -.decl AssignHeapAllocation_Heap(?insn:AssignHeapAllocation_Insn, ?heap:HeapAllocation) -.decl ReturnNonvoid_Var(?return:ReturnNonvoid_Insn, ?var:Var) -.decl MethodInvocation_Method(?invocation:MethodInvocation, ?signature:Method) -.decl AssignReturnValue(?invocation:MethodInvocation, ?to:Var) -.input AssignReturnValue(IO="file", filename="AssignReturnValue.facts", delimiter="\t") -.decl ActualParam(?index:number, ?invocation:MethodInvocation, ?var:Var) -.input ActualParam(IO="file", filename="ActualParam.facts", delimiter="\t") -.decl VirtualMethodInvocation_Base(?invocation:VirtualMethodInvocation_Insn, ?base:Var) -.decl VirtualMethodInvocation_SimpleName(?invocation:MethodInvocation, ?simplename:symbol) -.decl VirtualMethodInvocation_Descriptor(?invocation:MethodInvocation, ?descriptor:MethodDescriptor) -.decl SpecialMethodInvocation_Base(?invocation:MethodInvocation, ?base:Var) -.decl MethodInvocation_Base(?invocation:MethodInvocation, ?base:Var) - -// Fat schema -.decl LoadInstanceField(?base:Var, ?sig:Field, ?to:Var, ?inmethod:Method) -.decl StoreInstanceField(?from:Var, ?base:Var, ?signature:Field, ?inmethod:Method) -.decl LoadStaticField(?sig:Field, ?to:Var, ?inmethod:Method) -.decl StoreStaticField(?from:Var, ?signature:Field, ?inmethod:Method) -.decl LoadArrayIndex(?base:Var, ?to:Var, ?inmethod:Method) -.decl StoreArrayIndex(?from:Var, ?base:Var, ?inmethod:Method) -.decl AssignCast(?type:Type, ?from:Var, ?to:Var, ?inmethod:Method) -.decl AssignLocal(?from:Var, ?to:Var, ?inmethod:Method) -.decl AssignHeapAllocation(?heap:HeapAllocation, ?to:Var, ?inmethod:Method) -.decl ReturnVar(?var:Var, ?method:Method) -.decl StaticMethodInvocation(?invocation:MethodInvocation, ?signature:Method, ?inmethod:Method) - -// imports -.decl _ClassType(?class:symbol) -.input _ClassType(IO="file", filename="ClassType.facts", delimiter="\t") -isType(?class), -isReferenceType(?class), -isClassType(?class) :- - _ClassType(?class). -.decl _ArrayType(?arrayType:symbol) -.input _ArrayType(IO="file", filename="ArrayType.facts", delimiter="\t") -isType(?arrayType), -isReferenceType(?arrayType), -isArrayType(?arrayType) :- - _ArrayType(?arrayType). -.decl _InterfaceType(?interface:symbol) -.input _InterfaceType(IO="file", filename="InterfaceType.facts", delimiter="\t") -isType(?interface), -isReferenceType(?interface), -isInterfaceType(?interface) :- - _InterfaceType(?interface). -.decl _Var_DeclaringMethod(?var:symbol, ?method:symbol) -.input _Var_DeclaringMethod(IO="file", filename="Var-DeclaringMethod.facts", delimiter="\t") -Var_DeclaringMethod(?var, ?method) :- - _Var_DeclaringMethod(?var, ?method). -.decl _ApplicationClass(?type:symbol) -.input _ApplicationClass(IO="file", filename="ApplicationClass.facts", delimiter="\t") -isType(?type), -isReferenceType(?type), -ApplicationClass(?type) :- - _ApplicationClass(?type). -.decl _ThisVar(?method:symbol, ?var:symbol) -.input _ThisVar(IO="file", filename="ThisVar.facts", delimiter="\t") -ThisVar(?method, ?var) :- - _ThisVar(?method, ?var). -.decl _NormalHeap(?id:symbol, ?type:symbol) -.input _NormalHeap(IO="file", filename="NormalHeap.facts", delimiter="\t") -isType(?type), -HeapAllocation_Type(?id, ?type) :- - _NormalHeap(?id, ?type). -.decl _StringConstant(?id:symbol) -.input _StringConstant(IO="file", filename="StringConstant.facts", delimiter="\t") -HeapAllocation_Type(?id, "java.lang.String") :- - _StringConstant(?id). -.decl _AssignHeapAllocation(?instruction:symbol, ?index:number, ?heap:symbol, ?to:symbol, ?inmethod:symbol, ?linenumber:number) -.input _AssignHeapAllocation(IO="file", filename="AssignHeapAllocation.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -AssignInstruction_To(?instruction, ?to), -AssignHeapAllocation_Heap(?instruction, ?heap) :- - _AssignHeapAllocation(?instruction, ?index, ?heap, ?to, ?method, ?linenumber). -.decl _AssignLocal(?instruction:symbol, ?index:number, ?from:symbol, ?to:symbol, ?inmethod:symbol) -.input _AssignLocal(IO="file", filename="AssignLocal.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -AssignLocal_From(?instruction, ?from), -AssignInstruction_To(?instruction, ?to) :- - _AssignLocal(?instruction, ?index, ?from, ?to, ?method). -.decl _AssignCast(?instruction:symbol, ?index:number, ?from:symbol, ?to:symbol, ?type:symbol, ?inmethod:symbol) -.input _AssignCast(IO="file", filename="AssignCast.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -AssignCast_Type(?instruction, ?type), -AssignCast_From(?instruction, ?from), -AssignInstruction_To(?instruction, ?to) :- - _AssignCast(?instruction, ?index, ?from, ?to, ?type, ?method). -.decl _Field(?signature:symbol, ?declaringClass:symbol, ?simplename:symbol, ?type:symbol) -.input _Field(IO="file", filename="Field.facts", delimiter="\t") -Field_DeclaringType(?signature, ?declaringType) :- - _Field(?signature, ?declaringType, _, _). -MethodInvocation_Base(?invocation, ?base) :- - VirtualMethodInvocation_Base(?invocation, ?base) ; - SpecialMethodInvocation_Base(?invocation, ?base). -.decl _StaticMethodInvocation(?instruction:symbol, ?index:number, ?signature:symbol, ?method:symbol) -.input _StaticMethodInvocation(IO="file", filename="StaticMethodInvocation.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -isStaticMethodInvocation_Insn(?instruction), -MethodInvocation_Method(?instruction, ?signature) :- - _StaticMethodInvocation(?instruction, ?index, ?signature, ?method). -.decl _SpecialMethodInvocation(?instruction:symbol, ?index:number, ?signature:symbol, ?base:symbol, ?method:symbol) -.input _SpecialMethodInvocation(IO="file", filename="SpecialMethodInvocation.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -SpecialMethodInvocation_Base(?instruction, ?base), -MethodInvocation_Method(?instruction, ?signature) :- - _SpecialMethodInvocation(?instruction, ?index, ?signature, ?base, ?method). -.decl _VirtualMethodInvocation(?instruction:symbol, ?index:number, ?signature:symbol, ?base:symbol, ?method:symbol) -.input _VirtualMethodInvocation(IO="file", filename="VirtualMethodInvocation.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -isVirtualMethodInvocation_Insn(?instruction), -VirtualMethodInvocation_Base(?instruction, ?base), -MethodInvocation_Method(?instruction, ?signature) :- - _VirtualMethodInvocation(?instruction, ?index, ?signature, ?base, ?method). -.decl _Method(?method:symbol, ?simplename:symbol, ?descriptor:symbol, ?declaringType:symbol, ?returnType:symbol, ?jvmDescriptor:symbol, ?arity:number) -.input _Method(IO="file", filename="Method.facts", delimiter="\t") -Method_SimpleName(?method, ?simplename), -Method_Params(?method, ?params), -Method_DeclaringType(?method, ?declaringType), -Method_ReturnType(?method, ?returnType) :- - _Method(?method, ?simplename, ?params, ?declaringType, ?returnType, ?jvmDescriptor, ?arity). -Method_Descriptor(?method, ?descriptor) :- - Method_ReturnType(?method, ?returnType), - Method_Params(?method, ?params), - ?descriptor = cat(?returnType, ?params). -.decl _StoreInstanceField(?instruction:symbol, ?index:number, ?from:symbol, ?base:symbol, ?signature:symbol, ?method:symbol) -.input _StoreInstanceField(IO="file", filename="StoreInstanceField.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -FieldInstruction_Signature(?instruction, ?signature), -StoreInstanceField_Base(?instruction, ?base), -StoreInstanceField_From(?instruction, ?from) :- - _StoreInstanceField(?instruction, ?index, ?from, ?base, ?signature, ?method). -.decl _LoadInstanceField(?instruction:symbol, ?index:number, ?to:symbol, ?base:symbol, ?signature:symbol, ?method:symbol) -.input _LoadInstanceField(IO="file", filename="LoadInstanceField.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -FieldInstruction_Signature(?instruction, ?signature), -LoadInstanceField_Base(?instruction, ?base), -LoadInstanceField_To(?instruction, ?to) :- - _LoadInstanceField(?instruction, ?index, ?to, ?base, ?signature, ?method). -.decl _StoreStaticField(?instruction:symbol, ?index:number, ?from:symbol, ?signature:symbol, ?method:symbol) -.input _StoreStaticField(IO="file", filename="StoreStaticField.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -FieldInstruction_Signature(?instruction, ?signature), -StoreStaticField_From(?instruction, ?from) :- - _StoreStaticField(?instruction, ?index, ?from, ?signature, ?method). -.decl _LoadStaticField(?instruction:symbol, ?index:number, ?to:symbol, ?signature:symbol, ?method:symbol) -.input _LoadStaticField(IO="file", filename="LoadStaticField.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -FieldInstruction_Signature(?instruction, ?signature), -LoadStaticField_To(?instruction, ?to) :- - _LoadStaticField(?instruction, ?index, ?to, ?signature, ?method). -.decl _StoreArrayIndex(?instruction:symbol, ?index:number, ?from:symbol, ?base:symbol, ?method:symbol) -.input _StoreArrayIndex(IO="file", filename="StoreArrayIndex.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -StoreArrayIndex_Base(?instruction, ?base), -StoreArrayIndex_From(?instruction, ?from) :- - _StoreArrayIndex(?instruction, ?index, ?from, ?base, ?method). -.decl _LoadArrayIndex(?instruction:symbol, ?index:number, ?to:symbol, ?base:symbol, ?method:symbol) -.input _LoadArrayIndex(IO="file", filename="LoadArrayIndex.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -LoadArrayIndex_Base(?instruction, ?base), -LoadArrayIndex_To(?instruction, ?to) :- - _LoadArrayIndex(?instruction, ?index, ?to, ?base, ?method). -.decl _Return(?instruction:symbol, ?index:number, ?var:symbol, ?method:symbol) -.input _Return(IO="file", filename="Return.facts", delimiter="\t") -Instruction_Method(?instruction, ?method), -ReturnNonvoid_Var(?instruction, ?var) :- - _Return(?instruction, ?index, ?var, ?method). - -// fat schema population -LoadInstanceField(?base, ?sig, ?to, ?inmethod) :- - Instruction_Method(?insn, ?inmethod), - LoadInstanceField_Base(?insn, ?base), - FieldInstruction_Signature(?insn, ?sig), - LoadInstanceField_To(?insn, ?to). -StoreInstanceField(?from, ?base, ?sig, ?inmethod) :- - Instruction_Method(?insn, ?inmethod), - StoreInstanceField_From(?insn, ?from), - StoreInstanceField_Base(?insn, ?base), - FieldInstruction_Signature(?insn, ?sig). -LoadStaticField(?sig, ?to, ?inmethod) :- - Instruction_Method(?insn, ?inmethod), - FieldInstruction_Signature(?insn, ?sig), - LoadStaticField_To(?insn, ?to). -StoreStaticField(?from, ?sig, ?inmethod) :- - Instruction_Method(?insn, ?inmethod), - StoreStaticField_From(?insn, ?from), - FieldInstruction_Signature(?insn, ?sig). -LoadArrayIndex(?base, ?to, ?inmethod) :- - Instruction_Method(?insn, ?inmethod), - LoadArrayIndex_Base(?insn, ?base), - LoadArrayIndex_To(?insn, ?to). -StoreArrayIndex(?from, ?base, ?inmethod) :- - Instruction_Method(?insn, ?inmethod), - StoreArrayIndex_From(?insn, ?from), - StoreArrayIndex_Base(?insn, ?base). -AssignCast(?type, ?from, ?to, ?inmethod) :- - Instruction_Method(?insn, ?inmethod), - AssignCast_From(?insn, ?from), - AssignInstruction_To(?insn, ?to), - AssignCast_Type(?insn, ?type). -AssignLocal(?from, ?to, ?inmethod) :- - AssignInstruction_To(?insn, ?to), - Instruction_Method(?insn, ?inmethod), - AssignLocal_From(?insn, ?from). -AssignHeapAllocation(?heap, ?to, ?inmethod) :- - Instruction_Method(?insn, ?inmethod), - AssignHeapAllocation_Heap(?insn, ?heap), - AssignInstruction_To(?insn, ?to). -ReturnVar(?var, ?method) :- - Instruction_Method(?insn, ?method), - ReturnNonvoid_Var(?insn, ?var). -StaticMethodInvocation(?invocation, ?signature, ?inmethod) :- - isStaticMethodInvocation_Insn(?invocation), - Instruction_Method(?invocation, ?inmethod), - MethodInvocation_Method(?invocation, ?signature). -HeapAllocation_Type(?heap, ?type), -MainMethodArgArray(?heap) :- - ?heap = "<
>", - ?type = "java.lang.String[]". -HeapAllocation_Type(?heap, ?type), -MainMethodArgArrayContent(?heap) :- - ?heap = "<
>", - ?type = "java.lang.String". -VirtualMethodInvocation_SimpleName(?invocation, ?simplename), -VirtualMethodInvocation_Descriptor(?invocation, ?descriptor) :- - isVirtualMethodInvocation_Insn(?invocation), - MethodInvocation_Method(?invocation, ?signature), - Method_SimpleName(?signature, ?simplename), - Method_Descriptor(?signature, ?descriptor). - -// Basic (type-based) analysis -.comp Basic { -.decl MethodLookup(?simplename:symbol, ?descriptor:MethodDescriptor, ?type:Type, ?method:Method) -.decl MethodImplemented(?simplename:symbol, ?descriptor:MethodDescriptor, ?type:Type, ?method:Method) -.decl DirectSubclass(?a:Type, ?c:Type) -.decl Subclass(?c:Type, ?a:Type) -.decl Superclass(?c:Type, ?a:Type) -.decl Superinterface(?k:Type, ?c:Type) -.decl SubtypeOf(?subtype:Type, ?type:Type) -.decl SupertypeOf(?supertype:Type, ?type:Type) -.decl SubtypeOfDifferent(?subtype:Type, ?type:Type) -.decl MainMethodDeclaration(?method:Method) -MethodLookup(?simplename, ?descriptor, ?type, ?method) :- - MethodImplemented(?simplename, ?descriptor, ?type, ?method). -MethodLookup(?simplename, ?descriptor, ?type, ?method) :- - (DirectSuperclass(?type, ?supertype) ; - DirectSuperinterface(?type, ?supertype)), - MethodLookup(?simplename, ?descriptor, ?supertype, ?method), - ! MethodImplemented(?simplename, ?descriptor, ?type, _). -MethodImplemented(?simplename, ?descriptor, ?type, ?method) :- - Method_SimpleName(?method, ?simplename), - Method_Descriptor(?method, ?descriptor), - Method_DeclaringType(?method, ?type), - ! Method_Modifier("abstract", ?method). -DirectSubclass(?a, ?c) :- - DirectSuperclass(?a, ?c). -Subclass(?c, ?a) :- - DirectSubclass(?a, ?c). -Subclass(?c, ?a) :- - Subclass(?b, ?a), - DirectSubclass(?b, ?c). -Superclass(?c, ?a) :- - Subclass(?a, ?c). -Superinterface(?k, ?c) :- - DirectSuperinterface(?c, ?k). -Superinterface(?k, ?c) :- - DirectSuperinterface(?c, ?j), - Superinterface(?k, ?j). -Superinterface(?k, ?c) :- - DirectSuperclass(?c, ?super), - Superinterface(?k, ?super). -SupertypeOf(?s, ?t) :- - SubtypeOf(?t, ?s). -SubtypeOf(?s, ?s) :- - isClassType(?s). -SubtypeOf(?s, ?t) :- - Subclass(?t, ?s). -SubtypeOf(?s, ?t) :- - isClassType(?s), - Superinterface(?t, ?s). -SubtypeOf(?s, ?t) :- - isInterfaceType(?s), - isType(?t), - ?t = "java.lang.Object". -SubtypeOf(?s, ?s) :- - isInterfaceType(?s). -SubtypeOf(?s, ?t) :- - isInterfaceType(?s), - Superinterface(?t, ?s). -SubtypeOf(?s, ?t) :- - isArrayType(?s), - isType(?t), - ?t = "java.lang.Object". -SubtypeOf(?s, ?t) :- - ComponentType(?s, ?sc), - ComponentType(?t, ?tc), - isReferenceType(?sc), - isReferenceType(?tc), - SubtypeOf(?sc, ?tc). -SubtypeOf(?s, ?t) :- - isArrayType(?s), - isInterfaceType(?t), - isType(?t), - ?t = "java.lang.Cloneable". -SubtypeOf(?s, ?t) :- - isArrayType(?s), - isInterfaceType(?t), - isType(?t), - ?t = "java.io.Serializable". -SubtypeOf(?t, ?t) :- - isType(?t). -SubtypeOfDifferent(?s, ?t) :- - SubtypeOf(?s, ?t), - ?s != ?t. -MainMethodDeclaration(?method) :- - MainClass(?type), - Method_DeclaringType(?method, ?type), - ?method != "", - ?method != "", - ?method != "", - Method_SimpleName(?method, "main"), - Method_Descriptor(?method, "void(java.lang.String[])"), - Method_Modifier("public", ?method), - Method_Modifier("static", ?method). -} -.init basic = Basic - -// class initialization -.decl ClassInitializer(?type:Type, ?method:Method) -.decl InitializedClass(?classOrInterface:Type) -ClassInitializer(?type, ?method) :- - basic.MethodImplemented("", "void()", ?type, ?method). -InitializedClass(?superclass) :- - InitializedClass(?class), - DirectSuperclass(?class, ?superclass). -InitializedClass(?superinterface) :- - InitializedClass(?classOrInterface), - DirectSuperinterface(?classOrInterface, ?superinterface). -InitializedClass(?class) :- - basic.MainMethodDeclaration(?method), - Method_DeclaringType(?method, ?class). -InitializedClass(?class) :- - Reachable(?inmethod), - AssignHeapAllocation(?heap, _, ?inmethod), - HeapAllocation_Type(?heap, ?class). -InitializedClass(?class) :- - Reachable(?inmethod), - Instruction_Method(?invocation, ?inmethod), - isStaticMethodInvocation_Insn(?invocation), - MethodInvocation_Method(?invocation, ?signature), - Method_DeclaringType(?signature, ?class). -InitializedClass(?classOrInterface) :- - Reachable(?inmethod), - StoreStaticField(_, ?signature, ?inmethod), - Field_DeclaringType(?signature, ?classOrInterface). -InitializedClass(?classOrInterface) :- - Reachable(?inmethod), - LoadStaticField(?signature, _, ?inmethod), - Field_DeclaringType(?signature, ?classOrInterface). -Reachable(?clinit) :- - InitializedClass(?class), - ClassInitializer(?class, ?clinit). - -// Main (value-based) analysis -.decl Assign(?to:Var, ?from:Var) -.output Assign -.decl VarPointsTo(?heap:HeapAllocation, ?var:Var) -.output VarPointsTo -.decl InstanceFieldPointsTo(?heap:HeapAllocation , ?fld:Field, ?baseheap:HeapAllocation) -.output InstanceFieldPointsTo -.decl StaticFieldPointsTo(?heap:HeapAllocation, ?fld:Field) -.output StaticFieldPointsTo -.decl CallGraphEdge(?invocation:MethodInvocation, ?meth:Method) -.output CallGraphEdge -.decl ArrayIndexPointsTo(?baseheap:HeapAllocation, ?heap:HeapAllocation) -.output ArrayIndexPointsTo -.decl Reachable(?method:Method) -.output Reachable -Assign(?actual, ?formal) :- - CallGraphEdge(?invocation, ?method), - FormalParam(?index, ?method, ?formal), - ActualParam(?index, ?invocation, ?actual). -Assign(?return, ?local) :- - CallGraphEdge(?invocation, ?method), - ReturnVar(?return, ?method), - AssignReturnValue(?invocation, ?local). -VarPointsTo(?heap, ?var) :- - AssignHeapAllocation(?heap, ?var, ?inMethod), - Reachable(?inMethod). -VarPointsTo(?heap, ?to) :- - Assign(?from, ?to), - VarPointsTo(?heap, ?from). -VarPointsTo(?heap, ?to) :- - Reachable(?inmethod), - AssignLocal(?from, ?to, ?inmethod), - VarPointsTo(?heap, ?from). - .plan 1:(3,2,1) -VarPointsTo(?heap, ?to) :- - Reachable(?method), - AssignCast(?type, ?from, ?to, ?method), - basic.SupertypeOf(?type, ?heaptype), - HeapAllocation_Type(?heap, ?heaptype), - VarPointsTo(?heap, ?from). - .plan 1:(5,2,1,4,3) -ArrayIndexPointsTo(?baseheap, ?heap) :- - Reachable(?inmethod), - StoreArrayIndex(?from, ?base, ?inmethod), - VarPointsTo(?baseheap, ?base), - VarPointsTo(?heap, ?from), - HeapAllocation_Type(?heap, ?heaptype), - HeapAllocation_Type(?baseheap, ?baseheaptype), - ComponentType(?baseheaptype, ?componenttype), - basic.SupertypeOf(?componenttype, ?heaptype). -VarPointsTo(?heap, ?to) :- - Reachable(?inmethod), - LoadArrayIndex(?base, ?to, ?inmethod), - VarPointsTo(?baseheap, ?base), - ArrayIndexPointsTo(?baseheap, ?heap), - Var_Type(?to, ?type), - HeapAllocation_Type(?baseheap, ?baseheaptype), - ComponentType(?baseheaptype, ?basecomponenttype), - basic.SupertypeOf(?type, ?basecomponenttype). - .plan 1:(3,2,1,4,5,6,7,8), 2:(4,3,2,1,5,6,7,8) -VarPointsTo(?heap, ?to) :- - Reachable(?inmethod), - LoadInstanceField(?base, ?signature, ?to, ?inmethod), - VarPointsTo(?baseheap, ?base), - InstanceFieldPointsTo(?heap, ?signature, ?baseheap). - .plan 1:(3,2,1,4), 2:(4,2,1,3) -InstanceFieldPointsTo(?heap, ?fld, ?baseheap) :- - Reachable(?inmethod), - StoreInstanceField(?from, ?base, ?fld, ?inmethod), - VarPointsTo(?heap, ?from), - VarPointsTo(?baseheap, ?base). - .plan 1:(3,2,1,4), 2:(4,2,1,3) -VarPointsTo(?heap, ?to) :- - Reachable(?inmethod), - LoadStaticField(?fld, ?to, ?inmethod), - StaticFieldPointsTo(?heap, ?fld). -StaticFieldPointsTo(?heap, ?fld) :- - Reachable(?inmethod), - StoreStaticField(?from, ?fld, ?inmethod), - VarPointsTo(?heap, ?from). -VarPointsTo(?heap, ?this) :- - Reachable(?inMethod), - Instruction_Method(?invocation, ?inMethod), - VirtualMethodInvocation_Base(?invocation, ?base), - VarPointsTo(?heap, ?base), - HeapAllocation_Type(?heap, ?heaptype), - VirtualMethodInvocation_SimpleName(?invocation, ?simplename), - VirtualMethodInvocation_Descriptor(?invocation, ?descriptor), - basic.MethodLookup(?simplename, ?descriptor, ?heaptype, ?toMethod), - ThisVar(?toMethod, ?this). - .plan 1:(4,3,2,1,5,6,7,8,9) -Reachable(?toMethod), -CallGraphEdge(?invocation, ?toMethod) :- - Reachable(?inMethod), - Instruction_Method(?invocation, ?inMethod), - VirtualMethodInvocation_Base(?invocation, ?base), - VarPointsTo(?heap, ?base), - HeapAllocation_Type(?heap, ?heaptype), - VirtualMethodInvocation_SimpleName(?invocation, ?simplename), - VirtualMethodInvocation_Descriptor(?invocation, ?descriptor), - basic.MethodLookup(?simplename, ?descriptor, ?heaptype, ?toMethod). - .plan 1:(4,3,2,1,5,6,7,8) -Reachable(?tomethod), -CallGraphEdge(?invocation, ?tomethod) :- - Reachable(?inmethod), - StaticMethodInvocation(?invocation, ?tomethod, ?inmethod). -Reachable(?tomethod), -CallGraphEdge(?invocation, ?tomethod), -VarPointsTo(?heap, ?this) :- - Reachable(?inmethod), - Instruction_Method(?invocation, ?inmethod), - SpecialMethodInvocation_Base(?invocation, ?base), - VarPointsTo(?heap, ?base), - MethodInvocation_Method(?invocation, ?tomethod), - ThisVar(?tomethod, ?this). - .plan 1:(4,3,2,1,5,6) -Reachable(?method) :- - basic.MainMethodDeclaration(?method). diff --git a/doop/src/main.rs b/doop/src/main.rs deleted file mode 100644 index b7f85f499a..0000000000 --- a/doop/src/main.rs +++ /dev/null @@ -1,1242 +0,0 @@ -#![allow(non_snake_case, dead_code)] - -use std::collections::HashMap; -use std::rc::Rc; -use std::cell::RefCell; - -use timely::dataflow::{Scope, ProbeHandle}; -use timely::dataflow::scopes::child::Iterative as Child; - -use differential_dataflow::{AsCollection, VecCollection, Hashable}; -use differential_dataflow::ExchangeData as Data; -use differential_dataflow::lattice::Lattice; -use differential_dataflow::input::Input; -use differential_dataflow::operators::iterate::VecVariable; - -// Type aliases for differential execution. -type Time = u32; -type Iter = u32; -type Diff = isize; - -type Number = u32; -type Symbol = u32; -type Type = Symbol; -type Modifier = Symbol; -// type PrimitiveType = Type; -type ReferenceType = Type; -type ArrayType = ReferenceType; -type ClassType = ReferenceType; -type InterfaceType = ReferenceType; -type Field = Symbol; -type MethodDescriptor = Symbol; -type Method = Symbol; -type Var = Symbol; -type HeapAllocation = Symbol; -type Instruction = Symbol; -type FieldInstruction = Instruction; -// type LoadInstanceField_Insn = FieldInstruction; -// type StoreInstanceField_Insn = FieldInstruction; -// type LoadStaticField_Insn = FieldInstruction; -// type StoreStaticField_Insn = FieldInstruction; -// type ArrayInstruction = Instruction; -// type LoadArrayIndex_Insn = ArrayInstruction; -// type StoreArrayIndex_Insn = ArrayInstruction; -type AssignInstruction = Instruction; -// type AssignLocal_Insn = AssignInstruction; -// type AssignCast_Insn = AssignInstruction; -// type AssignHeapAllocation_Insn = AssignInstruction; -// type ReturnInstruction = Instruction; -// type ReturnNonvoid_Insn = ReturnInstruction; -type MethodInvocation = Instruction; -// type VirtualMethodInvocation_Insn = MethodInvocation; -// type StaticMethodInvocation_Insn = MethodInvocation; - - -/// Set-valued collection. -pub struct Relation<'a, G: Scope, D: Data+Hashable> where G::Timestamp : Lattice { - variable: VecVariable, D, Diff>, - current: VecCollection, D, Diff>, -} - -impl<'a, G: Scope, D: Data+Hashable> Relation<'a, G, D> where G::Timestamp : Lattice { - /// Creates a new variable initialized with `source`. - pub fn new(scope: &mut Child<'a, G, Iter>) -> Self { - Self::new_from(&::timely::dataflow::operators::generic::operator::empty(scope).as_collection()) - } - /// Creates a new variable initialized with `source`. - pub fn new_from(source: VecCollection, D, Diff>) -> Self { - use ::timely::order::Product; - let variable = VecVariable::new_from(source.clone(), Product::new(Default::default(), 1)); - Relation { - variable: variable, - current: source.clone(), - } - } - /// Concatenates `production` into the definition of the variable. - pub fn add_production(&mut self, production: VecCollection, D, Diff>) { - self.current = self.current.concat(production); - } - /// Finalizes the variable, connecting its recursive definition. - /// - /// Failure to call `complete` on a variable results in a non-recursively defined - /// collection, whose contents are just its initial `source` data. - pub fn complete(self) { - self.variable.set(self.current.threshold(|_,_| 1)); - } -} - -impl<'a, G: Scope, D: Data+Hashable> ::std::ops::Deref for Relation<'a, G, D> -where G::Timestamp : Lattice { - type Target = VecCollection, D, Diff>; - fn deref(&self) -> &VecCollection, D, Diff> { - &self.variable - } -} - -struct StringInterner { - vec: Vec, - map: HashMap -} - -impl StringInterner { - pub fn new() -> Self { StringInterner { vec: Vec::new(), map: HashMap::new() } } - // pub fn intern(&mut self, string: &str) -> Symbol { - // string.to_owned() - // } - pub fn intern(&mut self, string: &str) -> Symbol { - if !self.map.contains_key(string) { - let len = self.map.len() as Symbol; - self.vec.push(string.to_owned()); - self.map.insert(string.to_owned(), len); - len - } - else { - *self.map.get(string).unwrap() - } - } - pub fn concat(mut self, id1: Symbol, id2: Symbol) -> Symbol { - let string = self.vec[id1 as usize].to_owned() + &self.vec[id2 as usize]; - self.intern(&string) - } -} - -fn read_file(filename: &str) -> impl Iterator { - use ::std::io::{BufReader, BufRead}; - use ::std::fs::File; - let file = BufReader::new(File::open(filename).unwrap()); - file.lines() - .filter_map(|line| line.ok()) -} - - -fn load<'a>(filename: &str, interner: Rc>) -> impl Iterator>+'a { - use ::std::io::{BufReader, BufRead}; - use ::std::fs::File; - let file = BufReader::new(File::open(filename).unwrap()); - file.lines() - .filter_map(|line| line.ok()) - .map(move |line| { - let mut interner = interner.borrow_mut(); - line.split('\t') - .map(move |string| interner.intern(string)) - .collect() - }) -} - -fn load1<'a>(index: usize, prefix: &str, filename: &str, interner: Rc>) -> impl Iterator+'a { - read_file(&format!("{}{}", prefix, filename)) - .filter(move |_| index == 0) - .map(move |line| { - let mut interner = interner.borrow_mut(); - let mut elts = line.split('\t'); - (( - interner.intern(elts.next().unwrap()) - ), 0, 1) - }) -} - -fn load2<'a>(index: usize, prefix: &str, filename: &str, interner: Rc>) -> impl Iterator+'a { - read_file(&format!("{}{}", prefix, filename)) - .filter(move |_| index == 0) - .map(move |line| { - let mut interner = interner.borrow_mut(); - let mut elts = line.split('\t'); - (( - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - ), 0, 1) - }) -} - -fn load3<'a>(index: usize, prefix: &str, filename: &str, interner: Rc>) -> impl Iterator+'a { - read_file(&format!("{}{}", prefix, filename)) - .filter(move |_| index == 0) - .map(move |line| { - let mut interner = interner.borrow_mut(); - let mut elts = line.split('\t'); - (( - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - ), 0, 1) - }) -} - -fn load4<'a>(index: usize, prefix: &str, filename: &str, interner: Rc>) -> impl Iterator+'a { - read_file(&format!("{}{}", prefix, filename)) - .filter(move |_| index == 0) - .map(move |line| { - let mut interner = interner.borrow_mut(); - let mut elts = line.split('\t'); - (( - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - ), 0, 1) - }) -} - -fn load5<'a>(index: usize, prefix: &str, filename: &str, interner: Rc>) -> impl Iterator+'a { - read_file(&format!("{}{}", prefix, filename)) - .filter(move |_| index == 0) - .map(move |line| { - let mut interner = interner.borrow_mut(); - let mut elts = line.split('\t'); - (( - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - ), 0, 1) - }) -} - -fn load6<'a>(index: usize, prefix: &str, filename: &str, interner: Rc>) -> impl Iterator+'a { - read_file(&format!("{}{}", prefix, filename)) - .filter(move |_| index == 0) - .map(move |line| { - let mut interner = interner.borrow_mut(); - let mut elts = line.split('\t'); - (( - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - ), 0, 1) - }) -} - -fn load7<'a>(index: usize, prefix: &str, filename: &str, interner: Rc>) -> impl Iterator+'a { - read_file(&format!("{}{}", prefix, filename)) - .filter(move |_| index == 0) - .map(move |line| { - let mut interner = interner.borrow_mut(); - let mut elts = line.split('\t'); - (( - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - interner.intern(elts.next().unwrap()), - ), 0, 1) - }) -} - -fn main() { - - let mut args = std::env::args().skip(1); - let prefix = args.next().expect("must supply path to facts"); - let batch: Time = args.next().unwrap_or("1".to_string()).parse().expect("batch must be an integer"); - - timely::execute_from_args(std::env::args(), move |worker| { - - let timer = ::std::time::Instant::now(); - let index = worker.index(); - - let mut probe = ProbeHandle::new(); - - // For interning strings. - let interner = Rc::new(RefCell::new(StringInterner::new())); - - let mut inputs = ( - Vec::new(), - Vec::new(), - Vec::new(), - Vec::new(), - Vec::new(), - Vec::new(), - Vec::new(), - ); - - // let inputs = - worker.dataflow::(|scope| { - - // For loading inputs - let (input1, ClassType) = scope.new_collection_from_raw(load1(index, &prefix, "ClassType.facts", interner.clone())); inputs.0.push(input1); - let (input2, ArrayType) = scope.new_collection_from_raw(load1(index, &prefix, "ArrayType.facts", interner.clone())); inputs.0.push(input2); - let (input3, InterfaceType) = scope.new_collection_from_raw(load1(index, &prefix, "InterfaceType.facts", interner.clone())); inputs.0.push(input3); - // let Var_DeclaringMethod: VecCollection<_,(Symbol, Symbol)> = scope.new_collection_from_raw(load2(index, &prefix, "Var-DeclaringMethod.facts", interner.clone())).1; - let (input4, ApplicationClass) = scope.new_collection_from_raw(load1(index, &prefix, "ApplicationClass.facts", interner.clone())); inputs.0.push(input4); - let (input5, ThisVar) = scope.new_collection_from_raw(load2(index, &prefix, "ThisVar.facts", interner.clone())); inputs.1.push(input5); - - let (input6, _NormalHeap) = scope.new_collection_from_raw(load2(index, &prefix, "NormalHeap.facts", interner.clone())); inputs.1.push(input6); - let (input7, _StringConstant) = scope.new_collection_from_raw(load1(index, &prefix, "StringConstant.facts", interner.clone())); inputs.0.push(input7); - let (input8, _AssignHeapAllocation) = scope.new_collection_from_raw(load6(index, &prefix, "AssignHeapAllocation.facts", interner.clone())); inputs.5.push(input8); - let (input9, _AssignLocal) = scope.new_collection_from_raw(load5(index, &prefix, "AssignLocal.facts", interner.clone())); inputs.4.push(input9); - let (input10, _AssignCast) = scope.new_collection_from_raw(load6(index, &prefix, "AssignCast.facts", interner.clone())); inputs.5.push(input10); - let (input11, _Field) = scope.new_collection_from_raw(load4(index, &prefix, "Field.facts", interner.clone())); inputs.3.push(input11); - let (input12, _StaticMethodInvocation) = scope.new_collection_from_raw(load4(index, &prefix, "StaticMethodInvocation.facts", interner.clone())); inputs.3.push(input12); - let (input13, _SpecialMethodInvocation) = scope.new_collection_from_raw(load5(index, &prefix, "SpecialMethodInvocation.facts", interner.clone())); inputs.4.push(input13); - let (input14, _VirtualMethodInvocation) = scope.new_collection_from_raw(load5(index, &prefix, "VirtualMethodInvocation.facts", interner.clone())); inputs.4.push(input14); - let (input15, _Method) = scope.new_collection_from_raw(load7(index, &prefix, "Method.facts", interner.clone())); inputs.6.push(input15); - let (input16, _StoreInstanceField) = scope.new_collection_from_raw(load6(index, &prefix, "StoreInstanceField.facts", interner.clone())); inputs.5.push(input16); - let (input17, _LoadInstanceField) = scope.new_collection_from_raw(load6(index, &prefix, "LoadInstanceField.facts", interner.clone())); inputs.5.push(input17); - let (input18, _StoreStaticField) = scope.new_collection_from_raw(load5(index, &prefix, "StoreStaticField.facts", interner.clone())); inputs.4.push(input18); - let (input19, _LoadStaticField) = scope.new_collection_from_raw(load5(index, &prefix, "LoadStaticField.facts", interner.clone())); inputs.4.push(input19); - let (input20, _StoreArrayIndex) = scope.new_collection_from_raw(load5(index, &prefix, "StoreArrayIndex.facts", interner.clone())); inputs.4.push(input20); - let (input21, _LoadArrayIndex) = scope.new_collection_from_raw(load5(index, &prefix, "LoadArrayIndex.facts", interner.clone())); inputs.4.push(input21); - let (input22, _Return) = scope.new_collection_from_raw(load4(index, &prefix, "Return.facts", interner.clone())); inputs.3.push(input22); - - // TODO: Loaded as an input. - let (input23, DirectSuperclass) = scope.new_collection_from_raw(load2(index, &prefix, "DirectSuperclass.facts", interner.clone())); inputs.1.push(input23); - let (input24, DirectSuperinterface) = scope.new_collection_from_raw(load2(index, &prefix, "DirectSuperinterface.facts", interner.clone())); inputs.1.push(input24); - let (input25, MainClass) = scope.new_collection_from_raw(load1(index, &prefix, "MainClass.facts", interner.clone())); inputs.0.push(input25); - let (input26, Method_Modifier) = scope.new_collection_from_raw(load2(index, &prefix, "Method-Modifier.facts", interner.clone())); inputs.1.push(input26); - let (input27, FormalParam) = scope.new_collection_from_raw(load3(index, &prefix, "FormalParam.facts", interner.clone())); inputs.2.push(input27); - let (input28, Var_Type) = scope.new_collection_from_raw(load2(index, &prefix, "Var-Type.facts", interner.clone())); inputs.1.push(input28); - let (input29, ComponentType) = scope.new_collection_from_raw(load2(index, &prefix, "ComponentType.facts", interner.clone())); inputs.1.push(input29); - let (input30, AssignReturnValue) = scope.new_collection_from_raw(load2(index, &prefix, "AssignReturnValue.facts", interner.clone())); inputs.1.push(input30); - let (input31, ActualParam) = scope.new_collection_from_raw(load3(index, &prefix, "ActualParam.facts", interner.clone())); inputs.2.push(input31); - - // Main schema - let isType: VecCollection<_,Type> = - ClassType - .concat(ArrayType) - .concat(InterfaceType) - .concat(ApplicationClass) - .concat(_NormalHeap.map(|(_id,ty)| ty)); - - let isReferenceType: VecCollection<_,ReferenceType> = - ClassType - .concat(ArrayType) - .concat(InterfaceType) - .concat(ApplicationClass); - - let Field_DeclaringType = _Field.map(|(sig,dec,_,_)| (sig,dec)); - let Method_DeclaringType = _Method.map(|(meth,_,_,dec,_,_,_)| (meth,dec)); - let _Method_ReturnType = _Method.map(|(meth,_,_,_,ret,_,_)| (meth,ret)); - let Method_SimpleName = _Method.map(|(meth,name,_,_,_,_,_)| (meth,name)); - let _Method_Params = _Method.map(|(meth,_,params,_,_,_,_)| (meth,params)); - let interner2 = interner.clone(); - let Method_Descriptor = _Method.map(move |(meth,_,params,_,ret,_,_)| (meth, interner2.borrow_mut().concat(ret, params))); - - let temp1 = interner.borrow_mut().intern("java.lang.String"); - let temp1b = interner.borrow_mut().intern("java.lang.String"); - let temp2 = interner.borrow_mut().intern("<
>"); - let temp3 = interner.borrow_mut().intern("<
>"); - let temp4 = interner.borrow_mut().intern("java.lang.String[]"); - let HeapAllocation_Type = - _NormalHeap - .concat(_StringConstant.map(move |s| (s, temp1.clone()))) - .concat(scope.new_collection_from_raw(Some(((temp3.clone(), temp4.clone()), 0, 1))).1) - .concat(scope.new_collection_from_raw(Some(((temp2.clone(), temp1b.clone()), 0, 1))).1); - - // NOTE: Unused - // let MainMethodArgArray: VecCollection<_,HeapAllocation> = scope.new_collection_from_raw(Some(temp3.clone())).1; - // NOTE: Unused - // let MainMethodArgArrayContent: VecCollection<_,HeapAllocation> = scope.new_collection_from_raw(Some(temp2.clone())).1; - - let Instruction_Method = //: VecCollection<_,(Instruction, Method)> = - _AssignHeapAllocation.map(|x| (x.0, x.4)) - .concat(_AssignLocal.map(|x| (x.0, x.4))) - .concat(_AssignCast.map(|x| (x.0, x.5))) - .concat(_StaticMethodInvocation.map(|x| (x.0, x.3))) - .concat(_SpecialMethodInvocation.map(|x| (x.0, x.4))) - .concat(_VirtualMethodInvocation.map(|x| (x.0, x.4))) - .concat(_StoreInstanceField.map(|x| (x.0, x.5))) - .concat(_LoadInstanceField.map(|x| (x.0, x.5))) - .concat(_StoreStaticField.map(|x| (x.0, x.4))) - .concat(_LoadStaticField.map(|x| (x.0, x.4))) - .concat(_StoreArrayIndex.map(|x| (x.0, x.4))) - .concat(_LoadArrayIndex.map(|x| (x.0, x.4))) - .concat(_Return.map(|x| (x.0, x.3))) - .distinct() - .arrange_by_key(); - - let isVirtualMethodInvocation_Insn = _VirtualMethodInvocation.map(|x| x.0); - let isStaticMethodInvocation_Insn = _StaticMethodInvocation.map(|x| x.0); - - let FieldInstruction_Signature: VecCollection<_,(FieldInstruction, Field)> = - _StoreInstanceField.map(|x| (x.0, x.4)) - .concat(_LoadInstanceField.map(|x| (x.0, x.4))) - .concat(_StoreStaticField.map(|x| (x.0, x.3))) - .concat(_LoadStaticField.map(|x| (x.0, x.3))); - - let LoadInstanceField_Base = _LoadInstanceField.map(|x| (x.0, x.3)); - let LoadInstanceField_To = _LoadInstanceField.map(|x| (x.0, x.2)); - let StoreInstanceField_From = _StoreInstanceField.map(|x| (x.0, x.2)); - let StoreInstanceField_Base = _StoreInstanceField.map(|x| (x.0, x.3)); - let LoadStaticField_To = _LoadStaticField.map(|x| (x.0, x.2)); - let StoreStaticField_From = _StoreStaticField.map(|x| (x.0, x.2)); - - let LoadArrayIndex_Base = _LoadArrayIndex.map(|x| (x.0, x.3)); - let LoadArrayIndex_To = _LoadArrayIndex.map(|x| (x.0, x.2)); - let StoreArrayIndex_From = _StoreArrayIndex.map(|x| (x.0, x.2)); - let StoreArrayIndex_Base = _StoreArrayIndex.map(|x| (x.0, x.3)); - - let AssignInstruction_To: VecCollection<_,(AssignInstruction, Var)> = - _AssignHeapAllocation.map(|x| (x.0, x.3)) - .concat(_AssignLocal.map(|x| (x.0, x.3))) - .concat(_AssignCast.map(|x| (x.0, x.3))); - - let AssignCast_From = _AssignCast.map(|x| (x.0, x.2)); - let AssignCast_Type = _AssignCast.map(|x| (x.0, x.4)); - let AssignLocal_From = _AssignLocal.map(|x| (x.0, x.2)); - let AssignHeapAllocation_Heap = _AssignHeapAllocation.map(|x| (x.0, x.2)); - - let ReturnNonvoid_Var = _Return.map(|x| (x.0, x.2)); - let MethodInvocation_Method: VecCollection<_,(MethodInvocation, Method)> = - _StaticMethodInvocation.map(|x| (x.0, x.2)) - .concat(_SpecialMethodInvocation.map(|x| (x.0, x.2))) - .concat(_VirtualMethodInvocation.map(|x| (x.0, x.2))); - - let VirtualMethodInvocation_Base = _VirtualMethodInvocation.map(|x| (x.0, x.3)); - let SpecialMethodInvocation_Base = _SpecialMethodInvocation.map(|x| (x.0, x.3)); - // NOTE: Unused - // let MethodInvocation_Base = VirtualMethodInvocation_Base.concat(SpecialMethodInvocation_Base); - - // Fat schema - - // LoadInstanceField(?base, ?sig, ?to, ?inmethod) :- - // Instruction_Method(?insn, ?inmethod), - // LoadInstanceField_Base(?insn, ?base), - // FieldInstruction_Signature(?insn, ?sig), - // LoadInstanceField_To(?insn, ?to). - let LoadInstanceField: VecCollection<_,(Var, Field, Var, Method)> = - Instruction_Method - .as_vecs() - .join(LoadInstanceField_Base) - .join(FieldInstruction_Signature) - .join(LoadInstanceField_To) - .map(|(_insn, (((inmethod, base), sig), to))| (base, sig, to, inmethod)); - - // StoreInstanceField(?from, ?base, ?sig, ?inmethod) :- - // Instruction_Method(?insn, ?inmethod), - // StoreInstanceField_From(?insn, ?from), - // StoreInstanceField_Base(?insn, ?base), - // FieldInstruction_Signature(?insn, ?sig). - let StoreInstanceField: VecCollection<_,(Var, Var, Field, Method)> = - Instruction_Method - .as_vecs() - .join(StoreInstanceField_From) - .join(StoreInstanceField_Base) - .join(FieldInstruction_Signature) - .map(|(_insn, (((inmethod, from), base), sig))| (from, base, sig, inmethod)); - - // LoadStaticField(?sig, ?to, ?inmethod) :- - // Instruction_Method(?insn, ?inmethod), - // FieldInstruction_Signature(?insn, ?sig), - // LoadStaticField_To(?insn, ?to). - let LoadStaticField: VecCollection<_,(Field, Var, Method)> = - Instruction_Method - .as_vecs() - .join(FieldInstruction_Signature) - .join(LoadStaticField_To) - .map(|(_insn, ((inmethod, sig), to))| (sig, to, inmethod)); - - // StoreStaticField(?from, ?sig, ?inmethod) :- - // Instruction_Method(?insn, ?inmethod), - // StoreStaticField_From(?insn, ?from), - // FieldInstruction_Signature(?insn, ?sig). - let StoreStaticField: VecCollection<_,(Var, Field, Method)> = - Instruction_Method - .as_vecs() - .join(StoreStaticField_From) - .join(FieldInstruction_Signature) - .map(|(_insn, ((inmethod, from), sig))| (from, sig, inmethod)); - - // LoadArrayIndex(?base, ?to, ?inmethod) :- - // Instruction_Method(?insn, ?inmethod), - // LoadArrayIndex_Base(?insn, ?base), - // LoadArrayIndex_To(?insn, ?to). - let LoadArrayIndex: VecCollection<_,(Var, Var, Method)> = - Instruction_Method - .as_vecs() - .join(LoadArrayIndex_Base) - .join(LoadArrayIndex_To) - .map(|(_insn, ((inmethod, base), to))| (base, to, inmethod)); - - // StoreArrayIndex(?from, ?base, ?inmethod) :- - // Instruction_Method(?insn, ?inmethod), - // StoreArrayIndex_From(?insn, ?from), - // StoreArrayIndex_Base(?insn, ?base). - let StoreArrayIndex: VecCollection<_,(Var, Var, Method)> = - Instruction_Method - .as_vecs() - .join(StoreArrayIndex_From) - .join(StoreArrayIndex_Base) - .map(|(_insn, ((inmethod, from), base))| (from, base, inmethod)); - - // AssignCast(?type, ?from, ?to, ?inmethod) :- - // Instruction_Method(?insn, ?inmethod), - // AssignCast_From(?insn, ?from), - // AssignInstruction_To(?insn, ?to), - // AssignCast_Type(?insn, ?type). - let AssignCast: VecCollection<_,(Type, Var, Var, Method)> = - Instruction_Method - .as_vecs() - .join(AssignCast_From) - .join(AssignInstruction_To) - .join(AssignCast_Type) - .map(|(_insn, (((inmethod, from), to), ty))| (ty, from, to, inmethod)); - - // AssignLocal(?from, ?to, ?inmethod) :- - // AssignInstruction_To(?insn, ?to), - // Instruction_Method(?insn, ?inmethod), - // AssignLocal_From(?insn, ?from). - let AssignLocal: VecCollection<_,(Var, Var, Method)> = - Instruction_Method - .as_vecs() - .join(AssignInstruction_To) - .join(AssignLocal_From) - .map(|(_insn, ((inmethod, to), from))| (from, to, inmethod)); - - // AssignHeapAllocation(?heap, ?to, ?inmethod) :- - // Instruction_Method(?insn, ?inmethod), - // AssignHeapAllocation_Heap(?insn, ?heap), - // AssignInstruction_To(?insn, ?to). - let AssignHeapAllocation: VecCollection<_,(HeapAllocation, Var, Method)> = - Instruction_Method - .as_vecs() - .join(AssignHeapAllocation_Heap) - .join(AssignInstruction_To) - .map(|(_insn, ((inmethod, heap), to))| (heap, to, inmethod)); - - // ReturnVar(?var, ?method) :- - // Instruction_Method(?insn, ?method), - // ReturnNonvoid_Var(?insn, ?var). - let ReturnVar: VecCollection<_,(Var, Method)> = - Instruction_Method - .as_vecs() - .join(ReturnNonvoid_Var) - .map(|(_insn, (inmethod, var))| (var, inmethod)); - - // StaticMethodInvocation(?invocation, ?signature, ?inmethod) :- - // isStaticMethodInvocation_Insn(?invocation), - // Instruction_Method(?invocation, ?inmethod), - // MethodInvocation_Method(?invocation, ?signature). - let StaticMethodInvocation: VecCollection<_,(MethodInvocation, Method, Method)> = - Instruction_Method - .join_core(isStaticMethodInvocation_Insn.arrange_by_self(), |k,v,_| [(k.clone(), v.clone())]) - .join(MethodInvocation_Method) - .map(|(invocation, (inmethod, sig))| (invocation, sig, inmethod)); - - // VirtualMethodInvocation_SimpleName(?invocation, ?simplename), - // VirtualMethodInvocation_Descriptor(?invocation, ?descriptor) :- - // isVirtualMethodInvocation_Insn(?invocation), - // MethodInvocation_Method(?invocation, ?signature), - // Method_SimpleName(?signature, ?simplename), - // Method_Descriptor(?signature, ?descriptor). - let VirtualTemp = - MethodInvocation_Method - .semijoin(isVirtualMethodInvocation_Insn) - .map(|(invocation, signature)| (signature, invocation)); - let VirtualMethodInvocation_SimpleName = - VirtualTemp - .join_map(Method_SimpleName, |_sig, inv, name| (inv.clone(), name.clone())); - let VirtualMethodInvocation_Descriptor = - VirtualTemp - .join_map(Method_Descriptor, |_sig, inv, desc| (inv.clone(), desc.clone())); - - let (MethodImplemented, MainMethodDeclaration, MethodLookup, SupertypeOf) = scope.scoped("Basic", |scope| { - - // Import some things - let isType = isType.enter(scope); - let isReferenceType = isReferenceType.enter(scope); - let ClassType = ClassType.enter(scope); - let ArrayType = ArrayType.enter(scope); - let InterfaceType = InterfaceType.enter(scope); - let ComponentType = ComponentType.enter(scope); - let DirectSuperclass = DirectSuperclass.enter(scope); - let DirectSuperinterface = DirectSuperinterface.enter(scope); - let Method_SimpleName = Method_SimpleName.enter(scope); - let Method_Descriptor = Method_Descriptor.enter(scope); - let Method_DeclaringType = Method_DeclaringType.enter(scope); - let Method_Modifier = Method_Modifier.enter(scope); - let MainClass = MainClass.enter(scope); - // let LoadStaticField = LoadStaticField.enter(scope); - // let HeapAllocation_Type = HeapAllocation_Type.enter(scope); - // let AssignHeapAllocation = AssignHeapAllocation.enter(scope); - // let Instruction_Method = Instruction_Method.enter(scope); - // let isStaticMethodInvocation_Insn = isStaticMethodInvocation_Insn.enter(scope); - // let MethodInvocation_Method = MethodInvocation_Method.enter(scope); - // let StoreStaticField = StoreStaticField.enter(scope); - // let Field_DeclaringType = Field_DeclaringType.enter(scope); - // let StoreArrayIndex = StoreArrayIndex.enter(scope); - // let FormalParam = FormalParam.enter(scope); - // let ActualParam = ActualParam.enter(scope); - // let AssignReturnValue = AssignReturnValue.enter(scope); - // let ReturnVar = ReturnVar.enter(scope); - // let StoreInstanceField = StoreInstanceField.enter(scope); - // let StaticMethodInvocation = StaticMethodInvocation.enter(scope); - // let VirtualMethodInvocation_Base = VirtualMethodInvocation_Base.enter(scope); - // let VirtualMethodInvocation_SimpleName = VirtualMethodInvocation_SimpleName.enter(scope); - // let VirtualMethodInvocation_Descriptor = VirtualMethodInvocation_Descriptor.enter(scope); - // let SpecialMethodInvocation_Base = SpecialMethodInvocation_Base.enter(scope); - // let ThisVar = ThisVar.enter(scope); - // let AssignLocal = AssignLocal.enter(scope); - // let AssignCast = AssignCast.enter(scope); - // let LoadArrayIndex = LoadArrayIndex.enter(scope); - // let Var_Type = Var_Type.enter(scope); - // let LoadInstanceField = LoadInstanceField.enter(scope); - - // Basic component - let mut MethodLookup = Relation::<_,(Symbol, MethodDescriptor, Type, Method)>::new(scope); - let mut Subclass = Relation::<_,(Type, Type)>::new(scope); - let mut Superinterface = Relation::<_,(Type, Type)>::new(scope); - let mut SubtypeOf = Relation::<_,(Type, Type)>::new(scope); - - // MethodImplemented(?simplename, ?descriptor, ?type, ?method) :- - // Method_SimpleName(?method, ?simplename), - // Method_Descriptor(?method, ?descriptor), - // Method_DeclaringType(?method, ?type), - // ! Method_Modifier("abstract", ?method). - let temp = interner.borrow_mut().intern("abstract"); - let MethodImplemented = - Method_SimpleName - .antijoin(Method_Modifier.filter(move |x| x.0 == temp).map(|x| x.1).distinct()) - .join(Method_Descriptor) - .join(Method_DeclaringType) - .map(|(method, ((simple, desc), ty))| (simple, desc, ty, method)) - .threshold(|_,_| 1 as Diff); - // .distinct(); - - // MethodLookup(?simplename, ?descriptor, ?type, ?method) :- - // MethodImplemented(?simplename, ?descriptor, ?type, ?method). - // MethodLookup(?simplename, ?descriptor, ?type, ?method) :- - // (DirectSuperclass(?type, ?supertype) ; DirectSuperinterface(?type, ?supertype)), - // MethodLookup(?simplename, ?descriptor, ?supertype, ?method), - // ! MethodImplemented(?simplename, ?descriptor, ?type, _). - let MethodLookupClone = MethodLookup.clone(); - MethodLookup.add_production(MethodImplemented); - MethodLookup.add_production( - DirectSuperclass.concat(DirectSuperinterface) - .map(|x| (x.1, x.0)) - .join(MethodLookupClone.map(|x| (x.2, (x.0, x.1, x.3)))) - .map(|(_superty, (ty, (name, desc, method)))| ((name, desc, ty), method)) - .antijoin(MethodImplemented.map(|x| (x.0, x.1, x.2)).threshold(|_,_| 1)) - .map(|((name, desc, ty), method)| (name, desc, ty, method)) - ); - - // MethodImplemented.map(|_| ()).consolidate().inspect(|x| println!("MI: {:?}", x)); - // MethodLookup.map(|_| ()).consolidate().inspect(|x| println!("ML: {:?}", x)); - - // DirectSubclass(?a, ?c) :- DirectSuperclass(?a, ?c). - let DirectSubclass = DirectSuperclass.clone(); // TODO: This seems badly named. - - // Subclass(?c, ?a) :- DirectSubclass(?a, ?c). - // Subclass(?c, ?a) :- Subclass(?b, ?a),DirectSubclass(?b, ?c). - let SubclassClone = Subclass.clone(); - Subclass.add_production(DirectSubclass.map(|x| (x.1, x.0))); - Subclass.add_production(SubclassClone.join_map(DirectSubclass, |_b, a, c| (c.clone(), a.clone()))); - - // Superclass(?c, ?a) :- Subclass(?a, ?c). - let _Superclass = Subclass.map(|x| (x.1, x.0)); - - // Superinterface(?k, ?c) :- DirectSuperinterface(?c, ?k). - // Superinterface(?k, ?c) :- DirectSuperinterface(?c, ?j),Superinterface(?k, ?j). - // Superinterface(?k, ?c) :- DirectSuperclass(?c, ?super),Superinterface(?k, ?super). - let SuperinterfaceClone = Superinterface.clone(); - Superinterface.add_production(DirectSuperinterface.map(|x| (x.1, x.0))); - Superinterface.add_production( - DirectSuperinterface - .map(|x| (x.1, x.0)) - .join(SuperinterfaceClone.map(|x| (x.1, x.0))) - .map(|(_j, (c, k))| (k, c)) - ); - Superinterface.add_production( - DirectSuperclass - .map(|x| (x.1, x.0)) - .join(SuperinterfaceClone.map(|x| (x.1, x.0))) - .map(|(_j, (c, k))| (k, c)) - ); - - // SupertypeOf(?s, ?t) :- SubtypeOf(?t, ?s). - let SupertypeOf = SubtypeOf.map(|x| (x.1, x.0)); - - let SubtypeOfClone = SubtypeOf.clone(); - // SubtypeOf(?s, ?s) :- isClassType(?s). - SubtypeOf.add_production(ClassType.map(|x| (x.clone(), x))); - // SubtypeOf(?s, ?t) :- Subclass(?t, ?s). - SubtypeOf.add_production(Subclass.map(|x| (x.1, x.0))); - // SubtypeOf(?s, ?t) :- isClassType(?s),Superinterface(?t, ?s). - SubtypeOf.add_production(Superinterface.map(|x| (x.1, x.0)).semijoin(ClassType)); - // SubtypeOf(?s, ?t) :- isInterfaceType(?s),isType(?t),?t = "java.lang.Object". - let temp = interner.borrow_mut().intern("java.lang.Object"); - SubtypeOf.add_production(InterfaceType.map(move |x| (x, temp.clone()))); - // SubtypeOf(?s, ?s) :- isInterfaceType(?s). - SubtypeOf.add_production(InterfaceType.map(|x| (x.clone(), x))); - // SubtypeOf(?s, ?t) :- isInterfaceType(?s),Superinterface(?t, ?s). - SubtypeOf.add_production(Superinterface.map(|x| (x.1, x.0)).semijoin(InterfaceType)); - // SubtypeOf(?s, ?t) :- isArrayType(?s),isType(?t),?t = "java.lang.Object". - let temp = interner.borrow_mut().intern("java.lang.Object"); - SubtypeOf.add_production(ArrayType.map(move |x| (x, temp.clone()))); - // SubtypeOf(?s, ?t) :- - // ComponentType(?s, ?sc), - // ComponentType(?t, ?tc), - // isReferenceType(?sc), - // isReferenceType(?tc), - // SubtypeOf(?sc, ?tc). - SubtypeOf.add_production( - ComponentType.map(|x| (x.1, x.0)) - .semijoin(isReferenceType) - .join_map(SubtypeOfClone, |_sc, s, tc| (tc.clone(), s.clone())) - .semijoin(isReferenceType) - .join_map(ComponentType.map(|x| (x.1, x.0)), |_tc, s, t| (s.clone(), t.clone())) - ); - // SubtypeOf(?s, ?t) :- isArrayType(?s),isInterfaceType(?t),isType(?t),?t = "java.lang.Cloneable". - let temp = interner.borrow_mut().intern("java.lang.Cloneable"); - SubtypeOf.add_production(ArrayType.map(move |x| (x, temp.clone()))); - // SubtypeOf(?s, ?t) :- isArrayType(?s),isInterfaceType(?t),isType(?t),?t = "java.io.Serializable". - let temp = interner.borrow_mut().intern("java.io.Serializable"); - SubtypeOf.add_production(ArrayType.map(move |x| (x, temp.clone()))); - // SubtypeOf(?t, ?t) :- isType(?t). - SubtypeOf.add_production(isType.map(|x| (x.clone(), x))); - - // SubtypeOfDifferent(?s, ?t) :- SubtypeOf(?s, ?t),?s != ?t. - let _SubtypeOfDifferent = SubtypeOf.filter(|x| x.0 != x.1); - - // MainMethodDeclaration(?method) :- - // MainClass(?type), - // Method_DeclaringType(?method, ?type), - // ?method != "", - // ?method != "", - // ?method != "", - // Method_SimpleName(?method, "main"), - // Method_Descriptor(?method, "void(java.lang.String[])"), - // Method_Modifier("public", ?method), - // Method_Modifier("static", ?method). - let temp1 = interner.borrow_mut().intern(""); - let temp2 = interner.borrow_mut().intern(""); - let temp3 = interner.borrow_mut().intern(""); - let temp4 = interner.borrow_mut().intern("main"); - let temp5 = interner.borrow_mut().intern("void(java.lang.String[])"); - let temp6 = interner.borrow_mut().intern("public"); - let temp7 = interner.borrow_mut().intern("static"); - let MainMethodDeclaration = - Method_DeclaringType - .map(|x| (x.1, x.0)) - .semijoin(MainClass) - .map(|x| (x.1, ())) - .filter(move |x| x.0 != temp1 && x.0 != temp2 && x.0 != temp3) - .semijoin(Method_SimpleName.filter(move |x| x.1 == temp4).map(|x| x.0)) - .semijoin(Method_Descriptor.filter(move |x| x.1 == temp5).map(|x| x.0)) - .semijoin(Method_Modifier.filter(move |x| x.0 == temp6).map(|x| x.1)) - .semijoin(Method_Modifier.filter(move |x| x.0 == temp7).map(|x| x.1)) - .map(|x| x.0); - - let result = (MethodImplemented.leave(), MainMethodDeclaration.leave(), MethodLookup.leave(), SupertypeOf.leave()); - - MethodLookup.complete(); - Subclass.complete(); - Superinterface.complete(); - SubtypeOf.complete(); - - result - }); - - let (_st, _ic, _reachable, _varpoints, _callgraph) = scope.scoped("Iteration", |scope| { - - // Import some things - // let isType = isType.enter(scope); - // let isReferenceType = isReferenceType.enter(scope); - // let ClassType = ClassType.enter(scope); - // let ArrayType = ArrayType.enter(scope); - // let InterfaceType = InterfaceType.enter(scope); - let ComponentType = ComponentType.enter(scope); - let DirectSuperclass = DirectSuperclass.enter(scope); - let DirectSuperinterface = DirectSuperinterface.enter(scope); - // let Method_SimpleName = Method_SimpleName.enter(scope); - // let Method_Descriptor = Method_Descriptor.enter(scope); - let Method_DeclaringType = Method_DeclaringType.enter(scope); - // let Method_Modifier = Method_Modifier.enter(scope); - // let MainClass = MainClass.enter(scope); - let LoadStaticField = LoadStaticField.enter(scope); - let HeapAllocation_Type = HeapAllocation_Type.enter(scope); - let AssignHeapAllocation = AssignHeapAllocation.enter(scope); - let Instruction_Method = Instruction_Method.enter(scope); - let isStaticMethodInvocation_Insn = isStaticMethodInvocation_Insn.enter(scope); - let MethodInvocation_Method = MethodInvocation_Method.enter(scope); - let StoreStaticField = StoreStaticField.enter(scope); - let Field_DeclaringType = Field_DeclaringType.enter(scope); - let StoreArrayIndex = StoreArrayIndex.enter(scope); - let FormalParam = FormalParam.enter(scope); - let ActualParam = ActualParam.enter(scope); - let AssignReturnValue = AssignReturnValue.enter(scope); - let ReturnVar = ReturnVar.enter(scope); - let StoreInstanceField = StoreInstanceField.enter(scope); - let StaticMethodInvocation = StaticMethodInvocation.enter(scope); - let VirtualMethodInvocation_Base = VirtualMethodInvocation_Base.enter(scope); - let VirtualMethodInvocation_SimpleName = VirtualMethodInvocation_SimpleName.enter(scope); - let VirtualMethodInvocation_Descriptor = VirtualMethodInvocation_Descriptor.enter(scope); - let SpecialMethodInvocation_Base = SpecialMethodInvocation_Base.enter(scope); - let ThisVar = ThisVar.enter(scope); - let AssignLocal = AssignLocal.enter(scope); - let AssignCast = AssignCast.enter(scope); - let LoadArrayIndex = LoadArrayIndex.enter(scope); - let Var_Type = Var_Type.enter(scope); - let LoadInstanceField = LoadInstanceField.enter(scope); - - let MethodImplemented = MethodImplemented.enter(scope); - let MainMethodDeclaration = MainMethodDeclaration.enter(scope); - let MethodLookup = MethodLookup.enter(scope); - let SupertypeOf = SupertypeOf.enter(scope); - - // Required by all - let mut Reachable = Relation::<_,Method>::new(scope); - - // NOTE: Common subexpression. - let Reachable_Invocation = - Instruction_Method - .as_collection(|inv,meth| (meth.clone(), inv.clone())) - // .map(|(inv,meth)| (meth,inv)) - .semijoin(Reachable) - .map(|(_meth,inv)| (inv, ())); - - // // NOTE: Cheating, but to test what is broken. - // let Reachable = ReachableFinal.clone(); - - // Class initialization - let mut InitializedClass = Relation::<_,Type>::new(scope); - - // ClassInitializer(?type, ?method) :- basic.MethodImplemented("", "void()", ?type, ?method). - let temp1 = interner.borrow_mut().intern(""); - let temp2 = interner.borrow_mut().intern("void()"); - let ClassInitializer = - MethodImplemented - .filter(move |x| x.0 == temp1 && x.1 == temp2) - .map(|x| (x.2, x.3)) - .distinct(); - - let InitializedClassClone = InitializedClass.clone(); - // InitializedClass(?superclass) :- InitializedClass(?class),DirectSuperclass(?class, ?superclass). - InitializedClass.add_production(DirectSuperclass.semijoin(InitializedClassClone).map(|x| x.1)); - // InitializedClass(?superinterface) :- InitializedClass(?classOrInterface),DirectSuperinterface(?classOrInterface, ?superinterface). - InitializedClass.add_production(DirectSuperinterface.semijoin(InitializedClassClone).map(|x| x.1)); - // InitializedClass(?class) :- basic.MainMethodDeclaration(?method),Method_DeclaringType(?method, ?class). - InitializedClass.add_production(Method_DeclaringType.semijoin(MainMethodDeclaration).map(|x| x.1)); - // InitializedClass(?class) :- - // Reachable(?inmethod), - // AssignHeapAllocation(?heap, _, ?inmethod), - // HeapAllocation_Type(?heap, ?class). - InitializedClass.add_production( - AssignHeapAllocation - .map(|(heap,_,inmethod)| (inmethod,heap)) - .semijoin(Reachable) - .map(|(_inmethod,heap)| (heap, ())) - .join_map(HeapAllocation_Type, |_,(),class| class.clone()) - ); - // InitializedClass(?class) :- - // Reachable(?inmethod), - // Instruction_Method(?invocation, ?inmethod), - // isStaticMethodInvocation_Insn(?invocation), - // MethodInvocation_Method(?invocation, ?signature), - // Method_DeclaringType(?signature, ?class). - InitializedClass.add_production( - Reachable_Invocation - .semijoin(isStaticMethodInvocation_Insn) - .join_map(MethodInvocation_Method, |_,(),sig| (sig.clone(), ())) - .join_map(Method_DeclaringType, |_,(),class| class.clone()) - ); - - // InitializedClass(?classOrInterface) :- - // Reachable(?inmethod), - // StoreStaticField(_, ?signature, ?inmethod), - // Field_DeclaringType(?signature, ?classOrInterface). - InitializedClass.add_production( - StoreStaticField - .map(|(_,sig,meth)| (meth,sig)) - .semijoin(Reachable) - .map(|(_meth,sig)| (sig, ())) - .join_map(Field_DeclaringType, |_,(),class| class.clone()) - ); - // InitializedClass(?classOrInterface) :- - // Reachable(?inmethod), - // LoadStaticField(?signature, _, ?inmethod), - // Field_DeclaringType(?signature, ?classOrInterface). - InitializedClass.add_production( - LoadStaticField - .map(|x| (x.2, x.0)) - .semijoin(Reachable) - .map(|x| (x.1, ())) - .join_map(Field_DeclaringType, |_,_,class| class.clone()) - ); - - // Reachable(?clinit) :- InitializedClass(?class),ClassInitializer(?class, ?clinit). - Reachable.add_production(ClassInitializer.semijoin(InitializedClass).map(|x| x.1)); - - // Main (value-based) analysis - let mut Assign = Relation::<_,(Var, Var)>::new(scope); - let mut VarPointsTo = Relation::<_,(HeapAllocation, Var)>::new(scope); - let mut CallGraphEdge = Relation::<_,(MethodInvocation, Method)>::new(scope); - - let VarPointsToRev = VarPointsTo.map(|x| (x.1, x.0)).arrange_by_key(); - - // ArrayIndexPointsTo(?baseheap, ?heap) :- - // Reachable(?inmethod), - // StoreArrayIndex(?from, ?base, ?inmethod), - // VarPointsTo(?baseheap, ?base), - // VarPointsTo(?heap, ?from), - // HeapAllocation_Type(?heap, ?heaptype), - // HeapAllocation_Type(?baseheap, ?baseheaptype), - // ComponentType(?baseheaptype, ?componenttype), - // basic.SupertypeOf(?componenttype, ?heaptype). - let ArrayIndexPointsTo = - StoreArrayIndex - .map(|(f,b,m)| (m,(f,b))) - .semijoin(Reachable) - .map(|(_m,(f,b))| (b,f)) - .join_core(VarPointsToRev, |_b,f,bh| Some((f.clone(), bh.clone()))) - .join_core(VarPointsToRev, |_f,bh,h| Some((h.clone(), bh.clone()))) - .join(HeapAllocation_Type) - .map(|(h,(bh,ht))| (bh,(h,ht))) - .join(HeapAllocation_Type) - .map(|(bh,((h,ht),bht))| (bht,(h,ht,bh))) - .join(ComponentType) - .map(|(_,((h,ht,bh),ct))| ((ct,ht),(bh,h))) - .semijoin(SupertypeOf) - .map(|(_,(bh,h))| (bh,h)); - - // Assign(?actual, ?formal) :- - // CallGraphEdge(?invocation, ?method), - // FormalParam(?index, ?method, ?formal), - // ActualParam(?index, ?invocation, ?actual). - Assign.add_production( - CallGraphEdge - .map(|x| (x.1, x.0)) - .join(FormalParam.map(|x| (x.1, (x.0, x.2)))) - .map(|(_method, (inv, (index, formal)))| ((index, inv), formal)) - .join(ActualParam.map(|x| ((x.0, x.1), x.2))) - .map(|(_ind_inv, (formal, actual))| (actual, formal)) - ); - // Assign(?return, ?local) :- - // CallGraphEdge(?invocation, ?method), - // ReturnVar(?return, ?method), - // AssignReturnValue(?invocation, ?local). - Assign.add_production( - CallGraphEdge - .join(AssignReturnValue) - .map(|(_inv, (meth, local))| (meth, local)) - .join(ReturnVar.map(|x| (x.1, x.0))) - .map(|(_meth, (local, ret))| (ret, local)) - ); - - // InstanceFieldPointsTo(?heap, ?fld, ?baseheap) :- - // Reachable(?inmethod), - // StoreInstanceField(?from, ?base, ?fld, ?inmethod), - // VarPointsTo(?heap, ?from), - // VarPointsTo(?baseheap, ?base). - let InstanceFieldPointsTo = - StoreInstanceField - .map(|(from, base, fld, meth)| (meth, (from, base, fld))) - .semijoin(Reachable) - .map(|(_, (from, base, fld))| (from, (base, fld))) - .join_core(VarPointsToRev, |_from,(base,fld),heap| Some((base.clone(), (fld.clone(), heap.clone())))) - .join_core(VarPointsToRev, |_base,(fld,heap),baseheap| Some((heap.clone(), fld.clone(), baseheap.clone()))); - - // SIMPLIFICATION: ALL CGE DERIVATIONS PRODUCE REACHABILITY. - Reachable.add_production(CallGraphEdge.map(|x| x.1)); - - // CallGraphEdge(?invocation, ?toMethod) :- - // Reachable(?inMethod), - // Instruction_Method(?invocation, ?inMethod), - // VirtualMethodInvocation_Base(?invocation, ?base), - // VarPointsTo(?heap, ?base), - // HeapAllocation_Type(?heap, ?heaptype), - // VirtualMethodInvocation_SimpleName(?invocation, ?simplename), - // VirtualMethodInvocation_Descriptor(?invocation, ?descriptor), - // basic.MethodLookup(?simplename, ?descriptor, ?heaptype, ?toMethod). - CallGraphEdge.add_production( - Reachable_Invocation - .join(VirtualMethodInvocation_Base) - .map(|(inv, ((), base))| (base, inv)) - .join_core(VarPointsToRev, |_base,inv,heap| Some((heap.clone(), inv.clone()))) - .join(HeapAllocation_Type) - .map(|(_heap, (inv, heaptype))| (inv, heaptype)) - .join(VirtualMethodInvocation_SimpleName) - .join(VirtualMethodInvocation_Descriptor) - .map(|(inv, ((heaptype, simplename), descriptor))| ((simplename, descriptor, heaptype), inv)) - .join(MethodLookup.map(|(s,d,h,t)| ((s,d,h),t))) - .map(|(_, (inv, to))| (inv, to)) - ); - - // CallGraphEdge(?invocation, ?tomethod) :- - // Reachable(?inmethod), - // StaticMethodInvocation(?invocation, ?tomethod, ?inmethod). - CallGraphEdge.add_production( - StaticMethodInvocation - .map(|x| (x.2, (x.0, x.1))) - .semijoin(Reachable) - .map(|(_inmethod, (inv, to))| (inv, to)) - ); - - // CallGraphEdge(?invocation, ?tomethod), - // VarPointsTo(?heap, ?this) :- - // Reachable(?inmethod), - // Instruction_Method(?invocation, ?inmethod), - // SpecialMethodInvocation_Base(?invocation, ?base), - // VarPointsTo(?heap, ?base), - // MethodInvocation_Method(?invocation, ?tomethod), - // ThisVar(?tomethod, ?this). - let temp = - Reachable_Invocation - .join(SpecialMethodInvocation_Base) - .join(MethodInvocation_Method) - .map(|(inv, (((), base), tomethod))| (base, (inv,tomethod))) - .join_core(VarPointsToRev, |_base,(inv,tomethod),heap| Some((tomethod.clone(), (inv.clone(), heap.clone())))) - .join(ThisVar) - .map(|(tomethod, ((inv,heap),this))| (inv, tomethod, heap, this)); - - CallGraphEdge.add_production(temp.map(|(i,t,_,_)| (i,t))); - VarPointsTo.add_production(temp.map(|(_,_,h,t)| (h,t))); - - // Reachable(?method) :- basic.MainMethodDeclaration(?method). - Reachable.add_production(MainMethodDeclaration); - - // StaticFieldPointsTo(?heap, ?fld) :- - // Reachable(?inmethod), - // StoreStaticField(?from, ?fld, ?inmethod), - // VarPointsTo(?heap, ?from). - let StaticFieldPointsTo = - StoreStaticField - .map(|(from, fld, meth)| (meth, (from, fld))) - .semijoin(Reachable) - .map(|(_meth, (from, fld))| (from, fld)) - .join_core(VarPointsToRev, |_from,fld,heap| Some((heap.clone(), fld.clone()))); - - let VarPointsToClone = VarPointsTo.clone(); - // VarPointsTo(?heap, ?var) :- - // AssignHeapAllocation(?heap, ?var, ?inMethod), - // Reachable(?inMethod). - VarPointsTo.add_production( - AssignHeapAllocation - .map(|x| (x.2, (x.0, x.1))) - .semijoin(Reachable) - .map(|x| x.1) - ); - - // VarPointsTo(?heap, ?to) :- Assign(?from, ?to),VarPointsTo(?heap, ?from). - VarPointsTo.add_production( - VarPointsToClone - .map(|x| (x.1, x.0)) - .join(Assign) - .map(|(_from, (heap, to))| (heap, to)) - ); - - // VarPointsTo(?heap, ?to) :- - // Reachable(?inmethod), - // AssignLocal(?from, ?to, ?inmethod), - // VarPointsTo(?heap, ?from). - VarPointsTo.add_production( - AssignLocal - .map(|(from, to, meth)| (meth, (from, to))) - .semijoin(Reachable) - .map(|(_, (from, to))| (from, to)) - .join_core(VarPointsToRev, |_from,to,heap| Some((heap.clone(), to.clone()))) - ); - - // VarPointsTo(?heap, ?to) :- - // Reachable(?method), - // AssignCast(?type, ?from, ?to, ?method), - // basic.SupertypeOf(?type, ?heaptype), - // HeapAllocation_Type(?heap, ?heaptype), - // VarPointsTo(?heap, ?from). - VarPointsTo.add_production( - AssignCast - .map(|(ty,f,to,m)| (m, (ty,f,to))) - .semijoin(Reachable) - .map(|(_m, (ty,f,to))| (ty, (f,to))) - .join(SupertypeOf) - .map(|(_ty, ((f,to), heaptype))| (heaptype, (f,to))) - .join(HeapAllocation_Type.map(|x| (x.1, x.0))) - .map(|(_heaptype, ((f,to),heap))| ((heap, f), to)) - .semijoin(VarPointsToClone) - .map(|((heap, _f), to)| (heap, to)) - ); - - // VarPointsTo(?heap, ?to) :- - // Reachable(?inmethod), - // LoadArrayIndex(?base, ?to, ?inmethod), - // VarPointsTo(?baseheap, ?base), - // ArrayIndexPointsTo(?baseheap, ?heap), - // Var_Type(?to, ?type), - // HeapAllocation_Type(?baseheap, ?baseheaptype), - // ComponentType(?baseheaptype, ?basecomponenttype), - // basic.SupertypeOf(?type, ?basecomponenttype). - VarPointsTo.add_production( - LoadArrayIndex - .map(|(b,t,m)| (m, (b,t))) - .semijoin(Reachable) - .map(|(_m, (b,t))| (b,t)) - .join_core(VarPointsToRev, |_base,to,baseheap| Some((baseheap.clone(), to.clone()))) - .join(ArrayIndexPointsTo) - .join(HeapAllocation_Type) - .map(|(_baseheap, ((to, heap), baseheaptype))| (to, (heap, baseheaptype))) - .join(Var_Type) - .map(|(to, ((h,bht),ty))| (bht,(to,h,ty))) - .join(ComponentType) - .map(|(_bht, ((to,h,ty),bct))| ((ty,bct), (to,h))) - .semijoin(SupertypeOf) - .map(|(_, (to,h))| (h,to)) - ); - - // VarPointsTo(?heap, ?to) :- - // Reachable(?inmethod), - // LoadInstanceField(?base, ?signature, ?to, ?inmethod), - // VarPointsTo(?baseheap, ?base), - // InstanceFieldPointsTo(?heap, ?signature, ?baseheap). - VarPointsTo.add_production( - LoadInstanceField - .map(|(b,s,t,m)| (m, (b,s,t))) - .semijoin(Reachable) - .map(|(_m, (b,s,t))| (b,(s,t))) - .join_core(VarPointsToRev, |_b,(s,t),bh| Some(((s.clone(),bh.clone()), t.clone()))) - .join(InstanceFieldPointsTo.map(|(h,s,bh)| ((s,bh),h))) - .map(|(_, (t,h))| (h,t)) - ); - - // VarPointsTo(?heap, ?to) :- - // Reachable(?inmethod), - // LoadStaticField(?fld, ?to, ?inmethod), - // StaticFieldPointsTo(?heap, ?fld). - VarPointsTo.add_production( - LoadStaticField - .map(|(f,t,m)| (m, (f,t))) - .semijoin(Reachable) - .map(|(_m,(f,t))| (f,t)) - .join(StaticFieldPointsTo.map(|x| (x.1, x.0))) - .map(|(_f,(t,h))| (h,t)) - ); - - // VarPointsTo(?heap, ?this) :- - // Reachable(?inMethod), - // Instruction_Method(?invocation, ?inMethod), - // VirtualMethodInvocation_Base(?invocation, ?base), - // VarPointsTo(?heap, ?base), - // HeapAllocation_Type(?heap, ?heaptype), - // VirtualMethodInvocation_SimpleName(?invocation, ?simplename), - // VirtualMethodInvocation_Descriptor(?invocation, ?descriptor), - // basic.MethodLookup(?simplename, ?descriptor, ?heaptype, ?toMethod), - // ThisVar(?toMethod, ?this). - VarPointsTo.add_production( - Reachable_Invocation - .join(VirtualMethodInvocation_Base) - .join(VirtualMethodInvocation_SimpleName) - .join(VirtualMethodInvocation_Descriptor) - .map(|(_inv, ((((), base), simplename), descriptor))| (base, (simplename, descriptor))) - .join_core(VarPointsToRev, |_base,(name,desc),heap| Some((heap.clone(), (name.clone(), desc.clone())))) - .join(HeapAllocation_Type) - .map(|(heap,((name,desc),heaptype))| ((name,desc,heaptype),heap)) - .join(MethodLookup.map(|(n,d,h,t)| ((n,d,h),t))) - .map(|((_n,_d,_t),(heap,to_method))| (to_method, heap)) - .join(ThisVar) - .map(|(_to_method, (heap, this))| (heap,this)) - ); - - let result = (SupertypeOf.leave(), InitializedClass.leave(), Reachable.leave(), VarPointsTo.leave(), CallGraphEdge.leave()); - - Reachable.complete(); - InitializedClass.complete(); - Assign.complete(); - VarPointsTo.complete(); - CallGraphEdge.complete(); - - result - }); - - // st .distinct() - // .map(|_| ()) - // .consolidate() - // .inspect(|x| println!("ST: {:?}", x)); - - // ic .distinct() - // .map(|_| ()) - // .consolidate() - // .inspect(|x| println!("IC: {:?}", x)); - - _reachable - .distinct() - .map(|_| ()) - .consolidate() - .inspect(|x| println!("Reach: {:?}", x)) - .probe_with(&mut probe); - - _varpoints - .distinct() - .map(|_| ()) - .consolidate() - .inspect(|x| println!("VarPT: {:?}", x)) - .probe_with(&mut probe); - - _callgraph - .distinct() - .map(|_| ()) - .consolidate() - .inspect(|x| println!("Graph: {:?}", x)) - .probe_with(&mut probe); - - // (input1, input2, input3, input4, input5, input6, input7, input8, input9, input10, input11, input12, input13, input14, input15, input16, input17, input18, input19, input20, input21, input22, input23, input24, input25, input26, input27, input28, input29, input30, input31) - - }); - - if worker.index() == 0 { - - for input in inputs.0.iter_mut() { input.advance_to(1); input.flush(); } - for input in inputs.1.iter_mut() { input.advance_to(1); input.flush(); } - for input in inputs.2.iter_mut() { input.advance_to(1); input.flush(); } - for input in inputs.3.iter_mut() { input.advance_to(1); input.flush(); } - for input in inputs.4.iter_mut() { input.advance_to(1); input.flush(); } - for input in inputs.5.iter_mut() { input.advance_to(1); input.flush(); } - for input in inputs.6.iter_mut() { input.advance_to(1); input.flush(); } - - while probe.less_than(inputs.0[0].time()) { worker.step(); } - - println!("{:?}\tcomputation initialized", timer.elapsed()); - - if batch > 0 { - - // Load methods from disk - let methods_stuff = load7(index, &prefix, "Method.facts", interner.clone()).collect::>(); - for (round, methods_thing) in methods_stuff.into_iter().enumerate() { - - let round = round as Time; - - // remove, advance, re-insert. - inputs.6[0].remove(methods_thing.0.clone()); - for input in inputs.0.iter_mut() { input.advance_to(2 + round); input.flush(); } - for input in inputs.1.iter_mut() { input.advance_to(2 + round); input.flush(); } - for input in inputs.2.iter_mut() { input.advance_to(2 + round); input.flush(); } - for input in inputs.3.iter_mut() { input.advance_to(2 + round); input.flush(); } - for input in inputs.4.iter_mut() { input.advance_to(2 + round); input.flush(); } - for input in inputs.5.iter_mut() { input.advance_to(2 + round); input.flush(); } - for input in inputs.6.iter_mut() { input.advance_to(2 + round); input.flush(); } - inputs.6[0].insert(methods_thing.0.clone()); - - // step worker until remove has resolved. - if round % batch == batch - 1 { - while probe.less_than(inputs.0[0].time()) { worker.step(); } - println!("{:?}\tround {} complete", timer.elapsed(), round); - } - - } - } - } - - }).expect("Timely computation did not complete cleanly"); -} diff --git a/tpchlike/Cargo.toml b/tpchlike/Cargo.toml deleted file mode 100644 index aa23160bf6..0000000000 --- a/tpchlike/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "tpchlike" -version = "0.1.0" -authors = ["Frank McSherry "] - -[dependencies] -rand = "0.6.5" -regex = "0.2" -#timely = "0.11" -timely = { workspace = true } -differential-dataflow = { workspace = true } -arrayvec = { git = "https://github.com/bluss/arrayvec" } -abomonation = "0.7" -core_affinity = "0.5.9" - -[profile.release] -panic = "abort" diff --git a/tpchlike/README.md b/tpchlike/README.md deleted file mode 100644 index f88f9d0d28..0000000000 --- a/tpchlike/README.md +++ /dev/null @@ -1,44 +0,0 @@ -## tpchlike: a TPCH-like evaluation of differential dataflow - -[TPC-H](http://www.tpc.org/tpch/) is a database benchmark, used by serious people to evaluate things that make money. [Differential dataflow](https://github.com/frankmcsherry/differential-dataflow) is less serious, but it is still interesting to see how it performs on this class of tasks. - -The evaluation here is meant to mimic the evaluation done in ["How to Win a Hot Dog Eating Contest"](https://infoscience.epfl.ch/record/218203/files/sigmod2016-cr.pdf?version=1), in which they also evaluate a TPC-H like workload adapted to a streaming setting. The idea is that instead of loading all base relations, we introduce tuples to the base relations in a streaming fashion. Specifically, they (and we) round-robin through the relations adding one tuple to each at a time. - -Our plan is to eventually implement all of the queries, each a few different ways to demonstrate the awesome flexibility of differential dataflow, and to get measurements from each reflecting the amount of time taken. - ---- - -The program runs with the command line - - cargo run --release -- - -and looks in `` for the various TPC-H files (e.g. `lineitem.tbl`). If you don't have these files, you can grab the generator at the TPC-H link up above. The `logical_batch` argument merges rounds of input and changes the output of the computation; we try to use `1` for the most part, which acts as if each tuple were introduced independently. The `physical_batch` argument indicates how many logical rounds should be introduced concurrently; increasing this argument can increase the throughput at the expense of latency, but will not change the output of the computation. - -Here are some throughput measurements on the scale factor 10 dataset (about 10GB of data, and sixty million tuples in the `lineitem` relation), as we vary the physical batching (varying the concurrent work) from 1K elements to 1M elements. We also list the reported from the single-threaded implementation from the hot dog eating paper. These are intended for *qualitative* comparison; so that we can see where things appear to be much improved (e.g. `q15`, `q19`, `q20`, `q22`), and where there is space to improve ourselves (e.g. `q04`, `q06`). - -| | 1K | 1M | [Hot Dog](https://infoscience.epfl.ch/record/218203/files/sigmod2016-cr.pdf?version=1) | -|------------------------------------:|----------:|----------:|----------:| -| [query01](./src/queries/query01.rs) | 3.76M/s | 2.67M/s | 1.27M/s | -| [query02](./src/queries/query02.rs) | 1.80M/s | 3.46M/s | 756.61K/s | -| [query03](./src/queries/query03.rs) | 3.85M/s | 8.35M/s | 3.74M/s | -| [query04](./src/queries/query04.rs) | 3.00M/s | 4.47M/s | 10.08M/s | -| [query05](./src/queries/query05.rs) | 2.22M/s | 5.04M/s | 584.26K/s | -| [query06](./src/queries/query06.rs) | 22.77M/s | 65.23M/s | 138.33M/s | -| [query07](./src/queries/query07.rs) | 2.02M/s | 5.77M/s | 650.65K/s | -| [query08](./src/queries/query08.rs) | 1.15M/s | 2.82M/s | 91.22K/s | -| [query09](./src/queries/query09.rs) | 896.25K/s | 2.12M/s | 104.37K/s | -| [query10](./src/queries/query10.rs) | 3.05M/s | 9.00M/s | 2.89M/s | -| [query11](./src/queries/query11.rs) | 7.02K/s | 7.90K/s | 768/s | -| [query12](./src/queries/query12.rs) | 7.37M/s | 17.41M/s | 8.68M/s | -| [query13](./src/queries/query13.rs) | 528.03K/s | 892.74K/s | 779.52K/s | -| [query14](./src/queries/query14.rs) | 9.05M/s | 33.43M/s | 33.04M/s | -| [query15](./src/queries/query15.rs) | 1.52M/s | 6.39M/s | 17/s | -| [query16](./src/queries/query16.rs) | 1.82M/s | 2.91M/s | 123.94K/s | -| [query17](./src/queries/query17.rs) | 1.18M/s | 2.41M/s | 379.30K/s | -| [query18](./src/queries/query18.rs) | 3.28M/s | 4.95M/s | 1.13M/s | -| [query19](./src/queries/query19.rs) | 7.48M/s | 24.61M/s | 1.95M/s | -| [query20](./src/queries/query20.rs) | 4.12M/s | 10.39M/s | 977/s | -| [query21](./src/queries/query21.rs) | 734.42K/s | 1.39M/s | 836.80K/s | -| [query22](./src/queries/query22.rs) | 21.33K/s | 11.61K/s | 189/s | - -**PLEASE NOTE**: These times are the reported running times of the code in the repository, which may or may not compute the intended quantities. It is very possible (likely, even) that I have botched some or all of the query implementations. I'm not validating the results at the moment, as I don't have much to validate against, but if you think you see bugs (or want to help validating) drop me a line! Please don't just go and use these measurements as "truth" until we find out if I am actually computing the correct answers. diff --git a/tpchlike/src/bin/arrange.rs b/tpchlike/src/bin/arrange.rs deleted file mode 100644 index 4cd6ee81b7..0000000000 --- a/tpchlike/src/bin/arrange.rs +++ /dev/null @@ -1,246 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; -extern crate core_affinity; -extern crate tpchlike; - -use std::rc::Rc; -use std::fs::File; -use std::io::{BufRead, BufReader}; -use std::time::Instant; - -use timely::dataflow::operators::*; -use differential_dataflow::AsCollection; -use tpchlike::{Context, Collections, types::*, queries}; - -fn main() { - - timely::execute_from_args(std::env::args().skip(4), |worker| { - - let timer = worker.timer(); - let index = worker.index(); - let peers = worker.peers(); - - let core_ids = core_affinity::get_core_ids().unwrap(); - core_affinity::set_for_current(core_ids[index]); - - let prefix = ::std::env::args().nth(1).unwrap();; - let logical_batch = ::std::env::args().nth(2).unwrap().parse::().unwrap(); - let physical_batch = ::std::env::args().nth(3).unwrap().parse::().unwrap(); - let arrange: bool = ::std::env::args().nth(4).unwrap().parse().unwrap(); - let seal: bool = ::std::env::args().any(|x| x == "seal-inputs"); - let window: bool = ::std::env::args().any(|x| x == "window"); - - let (mut inputs, probe, used, mut traces) = worker.dataflow::(move |scope| { - - // create new inputs to use in workers! - let (cust_in, cust) = scope.new_input(); - let (line_in, mut line) = scope.new_input(); - let (nats_in, nats) = scope.new_input(); - let (ords_in, ords) = scope.new_input(); - let (part_in, part) = scope.new_input(); - let (psup_in, psup) = scope.new_input(); - let (regs_in, regs) = scope.new_input(); - let (supp_in, supp) = scope.new_input(); - - if window { - line = line.map(|(x,y,z): (LineItem, usize, isize)| (x,y+1,-z)).concat(line); - } - - let collections = Collections::new( - cust.as_collection(), - line.map(|(d,t,r)| (Rc::new(d),t,r)).as_collection(), - nats.as_collection(), - ords.as_collection(), - part.as_collection(), - psup.as_collection(), - regs.as_collection(), - supp.as_collection(), - ); - - // use timely::dataflow::ProbeHandle; - - let mut context = Context::new(scope, collections); - - context.index = arrange; - - queries::query01::query_arranged(&mut context); - queries::query02::query_arranged(&mut context); - queries::query03::query_arranged(&mut context); - queries::query04::query_arranged(&mut context); - queries::query05::query_arranged(&mut context); - queries::query06::query_arranged(&mut context); - queries::query07::query_arranged(&mut context); - queries::query08::query_arranged(&mut context); - queries::query09::query_arranged(&mut context); - queries::query10::query_arranged(&mut context); - // queries::query11::query_arranged(&mut context); - queries::query12::query_arranged(&mut context); - queries::query13::query_arranged(&mut context); - queries::query14::query_arranged(&mut context); - queries::query15::query_arranged(&mut context); - queries::query16::query_arranged(&mut context); - queries::query17::query_arranged(&mut context); - queries::query18::query_arranged(&mut context); - queries::query19::query_arranged(&mut context); - // queries::query20::query_arranged(&mut context); - // queries::query21::query_arranged(&mut context); - // queries::query22::query_arranged(&mut context); - - // return the various input handles, and the list of probes. - let inputs = ( - Some(cust_in), - Some(line_in), - Some(nats_in), - Some(ords_in), - Some(part_in), - Some(psup_in), - Some(regs_in), - Some(supp_in), - ); - - (inputs, context.probe, context.collections.used(), context.arrangements) - }); - - // customer.tbl lineitem.tbl nation.tbl orders.tbl part.tbl partsupp.tbl region.tbl supplier.tbl - let mut customers = if used[0] { load::(prefix.as_str(), "customer.tbl", index, peers, logical_batch, physical_batch, 0) } else { Vec::new() }; - let mut lineitems = if used[1] { load::(prefix.as_str(), "lineitem.tbl", index, peers, logical_batch, physical_batch, 1) } else { Vec::new() }; - let mut nations = if used[2] { load::(prefix.as_str(), "nation.tbl", index, peers, logical_batch, physical_batch, 2) } else { Vec::new() }; - let mut orders = if used[3] { load::(prefix.as_str(), "orders.tbl", index, peers, logical_batch, physical_batch, 3) } else { Vec::new() }; - let mut parts = if used[4] { load::(prefix.as_str(), "part.tbl", index, peers, logical_batch, physical_batch, 4) } else { Vec::new() }; - let mut partsupps = if used[5] { load::(prefix.as_str(), "partsupp.tbl", index, peers, logical_batch, physical_batch, 5) } else { Vec::new() }; - let mut regions = if used[6] { load::(prefix.as_str(), "region.tbl", index, peers, logical_batch, physical_batch, 6) } else { Vec::new() }; - let mut suppliers = if used[7] { load::(prefix.as_str(), "supplier.tbl", index, peers, logical_batch, physical_batch, 7) } else { Vec::new() }; - - println!("{:?}\tInput loaded", timer.elapsed()); - - let mut tuples = 0usize; - tuples += customers.iter().map(|x| x.len()).sum::(); - tuples += lineitems.iter().map(|x| x.len()).sum::(); - tuples += nations.iter().map(|x| x.len()).sum::(); - tuples += orders.iter().map(|x| x.len()).sum::(); - tuples += parts.iter().map(|x| x.len()).sum::(); - tuples += partsupps.iter().map(|x| x.len()).sum::(); - tuples += regions.iter().map(|x| x.len()).sum::(); - tuples += suppliers.iter().map(|x| x.len()).sum::(); - - // Synchronize before starting the timer. - let next_round = 1; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - - let timer = Instant::now(); - let mut round = 0; - while customers.len() > 0 || lineitems.len() > 0 || nations.len() > 0 || orders.len() > 0 || parts.len() > 0 || partsupps.len() > 0 || regions.len() > 0 || suppliers.len() > 0 { - - println!("{:?}\tInjecting data for round {}", timer.elapsed(), round); - - // introduce physical batch of data for each input with remaining data. - if let Some(mut data) = customers.pop() { inputs.0.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.0 = None; } } - if let Some(mut data) = lineitems.pop() { inputs.1.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.1 = None; } } - if let Some(mut data) = nations.pop() { inputs.2.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.2 = None; } } - if let Some(mut data) = orders.pop() { inputs.3.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.3 = None; } } - if let Some(mut data) = parts.pop() { inputs.4.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.4 = None; } } - if let Some(mut data) = partsupps.pop() { inputs.5.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.5 = None; } } - if let Some(mut data) = regions.pop() { inputs.6.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.6 = None; } } - if let Some(mut data) = suppliers.pop() { inputs.7.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.7 = None; } } - - // catch all inputs up to the same (next) round. - let next_round = 1 + 8 * (round + 1) * physical_batch; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - - traces.set_logical_compaction(&[next_round]); - - worker.step_while(|| probe.less_than(&time)); - round += 1; - } - - // Finish outstanding work before stopping the timer. - let next_round = usize::MAX; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - - // let query_name = if query < 10 { format!("q0{}", query) } else { format!("q{}", query) }; - let elapsed = timer.elapsed(); - let nanos = elapsed.as_secs() * 1000000000 + elapsed.subsec_nanos() as u64; - if index == 0 { - let rate = ((peers * tuples) as f64) / (nanos as f64 / 1000000000.0); - // Query, Logical, Physical, Workers, Rate, Time - println!("{}\t{}\t{}\t{}\t{}", logical_batch, physical_batch, peers, rate, nanos); - // println!("query: {}, elapsed: {:?}, tuples: {:?}, rate: {:?}", query_name, timer.elapsed(), peers * tuples, ((peers * tuples) as f64) / (nanos as f64 / 1000000000.0)); - } - - }).unwrap(); -} - -// Returns a sequence of physical batches of ready-to-go timestamped data. Not clear that `input` can exploit the pre-arrangement yet. -fn load(prefix: &str, name: &str, index: usize, peers: usize, logical_batch: usize, physical_batch: usize, off: usize) - -> Vec> -where T: for<'a> From<&'a str> { - - let mut result = Vec::new(); - let mut buffer = Vec::new(); - - let path = format!("{}{}", prefix, name); - - let items_file = File::open(&path).expect("didn't find items file"); - let mut items_reader = BufReader::new(items_file); - let mut count = 0; - - let mut line = String::new(); - - while items_reader.read_line(&mut line).unwrap() > 0 { - - if count % peers == index { - - let logical = (8 * count / logical_batch) + off; - let physical = logical / physical_batch; - let round = physical / 8; - - while result.len() < round { - result.push(buffer); - buffer = Vec::with_capacity(2 + logical_batch * physical_batch / peers); - } - - let item = T::from(line.as_str()); - buffer.push((item, logical + 1, 1)); - } - - count += 1; - - line.clear(); - } - - if buffer.len() > 0 { - result.push(buffer); - } - - result.reverse(); - result -} diff --git a/tpchlike/src/bin/batch.rs b/tpchlike/src/bin/batch.rs deleted file mode 100644 index d19ff20de8..0000000000 --- a/tpchlike/src/bin/batch.rs +++ /dev/null @@ -1,166 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; -extern crate core_affinity; -extern crate tpchlike; - -use std::rc::Rc; -use std::fs::File; -use std::io::{BufRead, BufReader}; -use std::time::Instant; - -use timely::dataflow::operators::*; - -use differential_dataflow::AsCollection; - -use tpchlike::{Collections, types::*, queries}; - -fn main() { - - timely::execute_from_args(std::env::args().skip(2), |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let core_ids = core_affinity::get_core_ids().unwrap(); - core_affinity::set_for_current(core_ids[index]); - - let prefix = ::std::env::args().nth(1).unwrap();; - let query: usize = ::std::env::args().nth(2).unwrap().parse().unwrap(); - - let (mut inputs, probe, used) = worker.dataflow::<(),_,_>(move |scope| { - - // create new inputs to use in workers! - let (cust_in, cust) = scope.new_input(); - let (line_in, line) = scope.new_input(); - let (nats_in, nats) = scope.new_input(); - let (ords_in, ords) = scope.new_input(); - let (part_in, part) = scope.new_input(); - let (psup_in, psup) = scope.new_input(); - let (regs_in, regs) = scope.new_input(); - let (supp_in, supp) = scope.new_input(); - - let mut collections = Collections::new( - cust.as_collection(), - line.map(|(d,t,r)| (Rc::new(d),t,r)).as_collection(), - nats.as_collection(), - ords.as_collection(), - part.as_collection(), - psup.as_collection(), - regs.as_collection(), - supp.as_collection(), - ); - - let mut probe = timely::dataflow::ProbeHandle::new(); - - match query { - 1 => queries::query01::query(&mut collections, &mut probe), - 2 => queries::query02::query(&mut collections, &mut probe), - 3 => queries::query03::query(&mut collections, &mut probe), - 4 => queries::query04::query(&mut collections, &mut probe), - 5 => queries::query05::query(&mut collections, &mut probe), - 6 => queries::query06::query(&mut collections, &mut probe), - 7 => queries::query07::query(&mut collections, &mut probe), - 8 => queries::query08::query(&mut collections, &mut probe), - 9 => queries::query09::query(&mut collections, &mut probe), - 10 => queries::query10::query(&mut collections, &mut probe), - 11 => queries::query11::query(&mut collections, &mut probe), - 12 => queries::query12::query(&mut collections, &mut probe), - 13 => queries::query13::query(&mut collections, &mut probe), - 14 => queries::query14::query(&mut collections, &mut probe), - 15 => queries::query15::query(&mut collections, &mut probe), - 16 => queries::query16::query(&mut collections, &mut probe), - 17 => queries::query17::query(&mut collections, &mut probe), - 18 => queries::query18::query(&mut collections, &mut probe), - 19 => queries::query19::query(&mut collections, &mut probe), - 20 => queries::query20::query(&mut collections, &mut probe), - 21 => queries::query21::query(&mut collections, &mut probe), - 22 => queries::query22::query(&mut collections, &mut probe), - _ => panic!("query: {:?} unimplemented", query), - } - - // return the various input handles, and the probe. - ((Some(cust_in), Some(line_in), Some(nats_in), Some(ords_in), Some(part_in), Some(psup_in), Some(regs_in), Some(supp_in)), probe, collections.used()) - }); - - // customer.tbl lineitem.tbl nation.tbl orders.tbl part.tbl partsupp.tbl region.tbl supplier.tbl - let mut customers = if used[0] { load::(prefix.as_str(), "customer.tbl", index, peers) } else { Vec::new() }; - let mut lineitems = if used[1] { load::(prefix.as_str(), "lineitem.tbl", index, peers) } else { Vec::new() }; - let mut nations = if used[2] { load::(prefix.as_str(), "nation.tbl", index, peers) } else { Vec::new() }; - let mut orders = if used[3] { load::(prefix.as_str(), "orders.tbl", index, peers) } else { Vec::new() }; - let mut parts = if used[4] { load::(prefix.as_str(), "part.tbl", index, peers) } else { Vec::new() }; - let mut partsupps = if used[5] { load::(prefix.as_str(), "partsupp.tbl", index, peers) } else { Vec::new() }; - let mut regions = if used[6] { load::(prefix.as_str(), "region.tbl", index, peers) } else { Vec::new() }; - let mut suppliers = if used[7] { load::(prefix.as_str(), "supplier.tbl", index, peers) } else { Vec::new() }; - - let mut tuples = 0usize; - tuples += customers.iter().map(|x| x.len()).sum::(); - tuples += lineitems.iter().map(|x| x.len()).sum::(); - tuples += nations.iter().map(|x| x.len()).sum::(); - tuples += orders.iter().map(|x| x.len()).sum::(); - tuples += parts.iter().map(|x| x.len()).sum::(); - tuples += partsupps.iter().map(|x| x.len()).sum::(); - tuples += regions.iter().map(|x| x.len()).sum::(); - tuples += suppliers.iter().map(|x| x.len()).sum::(); - - // Synchronize before starting the timer. - let probe2 = worker.dataflow::<(),_,_>(|scope| { - let (_, input) = scope.new_input::<()>(); - input.probe() - }); - while !probe2.done() { worker.step(); } - - let timer = Instant::now(); - - // introduce physical batch of data for each input with remaining data. - for _ in 0..10 { worker.step(); } while let Some(mut data) = regions.pop() { inputs.6.as_mut().map(|x| x.send_batch(&mut data)); } inputs.6 = None; - for _ in 0..10 { worker.step(); } while let Some(mut data) = nations.pop() { inputs.2.as_mut().map(|x| x.send_batch(&mut data)); } inputs.2 = None; - for _ in 0..10 { worker.step(); } while let Some(mut data) = suppliers.pop() { inputs.7.as_mut().map(|x| x.send_batch(&mut data)); } inputs.7 = None; - for _ in 0..10 { worker.step(); } while let Some(mut data) = parts.pop() { inputs.4.as_mut().map(|x| x.send_batch(&mut data)); } inputs.4 = None; - for _ in 0..10 { worker.step(); } while let Some(mut data) = customers.pop() { inputs.0.as_mut().map(|x| x.send_batch(&mut data)); } inputs.0 = None; - for _ in 0..10 { worker.step(); } while let Some(mut data) = lineitems.pop() { inputs.1.as_mut().map(|x| x.send_batch(&mut data)); } inputs.1 = None; - for _ in 0..10 { worker.step(); } while let Some(mut data) = orders.pop() { inputs.3.as_mut().map(|x| x.send_batch(&mut data)); } inputs.3 = None; - for _ in 0..10 { worker.step(); } while let Some(mut data) = partsupps.pop() { inputs.5.as_mut().map(|x| x.send_batch(&mut data)); } inputs.5 = None; - - worker.step_while(|| probe.done()); - - let query_name = if query < 10 { format!("q0{}", query) } else { format!("q{}", query) }; - let elapsed = timer.elapsed(); - let nanos = elapsed.as_secs() * 1000000000 + elapsed.subsec_nanos() as u64; - if index == 0 { - let rate = ((peers * tuples) as f64) / (nanos as f64 / 1000000000.0); - // Query, Logical, Physical, Workers, Rate, Time - println!("{}\t{}\t{}\t{}", query_name, peers, rate, nanos); - } - - }).unwrap(); -} - -// Returns a sequence of physical batches of ready-to-go timestamped data. Not clear that `input` can exploit the pre-arrangement yet. -fn load(prefix: &str, name: &str, index: usize, peers: usize) - -> Vec> -where T: for<'a> From<&'a str> { - - let mut buffer = Vec::new(); - - let path = format!("{}{}", prefix, name); - - let items_file = File::open(&path).expect("didn't find items file"); - let mut items_reader = BufReader::new(items_file); - let mut count = 0; - - let mut line = String::new(); - - while items_reader.read_line(&mut line).unwrap() > 0 { - - if count % peers == index { - let item = T::from(line.as_str()); - buffer.push((item, (), 1)); - } - - count += 1; - - line.clear(); - } - - vec![buffer] -} diff --git a/tpchlike/src/bin/just-arrange.rs b/tpchlike/src/bin/just-arrange.rs deleted file mode 100644 index f4b9393b74..0000000000 --- a/tpchlike/src/bin/just-arrange.rs +++ /dev/null @@ -1,223 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; -extern crate core_affinity; -extern crate tpchlike; - -use std::rc::Rc; -use std::fs::File; -use std::io::{BufRead, BufReader}; -use std::time::Instant; - -use timely::dataflow::operators::*; -use differential_dataflow::AsCollection; -use tpchlike::{Context, Collections, types::*, queries}; - -fn main() { - - timely::execute_from_args(std::env::args().skip(4), |worker| { - - let timer = worker.timer(); - let index = worker.index(); - let peers = worker.peers(); - - let core_ids = core_affinity::get_core_ids().unwrap(); - core_affinity::set_for_current(core_ids[index]); - - let prefix = ::std::env::args().nth(1).unwrap();; - let logical_batch = ::std::env::args().nth(2).unwrap().parse::().unwrap(); - let physical_batch = ::std::env::args().nth(3).unwrap().parse::().unwrap(); - let arrange: bool = ::std::env::args().nth(4).unwrap().parse().unwrap(); - let seal: bool = ::std::env::args().any(|x| x == "seal-inputs"); - let window: bool = ::std::env::args().any(|x| x == "window"); - - let (mut inputs, probe, used, mut traces) = worker.dataflow::(move |scope| { - - // create new inputs to use in workers! - let (cust_in, cust) = scope.new_input(); - let (line_in, mut line) = scope.new_input(); - let (nats_in, nats) = scope.new_input(); - let (ords_in, ords) = scope.new_input(); - let (part_in, part) = scope.new_input(); - let (psup_in, psup) = scope.new_input(); - let (regs_in, regs) = scope.new_input(); - let (supp_in, supp) = scope.new_input(); - - if window { - line = line.map(|(x,y,z): (LineItem, usize, isize)| (x,y+1,-z)).concat(line); - } - - let collections = Collections::new( - cust.as_collection(), - line.map(|(d,t,r)| (Rc::new(d),t,r)).as_collection(), - nats.as_collection(), - ords.as_collection(), - part.as_collection(), - psup.as_collection(), - regs.as_collection(), - supp.as_collection(), - ); - - // use timely::dataflow::ProbeHandle; - - let mut context = Context::new(scope, collections); - - context.index = arrange; - - // return the various input handles, and the list of probes. - let inputs = ( - Some(cust_in), - Some(line_in), - Some(nats_in), - Some(ords_in), - Some(part_in), - Some(psup_in), - Some(regs_in), - Some(supp_in), - ); - - (inputs, context.probe, context.collections.used(), context.arrangements) - }); - - // customer.tbl lineitem.tbl nation.tbl orders.tbl part.tbl partsupp.tbl region.tbl supplier.tbl - let mut customers = if used[0] { load::(prefix.as_str(), "customer.tbl", index, peers, logical_batch, physical_batch, 0) } else { Vec::new() }; - let mut lineitems = if used[1] { load::(prefix.as_str(), "lineitem.tbl", index, peers, logical_batch, physical_batch, 1) } else { Vec::new() }; - let mut nations = if used[2] { load::(prefix.as_str(), "nation.tbl", index, peers, logical_batch, physical_batch, 2) } else { Vec::new() }; - let mut orders = if used[3] { load::(prefix.as_str(), "orders.tbl", index, peers, logical_batch, physical_batch, 3) } else { Vec::new() }; - let mut parts = if used[4] { load::(prefix.as_str(), "part.tbl", index, peers, logical_batch, physical_batch, 4) } else { Vec::new() }; - let mut partsupps = if used[5] { load::(prefix.as_str(), "partsupp.tbl", index, peers, logical_batch, physical_batch, 5) } else { Vec::new() }; - let mut regions = if used[6] { load::(prefix.as_str(), "region.tbl", index, peers, logical_batch, physical_batch, 6) } else { Vec::new() }; - let mut suppliers = if used[7] { load::(prefix.as_str(), "supplier.tbl", index, peers, logical_batch, physical_batch, 7) } else { Vec::new() }; - - println!("{:?}\tInput loaded", timer.elapsed()); - - let mut tuples = 0usize; - tuples += customers.iter().map(|x| x.len()).sum::(); - tuples += lineitems.iter().map(|x| x.len()).sum::(); - tuples += nations.iter().map(|x| x.len()).sum::(); - tuples += orders.iter().map(|x| x.len()).sum::(); - tuples += parts.iter().map(|x| x.len()).sum::(); - tuples += partsupps.iter().map(|x| x.len()).sum::(); - tuples += regions.iter().map(|x| x.len()).sum::(); - tuples += suppliers.iter().map(|x| x.len()).sum::(); - - // Synchronize before starting the timer. - let next_round = 1; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - - let timer = Instant::now(); - let mut round = 0; - while customers.len() > 0 || lineitems.len() > 0 || nations.len() > 0 || orders.len() > 0 || parts.len() > 0 || partsupps.len() > 0 || regions.len() > 0 || suppliers.len() > 0 { - - println!("{:?}\tInjecting data for round {}", timer.elapsed(), round); - - // introduce physical batch of data for each input with remaining data. - if let Some(mut data) = customers.pop() { inputs.0.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.0 = None; } } - if let Some(mut data) = lineitems.pop() { inputs.1.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.1 = None; } } - if let Some(mut data) = nations.pop() { inputs.2.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.2 = None; } } - if let Some(mut data) = orders.pop() { inputs.3.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.3 = None; } } - if let Some(mut data) = parts.pop() { inputs.4.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.4 = None; } } - if let Some(mut data) = partsupps.pop() { inputs.5.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.5 = None; } } - if let Some(mut data) = regions.pop() { inputs.6.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.6 = None; } } - if let Some(mut data) = suppliers.pop() { inputs.7.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.7 = None; } } - - // catch all inputs up to the same (next) round. - let next_round = 1 + 8 * (round + 1) * physical_batch; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - - traces.set_logical_compaction(&[next_round]); - - worker.step_while(|| probe.less_than(&time)); - round += 1; - } - - // Finish outstanding work before stopping the timer. - let next_round = usize::MAX; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - - // let query_name = if query < 10 { format!("q0{}", query) } else { format!("q{}", query) }; - let elapsed = timer.elapsed(); - let nanos = elapsed.as_secs() * 1000000000 + elapsed.subsec_nanos() as u64; - if index == 0 { - let rate = ((peers * tuples) as f64) / (nanos as f64 / 1000000000.0); - // Query, Logical, Physical, Workers, Rate, Time - println!("{}\t{}\t{}\t{}\t{}", logical_batch, physical_batch, peers, rate, nanos); - // println!("query: {}, elapsed: {:?}, tuples: {:?}, rate: {:?}", query_name, timer.elapsed(), peers * tuples, ((peers * tuples) as f64) / (nanos as f64 / 1000000000.0)); - } - - }).unwrap(); -} - -// Returns a sequence of physical batches of ready-to-go timestamped data. Not clear that `input` can exploit the pre-arrangement yet. -fn load(prefix: &str, name: &str, index: usize, peers: usize, logical_batch: usize, physical_batch: usize, off: usize) - -> Vec> -where T: for<'a> From<&'a str> { - - let mut result = Vec::new(); - let mut buffer = Vec::new(); - - let path = format!("{}{}", prefix, name); - - let items_file = File::open(&path).expect("didn't find items file"); - let mut items_reader = BufReader::new(items_file); - let mut count = 0; - - let mut line = String::new(); - - while items_reader.read_line(&mut line).unwrap() > 0 { - - if count % peers == index { - - let logical = (8 * count / logical_batch) + off; - let physical = logical / physical_batch; - let round = physical / 8; - - while result.len() < round { - result.push(buffer); - buffer = Vec::with_capacity(2 + logical_batch * physical_batch / peers); - } - - let item = T::from(line.as_str()); - buffer.push((item, logical + 1, 1)); - } - - count += 1; - - line.clear(); - } - - if buffer.len() > 0 { - result.push(buffer); - } - - result.reverse(); - result -} diff --git a/tpchlike/src/bin/sosp.rs b/tpchlike/src/bin/sosp.rs deleted file mode 100644 index eaa4e949d2..0000000000 --- a/tpchlike/src/bin/sosp.rs +++ /dev/null @@ -1,200 +0,0 @@ -extern crate rand; -extern crate timely; -extern crate differential_dataflow; -extern crate core_affinity; -extern crate tpchlike; - -use std::rc::Rc; -use std::fs::File; -use std::io::{BufRead, BufReader}; -use std::time::Instant; - -use timely::dataflow::ProbeHandle; -use tpchlike::{Arrangements, Experiment, InputHandles, types::*, queries}; - -fn main() { - - timely::execute_from_args(std::env::args().skip(4), |worker| { - - let timer = worker.timer(); - let index = worker.index(); - let peers = worker.peers(); - - let core_ids = core_affinity::get_core_ids().unwrap(); - core_affinity::set_for_current(core_ids[index]); - - let mut args = ::std::env::args(); - args.next(); - let prefix = args.next().unwrap(); - let logical_batch = args.next().unwrap().parse::().expect("logical batch must be an integer"); - let physical_batch = args.next().unwrap().parse::().expect("physical batch must be an integer"); - let concurrent = args.next().unwrap().parse::().expect("concurrency must be an integer"); - let arrange: bool = args.next().unwrap().parse().unwrap(); - let seal: bool = ::std::env::args().any(|x| x == "seal-inputs"); - - // Build all indices, as we plan to use all of them. - let (mut inputs, mut probe, mut traces) = worker.dataflow::(move |scope| { - - let mut inputs = InputHandles::new(); - let mut probe = ProbeHandle::new(); - let traces = Arrangements::new(&mut inputs, scope, &mut probe, arrange); - - (inputs, probe, traces) - }); - - // customer.tbl lineitem.tbl nation.tbl orders.tbl part.tbl partsupp.tbl region.tbl supplier.tbl - let mut customers = load::(prefix.as_str(), "customer.tbl", index, peers, logical_batch, physical_batch, 0); - let mut lineitems = load::(prefix.as_str(), "lineitem.tbl", index, peers, logical_batch, physical_batch, 1); - let mut nations = load::(prefix.as_str(), "nation.tbl", index, peers, logical_batch, physical_batch, 2); - let mut orders = load::(prefix.as_str(), "orders.tbl", index, peers, logical_batch, physical_batch, 3); - let mut parts = load::(prefix.as_str(), "part.tbl", index, peers, logical_batch, physical_batch, 4); - let mut partsupps = load::(prefix.as_str(), "partsupp.tbl", index, peers, logical_batch, physical_batch, 5); - let mut regions = load::(prefix.as_str(), "region.tbl", index, peers, logical_batch, physical_batch, 6); - let mut suppliers = load::(prefix.as_str(), "supplier.tbl", index, peers, logical_batch, physical_batch, 7); - - println!("{:?}\tInput loaded", timer.elapsed()); - - // Synchronize before starting the timer. - let next_round = 1; - inputs.advance_to(next_round); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - - use rand::prelude::*; - let mut rng = rand::thread_rng(); - - let timer = Instant::now(); - let mut experiments = Vec::::new(); - let mut round = 0; - while customers.len() > 0 || lineitems.len() > 0 || nations.len() > 0 || orders.len() > 0 || parts.len() > 0 || partsupps.len() > 0 || regions.len() > 0 || suppliers.len() > 0 { - - let this_round = 1 + 8 * round * physical_batch; - - let query = rng.gen_range(0, 22); - - let token = std::rc::Rc::new(()); - let mut experiment = Experiment::new(query, &token); - // install new dataflows, retire old dataflow - worker.dataflow_core::("dataflow", None, token, |_,scope| { - match query { - 0 => queries::query01::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 1 => queries::query02::query_arranged(scope, &mut probe, &mut experiment, &mut traces, this_round-1), - 2 => queries::query03::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 3 => queries::query04::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 4 => queries::query05::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 5 => queries::query06::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 6 => queries::query07::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 7 => queries::query08::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 8 => queries::query09::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 9 => queries::query10::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 10 => queries::query11::query_arranged(scope, &mut probe, &mut experiment, &mut traces, this_round-1), - 11 => queries::query12::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 12 => queries::query13::query_arranged(scope, &mut probe, &mut experiment, &mut traces, this_round-1), - 13 => queries::query14::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 14 => queries::query15::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 15 => queries::query16::query_arranged(scope, &mut probe, &mut experiment, &mut traces, this_round-1), - 16 => queries::query17::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 17 => queries::query18::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 18 => queries::query19::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 19 => queries::query20::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 20 => queries::query21::query_arranged(scope, &mut probe, &mut experiment, &mut traces), - 21 => queries::query22::query_arranged(scope, &mut probe, &mut experiment, &mut traces, this_round-1), - _ => { }, - } - experiment.lineitem.advance_to(this_round); - experiments.push(experiment); - }); - let start = timer.elapsed(); - worker.step_while(|| probe.less_than(&this_round)); - let install = timer.elapsed() - start; - - let start = timer.elapsed(); - if experiments.len() > concurrent { - let token = experiments.remove(0).close(); - worker.step_while(|| token.upgrade().is_some()); - } - let uninstall = timer.elapsed() - start; - - // catch all inputs up to the same (next) round. - let next_round = 1 + 8 * (round + 1) * physical_batch; - - // introduce physical batch of data for each input with remaining data. - if let Some(mut data) = customers.pop() { inputs.customer.send_batch(&mut data); } - if let Some(mut data) = lineitems.pop() { - let mut data = data.drain(..).map(|(x,y,z)| (Rc::new(x),y,z)).collect::>(); - let mut temp = Vec::new(); - for experiment in experiments.iter_mut() { - temp.clone_from(&data); - experiment.lineitem.send_batch(&mut temp); - experiment.lineitem.advance_to(next_round); - } - inputs.lineitem.send_batch(&mut data); - } - if let Some(mut data) = nations.pop() { inputs.nation.send_batch(&mut data); } - if let Some(mut data) = orders.pop() { inputs.order.send_batch(&mut data); } - if let Some(mut data) = parts.pop() { inputs.part.send_batch(&mut data); } - if let Some(mut data) = partsupps.pop() { inputs.partsupp.send_batch(&mut data); } - if let Some(mut data) = regions.pop() { inputs.region.send_batch(&mut data); } - if let Some(mut data) = suppliers.pop() { inputs.supplier.send_batch(&mut data); } - - inputs.advance_to(next_round); - traces.set_logical_compaction(&[next_round]); - - let start = timer.elapsed(); - worker.step_while(|| probe.less_than(&next_round)); - let work = timer.elapsed() - start; - - println!("{:?}\t{}\t{}\t{:?}\t{:?}\t{:?}", timer.elapsed(), round, query, install.as_nanos(), uninstall.as_nanos(), work.as_nanos()); - - round += 1; - } - - }).unwrap(); -} - -// Returns a sequence of physical batches of ready-to-go timestamped data. Not clear that `input` can exploit the pre-arrangement yet. -fn load(prefix: &str, name: &str, index: usize, peers: usize, logical_batch: usize, physical_batch: usize, off: usize) - -> Vec> -where T: for<'a> From<&'a str> { - - let mut result = Vec::new(); - let mut buffer = Vec::new(); - - let path = format!("{}{}", prefix, name); - - let items_file = File::open(&path).expect("didn't find items file"); - let mut items_reader = BufReader::new(items_file); - let mut count = 0; - - let mut line = String::new(); - - while items_reader.read_line(&mut line).unwrap() > 0 { - - if count % peers == index { - - let logical = (8 * count / logical_batch) + off; - let physical = logical / physical_batch; - let round = physical / 8; - - while result.len() < round { - result.push(buffer); - buffer = Vec::with_capacity(2 + logical_batch * physical_batch / peers); - } - - let item = T::from(line.as_str()); - buffer.push((item, logical + 1, 1)); - } - - count += 1; - - line.clear(); - } - - if buffer.len() > 0 { - result.push(buffer); - } - - result.reverse(); - result -} \ No newline at end of file diff --git a/tpchlike/src/bin/stream-concurrent.rs b/tpchlike/src/bin/stream-concurrent.rs deleted file mode 100644 index 85c0b449b1..0000000000 --- a/tpchlike/src/bin/stream-concurrent.rs +++ /dev/null @@ -1,219 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; -extern crate core_affinity; -extern crate tpchlike; - -use std::rc::Rc; -use std::fs::File; -use std::io::{BufRead, BufReader}; -use std::time::Instant; - -use timely::dataflow::operators::*; - -use differential_dataflow::AsCollection; - -use tpchlike::{Collections, types::*, queries}; - -fn main() { - - timely::execute_from_args(std::env::args().skip(4), |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let core_ids = core_affinity::get_core_ids().unwrap(); - core_affinity::set_for_current(core_ids[index]); - - let prefix = ::std::env::args().nth(1).unwrap();; - let logical_batch = ::std::env::args().nth(2).unwrap().parse::().unwrap(); - let physical_batch = ::std::env::args().nth(3).unwrap().parse::().unwrap(); - let seal: bool = ::std::env::args().any(|x| x == "seal-inputs"); - - let (mut inputs, probe, used) = worker.dataflow::(move |scope| { - - // create new inputs to use in workers! - let (cust_in, cust) = scope.new_input(); - let (line_in, line) = scope.new_input(); - let (nats_in, nats) = scope.new_input(); - let (ords_in, ords) = scope.new_input(); - let (part_in, part) = scope.new_input(); - let (psup_in, psup) = scope.new_input(); - let (regs_in, regs) = scope.new_input(); - let (supp_in, supp) = scope.new_input(); - - let mut collections = Collections::new( - cust.as_collection(), - line.map(|(d,t,r)| (Rc::new(d),t,r)).as_collection(), - nats.as_collection(), - ords.as_collection(), - part.as_collection(), - psup.as_collection(), - regs.as_collection(), - supp.as_collection(), - ); - - let mut probe = timely::dataflow::ProbeHandle::new(); - - queries::query01::query(&mut collections, &mut probe); - queries::query02::query(&mut collections, &mut probe); - queries::query03::query(&mut collections, &mut probe); - queries::query04::query(&mut collections, &mut probe); - queries::query05::query(&mut collections, &mut probe); - queries::query06::query(&mut collections, &mut probe); - queries::query07::query(&mut collections, &mut probe); - queries::query08::query(&mut collections, &mut probe); - queries::query09::query(&mut collections, &mut probe); - queries::query10::query(&mut collections, &mut probe); - // queries::query11::query(&mut collections, &mut probe); - queries::query12::query(&mut collections, &mut probe); - queries::query13::query(&mut collections, &mut probe); - queries::query14::query(&mut collections, &mut probe); - queries::query15::query(&mut collections, &mut probe); - queries::query16::query(&mut collections, &mut probe); - queries::query17::query(&mut collections, &mut probe); - queries::query18::query(&mut collections, &mut probe); - queries::query19::query(&mut collections, &mut probe); - // queries::query20::query(&mut collections, &mut probe); - // queries::query21::query(&mut collections, &mut probe); - // queries::query22::query(&mut collections, &mut probe); - - // return the various input handles, and the list of probes. - ((Some(cust_in), Some(line_in), Some(nats_in), Some(ords_in), Some(part_in), Some(psup_in), Some(regs_in), Some(supp_in)), probe, collections.used()) - }); - - // customer.tbl lineitem.tbl nation.tbl orders.tbl part.tbl partsupp.tbl region.tbl supplier.tbl - let mut customers = if used[0] { load::(prefix.as_str(), "customer.tbl", index, peers, logical_batch, physical_batch, 0) } else { Vec::new() }; - let mut lineitems = if used[1] { load::(prefix.as_str(), "lineitem.tbl", index, peers, logical_batch, physical_batch, 1) } else { Vec::new() }; - let mut nations = if used[2] { load::(prefix.as_str(), "nation.tbl", index, peers, logical_batch, physical_batch, 2) } else { Vec::new() }; - let mut orders = if used[3] { load::(prefix.as_str(), "orders.tbl", index, peers, logical_batch, physical_batch, 3) } else { Vec::new() }; - let mut parts = if used[4] { load::(prefix.as_str(), "part.tbl", index, peers, logical_batch, physical_batch, 4) } else { Vec::new() }; - let mut partsupps = if used[5] { load::(prefix.as_str(), "partsupp.tbl", index, peers, logical_batch, physical_batch, 5) } else { Vec::new() }; - let mut regions = if used[6] { load::(prefix.as_str(), "region.tbl", index, peers, logical_batch, physical_batch, 6) } else { Vec::new() }; - let mut suppliers = if used[7] { load::(prefix.as_str(), "supplier.tbl", index, peers, logical_batch, physical_batch, 7) } else { Vec::new() }; - - let mut tuples = 0usize; - tuples += customers.iter().map(|x| x.len()).sum::(); - tuples += lineitems.iter().map(|x| x.len()).sum::(); - tuples += nations.iter().map(|x| x.len()).sum::(); - tuples += orders.iter().map(|x| x.len()).sum::(); - tuples += parts.iter().map(|x| x.len()).sum::(); - tuples += partsupps.iter().map(|x| x.len()).sum::(); - tuples += regions.iter().map(|x| x.len()).sum::(); - tuples += suppliers.iter().map(|x| x.len()).sum::(); - - // Synchronize before starting the timer. - let next_round = 1; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - - let timer = Instant::now(); - let mut round = 0; - while customers.len() > 0 || lineitems.len() > 0 || nations.len() > 0 || orders.len() > 0 || parts.len() > 0 || partsupps.len() > 0 || regions.len() > 0 || suppliers.len() > 0 { - - // introduce physical batch of data for each input with remaining data. - if let Some(mut data) = customers.pop() { inputs.0.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.0 = None; } } - if let Some(mut data) = lineitems.pop() { inputs.1.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.1 = None; } } - if let Some(mut data) = nations.pop() { inputs.2.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.2 = None; } } - if let Some(mut data) = orders.pop() { inputs.3.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.3 = None; } } - if let Some(mut data) = parts.pop() { inputs.4.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.4 = None; } } - if let Some(mut data) = partsupps.pop() { inputs.5.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.5 = None; } } - if let Some(mut data) = regions.pop() { inputs.6.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.6 = None; } } - if let Some(mut data) = suppliers.pop() { inputs.7.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.7 = None; } } - - // catch all inputs up to the same (next) round. - let next_round = 1 + 8 * (round + 1) * physical_batch; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - round += 1; - } - - // Finish outstanding work before stopping the timer. - let next_round = usize::MAX; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - - // let query_name = if query < 10 { format!("q0{}", query) } else { format!("q{}", query) }; - let elapsed = timer.elapsed(); - let nanos = elapsed.as_secs() * 1000000000 + elapsed.subsec_nanos() as u64; - if index == 0 { - let rate = ((peers * tuples) as f64) / (nanos as f64 / 1000000000.0); - // Query, Logical, Physical, Workers, Rate, Time - println!("{}\t{}\t{}\t{}\t{}", logical_batch, physical_batch, peers, rate, nanos); - // println!("query: {}, elapsed: {:?}, tuples: {:?}, rate: {:?}", query_name, timer.elapsed(), peers * tuples, ((peers * tuples) as f64) / (nanos as f64 / 1000000000.0)); - } - - }).unwrap(); -} - -// Returns a sequence of physical batches of ready-to-go timestamped data. Not clear that `input` can exploit the pre-arrangement yet. -fn load(prefix: &str, name: &str, index: usize, peers: usize, logical_batch: usize, physical_batch: usize, off: usize) - -> Vec> -where T: for<'a> From<&'a str> { - - let mut result = Vec::new(); - let mut buffer = Vec::new(); - - let path = format!("{}{}", prefix, name); - - let items_file = File::open(&path).expect("didn't find items file"); - let mut items_reader = BufReader::new(items_file); - let mut count = 0; - - let mut line = String::new(); - - while items_reader.read_line(&mut line).unwrap() > 0 { - - if count % peers == index { - - let logical = (8 * count / logical_batch) + off; - let physical = logical / physical_batch; - let round = physical / 8; - - while result.len() < round { - result.push(buffer); - buffer = Vec::with_capacity(2 + logical_batch * physical_batch / peers); - } - - let item = T::from(line.as_str()); - buffer.push((item, logical + 1, 1)); - } - - count += 1; - - line.clear(); - } - - if buffer.len() > 0 { - result.push(buffer); - } - - result.reverse(); - result -} diff --git a/tpchlike/src/bin/stream.rs b/tpchlike/src/bin/stream.rs deleted file mode 100644 index fbdc6385f9..0000000000 --- a/tpchlike/src/bin/stream.rs +++ /dev/null @@ -1,223 +0,0 @@ -extern crate timely; -extern crate differential_dataflow; -extern crate core_affinity; -extern crate tpchlike; - -use std::rc::Rc; -use std::fs::File; -use std::io::{BufRead, BufReader}; -use std::time::Instant; - -use timely::dataflow::operators::*; - -use differential_dataflow::AsCollection; - -use tpchlike::{Collections, types::*, queries}; - -fn main() { - - timely::execute_from_args(std::env::args().skip(4), |worker| { - - let index = worker.index(); - let peers = worker.peers(); - - let core_ids = core_affinity::get_core_ids().unwrap(); - core_affinity::set_for_current(core_ids[index]); - - let prefix = ::std::env::args().nth(1).unwrap();; - let logical_batch = ::std::env::args().nth(2).unwrap().parse::().unwrap(); - let physical_batch = ::std::env::args().nth(3).unwrap().parse::().unwrap(); - let query: usize = ::std::env::args().nth(4).unwrap().parse().unwrap(); - let seal: bool = ::std::env::args().any(|x| x == "seal-inputs"); - - let (mut inputs, probe, used) = worker.dataflow::(move |scope| { - - // create new inputs to use in workers! - let (cust_in, cust) = scope.new_input(); - let (line_in, line) = scope.new_input(); - let (nats_in, nats) = scope.new_input(); - let (ords_in, ords) = scope.new_input(); - let (part_in, part) = scope.new_input(); - let (psup_in, psup) = scope.new_input(); - let (regs_in, regs) = scope.new_input(); - let (supp_in, supp) = scope.new_input(); - - let mut collections = Collections::new( - cust.as_collection(), - line.map(|(d,t,r)| (Rc::new(d),t,r)).as_collection(), - nats.as_collection(), - ords.as_collection(), - part.as_collection(), - psup.as_collection(), - regs.as_collection(), - supp.as_collection(), - ); - - let mut probe = timely::dataflow::ProbeHandle::new(); - - match query { - 1 => queries::query01::query(&mut collections, &mut probe), - 2 => queries::query02::query(&mut collections, &mut probe), - 3 => queries::query03::query(&mut collections, &mut probe), - 4 => queries::query04::query(&mut collections, &mut probe), - 5 => queries::query05::query(&mut collections, &mut probe), - 6 => queries::query06::query(&mut collections, &mut probe), - 7 => queries::query07::query(&mut collections, &mut probe), - 8 => queries::query08::query(&mut collections, &mut probe), - 9 => queries::query09::query(&mut collections, &mut probe), - 10 => queries::query10::query(&mut collections, &mut probe), - 11 => queries::query11::query(&mut collections, &mut probe), - 12 => queries::query12::query(&mut collections, &mut probe), - 13 => queries::query13::query(&mut collections, &mut probe), - 14 => queries::query14::query(&mut collections, &mut probe), - 15 => queries::query15::query(&mut collections, &mut probe), - 16 => queries::query16::query(&mut collections, &mut probe), - 17 => queries::query17::query(&mut collections, &mut probe), - 18 => queries::query18::query(&mut collections, &mut probe), - 19 => queries::query19::query(&mut collections, &mut probe), - 20 => queries::query20::query(&mut collections, &mut probe), - 21 => queries::query21::query(&mut collections, &mut probe), - 22 => queries::query22::query(&mut collections, &mut probe), - _ => panic!("query: {:?} unimplemented", query), - } - - // return the various input handles, and the list of probes. - ((Some(cust_in), Some(line_in), Some(nats_in), Some(ords_in), Some(part_in), Some(psup_in), Some(regs_in), Some(supp_in)), probe, collections.used()) - }); - - // customer.tbl lineitem.tbl nation.tbl orders.tbl part.tbl partsupp.tbl region.tbl supplier.tbl - let mut customers = if used[0] { load::(prefix.as_str(), "customer.tbl", index, peers, logical_batch, physical_batch, 0) } else { Vec::new() }; - let mut lineitems = if used[1] { load::(prefix.as_str(), "lineitem.tbl", index, peers, logical_batch, physical_batch, 1) } else { Vec::new() }; - let mut nations = if used[2] { load::(prefix.as_str(), "nation.tbl", index, peers, logical_batch, physical_batch, 2) } else { Vec::new() }; - let mut orders = if used[3] { load::(prefix.as_str(), "orders.tbl", index, peers, logical_batch, physical_batch, 3) } else { Vec::new() }; - let mut parts = if used[4] { load::(prefix.as_str(), "part.tbl", index, peers, logical_batch, physical_batch, 4) } else { Vec::new() }; - let mut partsupps = if used[5] { load::(prefix.as_str(), "partsupp.tbl", index, peers, logical_batch, physical_batch, 5) } else { Vec::new() }; - let mut regions = if used[6] { load::(prefix.as_str(), "region.tbl", index, peers, logical_batch, physical_batch, 6) } else { Vec::new() }; - let mut suppliers = if used[7] { load::(prefix.as_str(), "supplier.tbl", index, peers, logical_batch, physical_batch, 7) } else { Vec::new() }; - - let mut tuples = 0usize; - tuples += customers.iter().map(|x| x.len()).sum::(); - tuples += lineitems.iter().map(|x| x.len()).sum::(); - tuples += nations.iter().map(|x| x.len()).sum::(); - tuples += orders.iter().map(|x| x.len()).sum::(); - tuples += parts.iter().map(|x| x.len()).sum::(); - tuples += partsupps.iter().map(|x| x.len()).sum::(); - tuples += regions.iter().map(|x| x.len()).sum::(); - tuples += suppliers.iter().map(|x| x.len()).sum::(); - - // Synchronize before starting the timer. - let next_round = 1; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - - let timer = Instant::now(); - let mut round = 0; - while customers.len() > 0 || lineitems.len() > 0 || nations.len() > 0 || orders.len() > 0 || parts.len() > 0 || partsupps.len() > 0 || regions.len() > 0 || suppliers.len() > 0 { - - // introduce physical batch of data for each input with remaining data. - if let Some(mut data) = customers.pop() { inputs.0.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.0 = None; } } - if let Some(mut data) = lineitems.pop() { inputs.1.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.1 = None; } } - if let Some(mut data) = nations.pop() { inputs.2.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.2 = None; } } - if let Some(mut data) = orders.pop() { inputs.3.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.3 = None; } } - if let Some(mut data) = parts.pop() { inputs.4.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.4 = None; } } - if let Some(mut data) = partsupps.pop() { inputs.5.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.5 = None; } } - if let Some(mut data) = regions.pop() { inputs.6.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.6 = None; } } - if let Some(mut data) = suppliers.pop() { inputs.7.as_mut().map(|x| x.send_batch(&mut data)); } else { if seal { inputs.7 = None; } } - - // catch all inputs up to the same (next) round. - let next_round = 1 + 8 * (round + 1) * physical_batch; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - round += 1; - } - - // Finish outstanding work before stopping the timer. - let next_round = usize::MAX; - inputs.0.as_mut().map(|x| x.advance_to(next_round)); - inputs.1.as_mut().map(|x| x.advance_to(next_round)); - inputs.2.as_mut().map(|x| x.advance_to(next_round)); - inputs.3.as_mut().map(|x| x.advance_to(next_round)); - inputs.4.as_mut().map(|x| x.advance_to(next_round)); - inputs.5.as_mut().map(|x| x.advance_to(next_round)); - inputs.6.as_mut().map(|x| x.advance_to(next_round)); - inputs.7.as_mut().map(|x| x.advance_to(next_round)); - - let time = next_round; - worker.step_while(|| probe.less_than(&time)); - - let query_name = if query < 10 { format!("q0{}", query) } else { format!("q{}", query) }; - let elapsed = timer.elapsed(); - let nanos = elapsed.as_secs() * 1000000000 + elapsed.subsec_nanos() as u64; - if index == 0 { - let rate = ((peers * tuples) as f64) / (nanos as f64 / 1000000000.0); - // Query, Logical, Physical, Workers, Rate, Time - println!("{}\t{}\t{}\t{}\t{}\t{}", query_name, logical_batch, physical_batch, peers, rate, nanos); - // println!("query: {}, elapsed: {:?}, tuples: {:?}, rate: {:?}", query_name, timer.elapsed(), peers * tuples, ((peers * tuples) as f64) / (nanos as f64 / 1000000000.0)); - } - - }).unwrap(); -} - -// Returns a sequence of physical batches of ready-to-go timestamped data. Not clear that `input` can exploit the pre-arrangement yet. -fn load(prefix: &str, name: &str, index: usize, peers: usize, logical_batch: usize, physical_batch: usize, off: usize) - -> Vec> -where T: for<'a> From<&'a str> { - - let mut result = Vec::new(); - let mut buffer = Vec::new(); - - let path = format!("{}{}", prefix, name); - - let items_file = File::open(&path).expect("didn't find items file"); - let mut items_reader = BufReader::new(items_file); - let mut count = 0; - - let mut line = String::new(); - - while items_reader.read_line(&mut line).unwrap() > 0 { - - if count % peers == index { - - let logical = (8 * count / logical_batch) + off; - let physical = logical / physical_batch; - let round = physical / 8; - - while result.len() < round { - result.push(buffer); - buffer = Vec::with_capacity(2 + logical_batch * physical_batch / peers); - } - - let item = T::from(line.as_str()); - buffer.push((item, logical + 1, 1)); - } - - count += 1; - - line.clear(); - } - - if buffer.len() > 0 { - result.push(buffer); - } - - result.reverse(); - result -} diff --git a/tpchlike/src/lib.rs b/tpchlike/src/lib.rs deleted file mode 100644 index 2ed7f60954..0000000000 --- a/tpchlike/src/lib.rs +++ /dev/null @@ -1,280 +0,0 @@ -#[macro_use] -extern crate abomonation; -extern crate timely; -extern crate differential_dataflow; -extern crate arrayvec; -extern crate regex; - -use std::rc::Rc; - -use timely::dataflow::*; -use timely::dataflow::operators::CapabilitySet; - -use differential_dataflow::VecCollection; -use differential_dataflow::operators::arrange::ShutdownButton; - -pub mod types; -pub mod queries; - -pub use types::*; - -pub struct InputHandles { - pub customer: InputHandle, - pub lineitem: InputHandle, usize, isize)>, - pub nation: InputHandle, - pub order: InputHandle, - pub part: InputHandle, - pub partsupp: InputHandle, - pub region: InputHandle, - pub supplier: InputHandle, -} - -impl InputHandles { - pub fn new() -> Self { - Self { - customer: InputHandle::new(), - lineitem: InputHandle::new(), - nation: InputHandle::new(), - order: InputHandle::new(), - part: InputHandle::new(), - partsupp: InputHandle::new(), - region: InputHandle::new(), - supplier: InputHandle::new(), - } - } - pub fn advance_to(&mut self, round: usize) { - self.customer.advance_to(round); - self.lineitem.advance_to(round); - self.nation.advance_to(round); - self.order.advance_to(round); - self.part.advance_to(round); - self.partsupp.advance_to(round); - self.region.advance_to(round); - self.supplier.advance_to(round); - } - pub fn close(self) { - self.customer.close(); - self.lineitem.close(); - self.nation.close(); - self.order.close(); - self.part.close(); - self.partsupp.close(); - self.region.close(); - self.supplier.close(); - } -} - -pub struct Collections { - customers: VecCollection, - lineitems: VecCollection, isize>, - nations: VecCollection, - orders: VecCollection, - parts: VecCollection, - partsupps: VecCollection, - regions: VecCollection, - suppliers: VecCollection, - used: [bool; 8], -} - -impl Collections { - pub fn new( - customers: VecCollection, - lineitems: VecCollection, isize>, - nations: VecCollection, - orders: VecCollection, - parts: VecCollection, - partsupps: VecCollection, - regions: VecCollection, - suppliers: VecCollection, - ) -> Self { - - Collections { - customers: customers, - lineitems: lineitems, - nations: nations, - orders: orders, - parts: parts, - partsupps: partsupps, - regions: regions, - suppliers: suppliers, - used: [false; 8] - } - } - - pub fn customers(&mut self) -> VecCollection { self.used[0] = true; &self.customers } - pub fn lineitems(&mut self) -> VecCollection, isize> { self.used[1] = true; &self.lineitems } - pub fn nations(&mut self) -> VecCollection { self.used[2] = true; &self.nations } - pub fn orders(&mut self) -> VecCollection { self.used[3] = true; &self.orders } - pub fn parts(&mut self) -> VecCollection { self.used[4] = true; &self.parts } - pub fn partsupps(&mut self) -> VecCollection { self.used[5] = true; &self.partsupps } - pub fn regions(&mut self) -> VecCollection { self.used[6] = true; &self.regions } - pub fn suppliers(&mut self) -> VecCollection { self.used[7] = true; &self.suppliers } - - pub fn used(&self) -> [bool; 8] { self.used } -} - - -use differential_dataflow::trace::implementations::ValSpine; -use differential_dataflow::operators::arrange::{Arranged, TraceAgent}; - -type ArrangedScope = Arranged>; -type ArrangedIndex = TraceAgent>; - -pub struct ArrangementsInScope> { - customer: ArrangedScope, - nation: ArrangedScope, - order: ArrangedScope, - part: ArrangedScope, - partsupp: ArrangedScope, - region: ArrangedScope, - supplier: ArrangedScope, -} - -pub struct Arrangements { - arrange: bool, - customer: ArrangedIndex, - nation: ArrangedIndex, - order: ArrangedIndex, - part: ArrangedIndex, - partsupp: ArrangedIndex<(usize, usize), PartSupp>, - region: ArrangedIndex, - supplier: ArrangedIndex, -} - -use timely::dataflow::Scope; - -impl Arrangements { - - pub fn new>(inputs: &mut InputHandles, scope: &mut G, probe: &mut ProbeHandle, arrange: bool) -> Self { - - use timely::dataflow::operators::Input; - use timely::dataflow::operators::Probe; - use differential_dataflow::AsCollection; - use differential_dataflow::trace::TraceReader; - - let empty_frontier = timely::progress::Antichain::new(); - let empty_frontier = empty_frontier.borrow(); - let mut arranged = scope.input_from(&mut inputs.customer).as_collection().map(|x| (x.cust_key, x)).arrange_by_key(); - arranged.stream.probe_with(probe); - arranged.trace.set_physical_compaction(empty_frontier); - let customer = arranged.trace; - - let mut arranged = scope.input_from(&mut inputs.nation).as_collection().map(|x| (x.nation_key, x)).arrange_by_key(); - arranged.stream.probe_with(probe); - arranged.trace.set_physical_compaction(empty_frontier); - let nation = arranged.trace; - - let mut arranged = scope.input_from(&mut inputs.order).as_collection().map(|x| (x.order_key, x)).arrange_by_key(); - arranged.stream.probe_with(probe); - arranged.trace.set_physical_compaction(empty_frontier); - let order = arranged.trace; - - let mut arranged = scope.input_from(&mut inputs.part).as_collection().map(|x| (x.part_key, x)).arrange_by_key(); - arranged.stream.probe_with(probe); - arranged.trace.set_physical_compaction(empty_frontier); - let part = arranged.trace; - - let mut arranged = scope.input_from(&mut inputs.partsupp).as_collection().map(|x| ((x.part_key, x.supp_key), x)).arrange_by_key(); - arranged.stream.probe_with(probe); - arranged.trace.set_physical_compaction(empty_frontier); - let partsupp = arranged.trace; - - let mut arranged = scope.input_from(&mut inputs.region).as_collection().map(|x| (x.region_key, x)).arrange_by_key(); - arranged.stream.probe_with(probe); - arranged.trace.set_physical_compaction(empty_frontier); - let region = arranged.trace; - - let mut arranged = scope.input_from(&mut inputs.supplier).as_collection().map(|x| (x.supp_key, x)).arrange_by_key(); - arranged.stream.probe_with(probe); - arranged.trace.set_physical_compaction(empty_frontier); - let supplier = arranged.trace; - - Arrangements { - arrange, - customer, - nation, - order, - part, - partsupp, - region, - supplier, - } - } - - pub fn in_scope>(&mut self, scope: &mut G, experiment: &mut Experiment) -> ArrangementsInScope { - let (mut customer, button) = self.customer.import_core(scope, "customer"); - if !self.arrange { customer = customer.as_collection(|&k,v| (k,v.clone())).arrange_by_key(); } - experiment.buttons.push(button); - let (mut nation, button) = self.nation.import_core(scope, "nation"); - if !self.arrange { nation = nation.as_collection(|&k,v| (k,v.clone())).arrange_by_key(); } - experiment.buttons.push(button); - let (mut order, button) = self.order.import_core(scope, "order"); - if !self.arrange { order = order.as_collection(|&k,v| (k,v.clone())).arrange_by_key(); } - experiment.buttons.push(button); - let (mut part, button) = self.part.import_core(scope, "part"); - if !self.arrange { part = part.as_collection(|&k,v| (k,v.clone())).arrange_by_key(); } - experiment.buttons.push(button); - let (mut partsupp, button) = self.partsupp.import_core(scope, "partsupp"); - if !self.arrange { partsupp = partsupp.as_collection(|&k,v| (k,v.clone())).arrange_by_key(); } - experiment.buttons.push(button); - let (mut region, button) = self.region.import_core(scope, "region"); - if !self.arrange { region = region.as_collection(|&k,v| (k,v.clone())).arrange_by_key(); } - experiment.buttons.push(button); - let (mut supplier, button) = self.supplier.import_core(scope, "supplier"); - if !self.arrange { supplier = supplier.as_collection(|&k,v| (k,v.clone())).arrange_by_key(); } - experiment.buttons.push(button); - - ArrangementsInScope { - customer, - nation, - order, - part, - partsupp, - region, - supplier, - } - } - - pub fn set_logical_compaction(&mut self, frontier: &[usize]) { - - use differential_dataflow::trace::TraceReader; - use timely::progress::frontier::AntichainRef; - let frontier = AntichainRef::new(frontier); - self.customer.set_logical_compaction(frontier); - self.nation.set_logical_compaction(frontier); - self.order.set_logical_compaction(frontier); - self.part.set_logical_compaction(frontier); - self.partsupp.set_logical_compaction(frontier); - self.region.set_logical_compaction(frontier); - self.supplier.set_logical_compaction(frontier); - } -} - -use std::rc::Weak; -pub struct Experiment { - pub index: usize, - pub token: Weak<()>, - pub lineitem: InputHandle, usize, isize)>, - pub buttons: Vec>>, -} - -impl Experiment { - pub fn new(index: usize, token: &Rc<()>) -> Self { - Self { - index, - token: std::rc::Rc::downgrade(token), - lineitem: InputHandle::new(), - buttons: Vec::new(), - } - } - pub fn lineitem>(&mut self, scope: &mut G) -> VecCollection, isize> { - use timely::dataflow::operators::Input; - use differential_dataflow::AsCollection; - scope.input_from(&mut self.lineitem).as_collection() - } - pub fn close(mut self) -> Weak<()> { - self.lineitem.close(); - for mut button in self.buttons.drain(..) { button.press(); } - self.token - } -} diff --git a/tpchlike/src/queries/mod.rs b/tpchlike/src/queries/mod.rs deleted file mode 100644 index 92d009c2c1..0000000000 --- a/tpchlike/src/queries/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -pub mod query01; -pub mod query02; -pub mod query03; -pub mod query04; -pub mod query05; -pub mod query06; -pub mod query07; -pub mod query08; -pub mod query09; -pub mod query10; -pub mod query11; -pub mod query12; -pub mod query13; -pub mod query14; -pub mod query15; -pub mod query16; -pub mod query17; -pub mod query18; -pub mod query19; -pub mod query20; -pub mod query21; -pub mod query22; diff --git a/tpchlike/src/queries/query01.rs b/tpchlike/src/queries/query01.rs deleted file mode 100644 index 530040a278..0000000000 --- a/tpchlike/src/queries/query01.rs +++ /dev/null @@ -1,90 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::difference::DiffPair; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Pricing Summary Report Query (Q1) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// l_returnflag, -// l_linestatus, -// sum(l_quantity) as sum_qty, -// sum(l_extendedprice) as sum_base_price, -// sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, -// sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, -// avg(l_quantity) as avg_qty, -// avg(l_extendedprice) as avg_price, -// avg(l_discount) as avg_disc, -// count(*) as count_order -// from -// lineitem -// where -// l_shipdate <= date '1998-12-01' - interval ':1' day (3) -// group by -// l_returnflag, -// l_linestatus -// order by -// l_returnflag, -// l_linestatus; -// :n -1 - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - collections - .lineitems() - .explode(|item| - if item.ship_date <= ::types::create_date(1998, 9, 2) { - Some(((item.return_flag[0], item.line_status[0]), - DiffPair::new(item.quantity as isize, - DiffPair::new(item.extended_price as isize, - DiffPair::new((item.extended_price * (100 - item.discount) / 100) as isize, - DiffPair::new((item.extended_price * (100 - item.discount) * (100 + item.tax) / 10000) as isize, - DiffPair::new(item.discount as isize, 1))))))) - } - else { - None - } - ) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - _arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - experiment - .lineitem(scope) - .explode(|item| - if item.ship_date <= ::types::create_date(1998, 9, 2) { - Some(((item.return_flag[0], item.line_status[0]), - DiffPair::new(item.quantity as isize, - DiffPair::new(item.extended_price as isize, - DiffPair::new((item.extended_price * (100 - item.discount) / 100) as isize, - DiffPair::new((item.extended_price * (100 - item.discount) * (100 + item.tax) / 10000) as isize, - DiffPair::new(item.discount as isize, 1))))))) - } - else { - None - } - ) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query02.rs b/tpchlike/src/queries/query02.rs deleted file mode 100644 index 13fb29550e..0000000000 --- a/tpchlike/src/queries/query02.rs +++ /dev/null @@ -1,167 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Minimum Cost Supplier Query (Q2) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// s_acctbal, -// s_name, -// n_name, -// p_partkey, -// p_mfgr, -// s_address, -// s_phone, -// s_comment -// from -// part, -// supplier, -// partsupp, -// nation, -// region -// where -// p_partkey = ps_partkey -// and s_suppkey = ps_suppkey -// and p_size = :1 -// and p_type like '%:2' -// and s_nationkey = n_nationkey -// and n_regionkey = r_regionkey -// and r_name = ':3' -// and ps_supplycost = ( -// select -// min(ps_supplycost) -// from -// partsupp, -// supplier, -// nation, -// region -// where -// p_partkey = ps_partkey -// and s_suppkey = ps_suppkey -// and s_nationkey = n_nationkey -// and n_regionkey = r_regionkey -// and r_name = ':3' -// ) -// order by -// s_acctbal desc, -// n_name, -// s_name, -// p_partkey; -// :n 100 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -fn substring(source: &[u8], query: &[u8]) -> bool { - (0 .. (source.len() - query.len())).any(|offset| - (0 .. query.len()).all(|i| source[i + offset] == query[i]) - ) -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let regions = - collections - .regions() - .flat_map(|x| if starts_with(&x.name[..], b"EUROPE") { Some(x.region_key) } else { None }); - - let nations = - collections - .nations() - .map(|x| (x.region_key, (x.nation_key, x.name))) - .semijoin(regions) - .map(|(_region_key, (nation_key, name))| (nation_key, name)); - - let suppliers = - collections - .suppliers() - .map(|x| (x.nation_key, (x.acctbal, x.name, x.address, x.phone, x.comment, x.supp_key))) - .semijoin(nations.map(|x| x.0)) - .map(|(nat, (acc, nam, add, phn, com, key))| (key, (nat, acc, nam, add, phn, com))); - - let parts = - collections - .parts() - .flat_map(|x| if substring(x.typ.as_str().as_bytes(), b"BRASS") && x.size == 15 { Some((x.part_key, x.mfgr)) } else { None }); - - let partsupps = - collections - .partsupps() - .map(|x| (x.supp_key, (x.part_key, x.supplycost))) - .semijoin(suppliers.map(|x| x.0)) - .map(|(supp, (part, supply_cost))| (part, (supply_cost, supp))) - .semijoin(parts.map(|x| x.0)) - .reduce(|_x, s, t| { - let minimum = (s[0].0).0; - t.extend(s.iter().take_while(|x| (x.0).0 == minimum).map(|&(&x,w)| (x,w))); - }); - - partsupps - .join(parts) - .map(|(part_key, ((cost, supp), mfgr))| (supp, (cost, part_key, mfgr))) - .join(suppliers) - .map(|(_supp, ((cost, part, mfgr), (nat, acc, nam, add, phn, com)))| (nat, (cost, part, mfgr, acc, nam, add, phn, com))) - .join(nations) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, - round: usize, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - use timely::dataflow::operators::Map; - use differential_dataflow::AsCollection; - - let arrangements = arrangements.in_scope(scope, experiment); - - let relevant_suppliers = - arrangements - .partsupp - .as_collection(|_,x| (x.supp_key, (x.part_key, x.supplycost))) - .inner - .map(move |(d,t,r)| (d, ::std::cmp::max(t,round),r)) - .as_collection() - .join_core(arrangements.supplier, |&sk, &(pk,sc), s| Some((s.nation_key, (pk,sc,sk)))) - .join_core(arrangements.nation, |_nk, &(pk,sc,sk), n| Some((n.region_key, (pk,sc,sk,n.name)))) - .join_core(arrangements.region, |_rk, &(pk,sc,sk,nm), r| { - if starts_with(&r.name[..], b"EUROPE") { Some((pk,(sc,sk,nm))) } else { None } - }); - - let cheapest_suppliers = - relevant_suppliers - .reduce(|_pk, s, t| { - let minimum = (s[0].0).0; - t.extend(s.iter().take_while(|x| (x.0).0 == minimum).map(|&(&x,w)| (x,w))); - }); - - cheapest_suppliers - .join_core(arrangements.part, |&pk,&(sc,sk,nm),p| { - if substring(p.typ.as_str().as_bytes(), b"BRASS") && p.size == 15 { - Some((sk, (sc,pk,nm,p.mfgr))) - } - else { - None - } - }) - .join_core(arrangements.supplier, |_sk,&(sc,pk,nm,pm),s| { - Some((sc,pk,nm,pm,s.acctbal,s.name,s.address,s.phone,s.comment)) - }) - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query03.rs b/tpchlike/src/queries/query03.rs deleted file mode 100644 index 8941e735a5..0000000000 --- a/tpchlike/src/queries/query03.rs +++ /dev/null @@ -1,115 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; -use ::types::create_date; - -// -- $ID$ -// -- TPC-H/TPC-R Shipping Priority Query (Q3) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// l_orderkey, -// sum(l_extendedprice * (1 - l_discount)) as revenue, -// o_orderdate, -// o_shippriority -// from -// customer, -// orders, -// lineitem -// where -// c_mktsegment = ':1' -// and c_custkey = o_custkey -// and l_orderkey = o_orderkey -// and o_orderdate < date ':2' -// and l_shipdate > date ':2' -// group by -// l_orderkey, -// o_orderdate, -// o_shippriority -// order by -// revenue desc, -// o_orderdate; -// :n 10 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let customers = - collections - .customers() - .flat_map(|c| if starts_with(&c.mktsegment[..], b"BUILDING") { Some(c.cust_key) } else { None }); - - let lineitems = - collections - .lineitems() - .explode(|l| - if l.ship_date > create_date(1995, 3, 15) { - Some((l.order_key, (l.extended_price * (100 - l.discount) / 100) as isize)) - } - else { None } - ); - - let orders = - collections - .orders() - .filter(|o| o.order_date < create_date(1995, 3, 15)) - .map(|o| (o.cust_key, (o.order_key, o.order_date, o.ship_priority))); - - orders - .semijoin(customers) - .map(|(_, (order_key, order_date, ship_priority))| (order_key, (order_date, ship_priority))) - .semijoin(lineitems) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .explode(|l| - if l.ship_date > create_date(1995, 3, 15) { - Some(((l.order_key, ()), (l.extended_price * (100 - l.discount) / 100) as isize)) - } - else { None } - ) - .join_core(arrangements.order, |_k, &(), o| { - if o.order_date < create_date(1995, 3, 15) { - Some((o.cust_key, (o.order_key, o.order_date, o.ship_priority))) - } - else { - None - } - }) - .join_core(arrangements.customer, |_k,o,c| { - if starts_with(&c.mktsegment[..], b"BUILDING") { - Some(o.clone()) - } - else { - None - } - }) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query04.rs b/tpchlike/src/queries/query04.rs deleted file mode 100644 index 49c2bd1fc9..0000000000 --- a/tpchlike/src/queries/query04.rs +++ /dev/null @@ -1,88 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Order Priority Checking Query (Q4) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// o_orderpriority, -// count(*) as order_count -// from -// orders -// where -// o_orderdate >= date ':1' -// and o_orderdate < date ':1' + interval '3' month -// and exists ( -// select -// * -// from -// lineitem -// where -// l_orderkey = o_orderkey -// and l_commitdate < l_receiptdate -// ) -// group by -// o_orderpriority -// order by -// o_orderpriority; -// :n -1 - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let lineitems = - collections - .lineitems() - .flat_map(|l| if l.commit_date < l.receipt_date { Some(l.order_key) } else { None }) - .distinct_total(); - - collections - .orders() - .flat_map(|o| - if o.order_date >= ::types::create_date(1993, 7, 1) && o.order_date < ::types::create_date(1993, 10, 1) { - Some((o.order_key, o.order_priority)) - } - else { None } - ) - .semijoin(lineitems) - .map(|(_k,v)| v) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .flat_map(|l| if l.commit_date < l.receipt_date { Some((l.order_key, ())) } else { None }) - .distinct_total() - .join_core(arrangements.order, |_k,&(),o| { - if o.order_date >= ::types::create_date(1993, 7, 1) && o.order_date < ::types::create_date(1993, 10, 1) { - Some(o.order_priority) - } - else { - None - } - }) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query05.rs b/tpchlike/src/queries/query05.rs deleted file mode 100644 index b66eb99fe1..0000000000 --- a/tpchlike/src/queries/query05.rs +++ /dev/null @@ -1,137 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; -use ::types::create_date; - -// -- $ID$ -// -- TPC-H/TPC-R Local Supplier Volume Query (Q5) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// n_name, -// sum(l_extendedprice * (1 - l_discount)) as revenue -// from -// customer, -// orders, -// lineitem, -// supplier, -// nation, -// region -// where -// c_custkey = o_custkey -// and l_orderkey = o_orderkey -// and l_suppkey = s_suppkey -// and c_nationkey = s_nationkey -// and s_nationkey = n_nationkey -// and n_regionkey = r_regionkey -// and r_name = ':1' -// and o_orderdate >= date ':2' -// and o_orderdate < date ':2' + interval '1' year -// group by -// n_name -// order by -// revenue desc; -// :n -1 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let regions = - collections - .regions() - .filter(|x| starts_with(&x.name[..], b"ASIA")) - .map(|x| x.region_key); - - let nations = - collections - .nations() - .map(|x| (x.region_key, x.nation_key)) - .semijoin(regions) - .map(|(_region_key, nation_key)| nation_key); - - let suppliers = - collections - .suppliers() - .map(|x| (x.nation_key, x.supp_key)) - .semijoin(nations) - .map(|(_nat, supp)| (supp, _nat)); - - let customers = - collections - .customers() - .map(|c| (c.nation_key, c.cust_key)) - .semijoin(nations) - .map(|c| (c.1, c.0)); - - let orders = - collections - .orders() - .flat_map(|o| - if o.order_date >= create_date(1994, 1, 1) && o.order_date < create_date(1995, 1, 1) { - Some((o.cust_key, o.order_key)) - } - else { None } - ) - .join(customers) - .map(|o| o.1); - - let lineitems = collections - .lineitems() - .explode(|l| Some(((l.order_key, l.supp_key), (l.extended_price * (100 - l.discount) / 100) as isize))) - .join(orders) - .map(|(_order, (supp, nat))| (supp, nat)); - - suppliers - .map(|x| (x, ())) - .semijoin(lineitems) - .map(|((_supp, nat), ())| nat) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .explode(|l| Some(((l.order_key, l.supp_key), (l.extended_price * (100 - l.discount) / 100) as isize))) - .join_core(arrangements.order, |_ok, &sk, o| { - if o.order_date >= create_date(1994, 1, 1) && o.order_date < create_date(1995, 1, 1) { - Some((o.cust_key, sk)) - } - else { None } - }) - .join_core(arrangements.customer, |_ck, &sk, c| Some((sk,c.nation_key))) - .join_core(arrangements.supplier, |_sk, &nk, s| { - if s.nation_key == nk { - Some((nk, ())) - } - else { None } - }) - .join_core(arrangements.nation, |_nk, &(), n| Some((n.region_key, n.name))) - .join_core(arrangements.region, |_rk, &name, r| { - if starts_with(&r.name[..], b"ASIA") { Some(name) } else { None } - }) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query06.rs b/tpchlike/src/queries/query06.rs deleted file mode 100644 index bb27b3f8ec..0000000000 --- a/tpchlike/src/queries/query06.rs +++ /dev/null @@ -1,63 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; -use ::types::create_date; - -// -- $ID$ -// -- TPC-H/TPC-R Forecasting Revenue Change Query (Q6) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// sum(l_extendedprice * l_discount) as revenue -// from -// lineitem -// where -// l_shipdate >= date ':1' -// and l_shipdate < date ':1' + interval '1' year -// and l_discount between :2 - 0.01 and :2 + 0.01 -// and l_quantity < :3; -// :n -1 - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - collections - .lineitems() - .explode(|x| { - if (create_date(1994, 1, 1) <= x.ship_date) && (x.ship_date < create_date(1995, 1, 1)) && (5 <= x.discount) && (x.discount <= 7) && (x.quantity < 24) { - Some(((), (x.extended_price * x.discount / 100) as isize)) - } - else { None } - }) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - _arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - experiment - .lineitem(scope) - .explode(|x| { - if (create_date(1994, 1, 1) <= x.ship_date) && (x.ship_date < create_date(1995, 1, 1)) && (5 <= x.discount) && (x.discount <= 7) && (x.quantity < 24) { - Some(((), (x.extended_price * x.discount / 100) as isize)) - } - else { None } - }) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query07.rs b/tpchlike/src/queries/query07.rs deleted file mode 100644 index a92c121670..0000000000 --- a/tpchlike/src/queries/query07.rs +++ /dev/null @@ -1,148 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; -use ::types::create_date; - -// -- $ID$ -// -- TPC-H/TPC-R Volume Shipping Query (Q7) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// supp_nation, -// cust_nation, -// l_year, -// sum(volume) as revenue -// from -// ( -// select -// n1.n_name as supp_nation, -// n2.n_name as cust_nation, -// extract(year from l_shipdate) as l_year, -// l_extendedprice * (1 - l_discount) as volume -// from -// supplier, -// lineitem, -// orders, -// customer, -// nation n1, -// nation n2 -// where -// s_suppkey = l_suppkey -// and o_orderkey = l_orderkey -// and c_custkey = o_custkey -// and s_nationkey = n1.n_nationkey -// and c_nationkey = n2.n_nationkey -// and ( -// (n1.n_name = ':1' and n2.n_name = ':2') -// or (n1.n_name = ':2' and n2.n_name = ':1') -// ) -// and l_shipdate between date '1995-01-01' and date '1996-12-31' -// ) as shipping -// group by -// supp_nation, -// cust_nation, -// l_year -// order by -// supp_nation, -// cust_nation, -// l_year; -// :n -1 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - println!("TODO: Q07 could use `join_core` to fuse map and filter"); - - let nations = - collections - .nations() - .filter(|n| starts_with(&n.name, b"FRANCE") || starts_with(&n.name, b"GERMANY")) - .map(|n| (n.nation_key, n.name)); - - let customers = - collections - .customers() - .map(|c| (c.nation_key, c.cust_key)) - .join_map(nations, |_, &cust_key, &name| (cust_key, name)); - - let orders = - collections - .orders() - .map(|o| (o.cust_key, o.order_key)) - .join_map(customers, |_, &order_key, &name| (order_key, name)); - - let suppliers = - collections - .suppliers() - .map(|s| (s.nation_key, s.supp_key)) - .join_map(nations, |_, &supp_key, &name| (supp_key, name)); - - collections - .lineitems() - .explode(|l| - if create_date(1995, 1, 1) <= l.ship_date && l.ship_date <= create_date(1996, 12, 31) { - Some(((l.supp_key, (l.order_key, l.ship_date)), (l.extended_price * (100 - l.discount)) as isize / 100)) - } - else { None } - ) - .join_map(suppliers, |_, &(order_key, ship_date), &name_s| (order_key, (ship_date, name_s))) - .join_map(orders, |_, &(ship_date, name_s), &name_c| (name_s, name_c, ship_date >> 16)) - .filter(|x| x.0 != x.1) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .explode(|l| - if create_date(1995, 1, 1) <= l.ship_date && l.ship_date <= create_date(1996, 12, 31) { - Some(((l.supp_key, (l.order_key, l.ship_date >> 16)), (l.extended_price * (100 - l.discount)) as isize / 100)) - } - else { None } - ) - .join_core(arrangements.supplier, |_sk,&(ok,sd),s| Some((s.nation_key,(ok,sd)))) - .join_core(arrangements.nation, |_nk,&(ok,sd),n| { - if starts_with(&n.name, b"FRANCE") || starts_with(&n.name, b"GERMANY") { - Some((ok,(sd,n.name))) - } - else { - None - } - }) - .join_core(arrangements.order, |_ok,&(sd,n1),o| Some((o.cust_key,(sd,n1)))) - .join_core(arrangements.customer, |_ck,&(sd,n1),c| Some((c.nation_key,(sd,n1)))) - .join_core(arrangements.nation, |_nk,&(sd,n1),n| { - if starts_with(&n.name, b"FRANCE") || starts_with(&n.name, b"GERMANY") { - Some((sd,n1,n.name)) - } - else { - None - } - }) - .filter(|&(_sd,n1,n2)| n1 != n2) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query08.rs b/tpchlike/src/queries/query08.rs deleted file mode 100644 index c7e34843b4..0000000000 --- a/tpchlike/src/queries/query08.rs +++ /dev/null @@ -1,136 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::difference::DiffPair; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; -use ::types::create_date; - -// -- $ID$ -// -- TPC-H/TPC-R National Market Share Query (Q8) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// o_year, -// sum(case -// when nation = ':1' then volume -// else 0 -// end) / sum(volume) as mkt_share -// from -// ( -// select -// extract(year from o_orderdate) as o_year, -// l_extendedprice * (1 - l_discount) as volume, -// n2.n_name as nation -// from -// part, -// supplier, -// lineitem, -// orders, -// customer, -// nation n1, -// nation n2, -// region -// where -// p_partkey = l_partkey -// and s_suppkey = l_suppkey -// and l_orderkey = o_orderkey -// and o_custkey = c_custkey -// and c_nationkey = n1.n_nationkey -// and n1.n_regionkey = r_regionkey -// and r_name = ':2' -// and s_nationkey = n2.n_nationkey -// and o_orderdate between date '1995-01-01' and date '1996-12-31' -// and p_type = ':3' -// ) as all_nations -// group by -// o_year -// order by -// o_year; -// :n -1 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let regions = collections.regions().filter(|r| starts_with(&r.name, b"AMERICA")).map(|r| r.region_key); - let nations1 = collections.nations().map(|n| (n.region_key, n.nation_key)).semijoin(regions).map(|x| x.1); - let customers = collections.customers().map(|c| (c.nation_key, c.cust_key)).semijoin(nations1).map(|x| x.1); - let orders = - collections - .orders() - .flat_map(|o| - if create_date(1995,1,1) <= o.order_date && o.order_date <= create_date(1996, 12, 31) { - Some((o.cust_key, (o.order_key, o.order_date >> 16))) - } - else { None } - ) - .semijoin(customers) - .map(|x| x.1); - - let nations2 = collections.nations.map(|n| (n.nation_key, starts_with(&n.name, b"BRAZIL"))); - let suppliers = - collections - .suppliers() - .map(|s| (s.nation_key, s.supp_key)) - .join(nations2) - .map(|(_, (supp_key, is_name))| (supp_key, is_name)); - - let parts = collections.parts().filter(|p| p.typ.as_str() == "ECONOMY ANODIZED STEEL").map(|p| p.part_key); - - collections - .lineitems() - .explode(|l| Some(((l.part_key, (l.supp_key, l.order_key)), ((l.extended_price * (100 - l.discount)) as isize / 100)))) - .semijoin(parts) - .map(|(_part_key, (supp_key, order_key))| (order_key, supp_key)) - .join(orders) - .map(|(_order_key, (supp_key, order_date))| (supp_key, order_date)) - .join(suppliers) - .explode(|(_, (order_date, is_name))| Some((order_date, DiffPair::new(if is_name { 1 } else { 0 }, 1)))) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .explode(|l| Some(((l.part_key, (l.order_key, l.supp_key)), ((l.extended_price * (100 - l.discount)) as isize / 100)))) - .join_core(arrangements.part, |_pk,&(ok,sk),p| { - if p.typ.as_str() == "ECONOMY ANODIZED STEEL" { Some((ok,sk)) } else { None } - }) - .join_core(arrangements.order, |_ok,&sk,o| { - if create_date(1995,1,1) <= o.order_date && o.order_date <= create_date(1996, 12, 31) { - Some((o.cust_key, (sk,o.order_date >> 16))) - } - else { None } - }) - .join_core(arrangements.customer, |_ck,&(sk,yr),c| Some((c.nation_key, (sk,yr)))) - .join_core(arrangements.nation, |_nk,&(sk,yr),n| Some((n.region_key, (sk,yr)))) - .join_core(arrangements.region, |_rk,&(sk,yr),r| { - if starts_with(&r.name, b"AMERICA") { Some((sk,yr,true)) } else { Some((sk,yr,false)) } - }) - .explode(|(sk,yr,is_name)| Some(((sk,yr), DiffPair::new(if is_name { 1 } else { 0 }, 1)))) - .join_core(arrangements.supplier, |_sk,&yr,s| Some((s.nation_key, yr))) - .join_core(arrangements.nation, |_nk,&yr,n| Some((n.name,yr))) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query09.rs b/tpchlike/src/queries/query09.rs deleted file mode 100644 index 426a2d8f9c..0000000000 --- a/tpchlike/src/queries/query09.rs +++ /dev/null @@ -1,109 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Product Type Profit Measure Query (Q9) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// nation, -// o_year, -// sum(amount) as sum_profit -// from -// ( -// select -// n_name as nation, -// extract(year from o_orderdate) as o_year, -// l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount -// from -// part, -// supplier, -// lineitem, -// partsupp, -// orders, -// nation -// where -// s_suppkey = l_suppkey -// and ps_suppkey = l_suppkey -// and ps_partkey = l_partkey -// and p_partkey = l_partkey -// and o_orderkey = l_orderkey -// and s_nationkey = n_nationkey -// and p_name like '%:1%' -// ) as profit -// group by -// nation, -// o_year -// order by -// nation, -// o_year desc; -// :n -1 - -fn substring(source: &[u8], query: &[u8]) -> bool { - (0 .. (source.len() - query.len())).any(|offset| - (0 .. query.len()).all(|i| source[i + offset] == query[i]) - ) -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - println!("TODO: Q09 join order may be pessimal; could pivot to put lineitems last"); - - let parts = - collections - .parts() - .flat_map(|x| if substring(&x.name.as_bytes(), b"green") { Some(x.part_key) } else { None } ); - - collections - .lineitems() - .map(|l| (l.part_key, (l.supp_key, l.order_key, l.extended_price * (100 - l.discount) / 100, l.quantity))) - .semijoin(parts) - .map(|(part_key, (supp_key, order_key, revenue, quantity))| ((part_key, supp_key), (order_key, revenue, quantity))) - .join(collections.partsupps().map(|ps| ((ps.part_key, ps.supp_key), ps.supplycost))) - .explode(|((_part_key, supp_key), ((order_key, revenue, quantity), supplycost))| - Some(((order_key, supp_key), ((revenue - supplycost * quantity) as isize))) - ) - .join_map(collections.orders().map(|o| (o.order_key, o.order_date >> 16)), |_, &supp_key, &order_year| (supp_key, order_year)) - .join_map(collections.suppliers().map(|s| (s.supp_key, s.nation_key)), |_, &order_year, &nation_key| (nation_key, order_year)) - .join(collections.nations().map(|n| (n.nation_key, n.name))) - .count_total() - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .map(|l| (l.part_key, (l.supp_key, l.order_key, l.extended_price * (100 - l.discount) / 100, l.quantity))) - .join_core(arrangements.part, |&pk,&(sk,ok,ep,qu),p| { - if substring(&p.name.as_bytes(), b"green") { - Some(((pk,sk),(ok,ep,qu))) - } - else { None } - }) - .join_core(arrangements.partsupp, |&(_pk,sk),&(ok,ep,qu),s| Some((ok, (sk, ep - (qu * s.supplycost))))) - .explode(|(ok,(sk,am))| Some(((ok,sk), am as isize))) - .join_core(arrangements.order, |_ok,&sk,o| Some((sk,o.order_date >> 16))) - .join_core(arrangements.supplier, |_sk,&yr,s| Some((s.nation_key, yr))) - .join_core(arrangements.nation, |_nk,&yr,n| Some((n.name,yr))) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query10.rs b/tpchlike/src/queries/query10.rs deleted file mode 100644 index b9874d9bf8..0000000000 --- a/tpchlike/src/queries/query10.rs +++ /dev/null @@ -1,122 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; -use ::types::create_date; - -// -- $ID$ -// -- TPC-H/TPC-R Returned Item Reporting Query (Q10) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// c_custkey, -// c_name, -// sum(l_extendedprice * (1 - l_discount)) as revenue, -// c_acctbal, -// n_name, -// c_address, -// c_phone, -// c_comment -// from -// customer, -// orders, -// lineitem, -// nation -// where -// c_custkey = o_custkey -// and l_orderkey = o_orderkey -// and o_orderdate >= date ':1' -// and o_orderdate < date ':1' + interval '3' month -// and l_returnflag = 'R' -// and c_nationkey = n_nationkey -// group by -// c_custkey, -// c_name, -// c_acctbal, -// c_phone, -// n_name, -// c_address, -// c_comment -// order by -// revenue desc; -// :n 20 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let lineitems = - collections - .lineitems() - .explode(|x| - if starts_with(&x.return_flag, b"R") { - Some((x.order_key, (x.extended_price * (100 - x.discount)) as isize)) - } - else { None } - ); - - let orders = - collections - .orders() - .flat_map(|o| - if create_date(1993,10,1) < o.order_date && o.order_date <= create_date(1994,1,1) { - Some((o.order_key, o.cust_key)) - } - else { None } - ) - .semijoin(lineitems) - .map(|(_, cust_key)| cust_key); - - collections - .customers() - .map(|c| (c.cust_key, (c.name, c.phone, c.address, c.comment, c.nation_key))) - .semijoin(orders) - .map(|(cust_key, (name, phn, addr, comm, nation_key))| (nation_key, (cust_key, name, phn, addr, comm))) - .join(collections.nations().map(|n| (n.nation_key, n.name))) - .count_total() - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .explode(|x| - if starts_with(&x.return_flag, b"R") { - Some((x.order_key, (x.extended_price * (100 - x.discount)) as isize)) - } - else { None } - ) - .arrange_by_self() - .join_core(arrangements.order, |_ok,&(),o| { - if create_date(1993,10,1) < o.order_date && o.order_date <= create_date(1994,1,1) { - Some(o.cust_key) - } - else { None } - }) - .arrange_by_self() - .join_core(arrangements.customer, |&ck,&(),c| { - Some((c.nation_key, (ck,c.name,c.acctbal,c.address,c.phone,c.comment))) - }) - .join_core(arrangements.nation, |_nk,&data,n| Some((n.name, data))) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query11.rs b/tpchlike/src/queries/query11.rs deleted file mode 100644 index ff505242a4..0000000000 --- a/tpchlike/src/queries/query11.rs +++ /dev/null @@ -1,112 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Important Stock Identification Query (Q11) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// ps_partkey, -// sum(ps_supplycost * ps_availqty) as value -// from -// partsupp, -// supplier, -// nation -// where -// ps_suppkey = s_suppkey -// and s_nationkey = n_nationkey -// and n_name = ':1' -// group by -// ps_partkey having -// sum(ps_supplycost * ps_availqty) > ( -// select -// sum(ps_supplycost * ps_availqty) * :2 -// from -// partsupp, -// supplier, -// nation -// where -// ps_suppkey = s_suppkey -// and s_nationkey = n_nationkey -// and n_name = ':1' -// ) -// order by -// value desc; -// :n -1 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let nations = - collections - .nations() - .filter(|n| starts_with(&n.name, b"GERMANY")) - .map(|n| n.nation_key); - - let suppliers = - collections - .suppliers() - .map(|s| (s.nation_key, s.supp_key)) - .semijoin(nations) - .map(|s| s.1); - - collections - .partsupps() - .explode(|x| Some(((x.supp_key, x.part_key), (x.supplycost as isize) * (x.availqty as isize)))) - .semijoin(suppliers) - .map(|(_, part_key)| ((), part_key)) - .reduce(|_part_key, s, t| { - let threshold: isize = s.iter().map(|x| x.1 as isize).sum::() / 10000; - t.extend(s.iter().filter(|x| x.1 > threshold).map(|&(&a,b)| (a, b))); - }) - .map(|(_, part_key)| part_key) - .count_total() - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, - round: usize, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - use timely::dataflow::operators::Map; - use differential_dataflow::AsCollection; - - let arrangements = arrangements.in_scope(scope, experiment); - - arrangements - .partsupp - .as_collection(|_,ps| ((ps.supp_key, ps.part_key), (ps.supplycost as isize) * (ps.availqty as isize))) - .inner - .map(move |(d,t,r)| (d, ::std::cmp::max(t,round),r)) - .as_collection() - .explode(|((sk,pk),prod)| Some(((sk,pk),prod))) - .join_core(arrangements.supplier, |_sk,&pk,s| Some((s.nation_key, pk))) - .join_core(arrangements.nation, |_nk,&pk,n| - if starts_with(&n.name, b"GERMANY") { Some(((), pk)) } else { None } - ) - .reduce(|_part_key, s, t| { - let threshold: isize = s.iter().map(|x| x.1 as isize).sum::() / 10000; - t.extend(s.iter().filter(|x| x.1 > threshold).map(|&(&a,b)| (a, b))); - }) - .map(|(_, part_key)| part_key) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query12.rs b/tpchlike/src/queries/query12.rs deleted file mode 100644 index 70e0120d08..0000000000 --- a/tpchlike/src/queries/query12.rs +++ /dev/null @@ -1,117 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::difference::DiffPair; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; -use ::types::create_date; - -// -- $ID$ -// -- TPC-H/TPC-R Shipping Modes and Order Priority Query (Q12) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// l_shipmode, -// sum(case -// when o_orderpriority = '1-URGENT' -// or o_orderpriority = '2-HIGH' -// then 1 -// else 0 -// end) as high_line_count, -// sum(case -// when o_orderpriority <> '1-URGENT' -// and o_orderpriority <> '2-HIGH' -// then 1 -// else 0 -// end) as low_line_count -// from -// orders, -// lineitem -// where -// o_orderkey = l_orderkey -// and l_shipmode in (':1', ':2') -// and l_commitdate < l_receiptdate -// and l_shipdate < l_commitdate -// and l_receiptdate >= date ':3' -// and l_receiptdate < date ':3' + interval '1' year -// group by -// l_shipmode -// order by -// l_shipmode; -// :n -1 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - println!("TODO: Q12 does contortions because isize doesn't implement Mul>."); - - let orders = - collections - .orders() - .explode(|o| - if starts_with(&o.order_priority, b"1-URGENT") || starts_with(&o.order_priority, b"2-HIGH") { - Some((o.order_key, DiffPair::new(1, 0))) - } - else { - Some((o.order_key, DiffPair::new(0, 1))) - } - ) - .arrange_by_self(); - - let lineitems = - collections - .lineitems() - .flat_map(|l| - if (starts_with(&l.ship_mode, b"MAIL") || starts_with(&l.ship_mode, b"SHIP")) && - l.commit_date < l.receipt_date && l.ship_date < l.commit_date && - create_date(1994,1,1) <= l.receipt_date && l.receipt_date < create_date(1995,1,1) { - Some((l.order_key, l.ship_mode)) - } - else { None } - ) - .arrange_by_key(); - - orders - .join_core(lineitems, |_, _, &ship_mode| Some(ship_mode)) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .flat_map(|l| - if (starts_with(&l.ship_mode, b"MAIL") || starts_with(&l.ship_mode, b"SHIP")) && - l.commit_date < l.receipt_date && l.ship_date < l.commit_date && - create_date(1994,1,1) <= l.receipt_date && l.receipt_date < create_date(1995,1,1) { - Some((l.order_key, l.ship_mode)) - } - else { None } - ) - .join_core(arrangements.order, |_ok,&sm,o| { - Some((sm, starts_with(&o.order_priority, b"1-URGENT") || starts_with(&o.order_priority, b"2-HIGH"))) - }) - .explode(|(sm,priority)| Some((sm, if priority { DiffPair::new(1, 0) } else { DiffPair::new(1, 0) }))) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query13.rs b/tpchlike/src/queries/query13.rs deleted file mode 100644 index d6651e3945..0000000000 --- a/tpchlike/src/queries/query13.rs +++ /dev/null @@ -1,97 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use regex::Regex; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Customer Distribution Query (Q13) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// c_count, -// count(*) as custdist -// from -// ( -// select -// c_custkey, -// count(o_orderkey) -// from -// customer left outer join orders on -// c_custkey = o_custkey -// and o_comment not like '%:1%:2%' -// group by -// c_custkey -// ) as c_orders (c_custkey, c_count) -// group by -// c_count -// order by -// custdist desc, -// c_count desc; -// :n -1 - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let regex = Regex::new("special.*requests").expect("Regex construction failed"); - - let orders = - collections - .orders() - .flat_map(move |o| if !regex.is_match(&o.comment) { Some(o.cust_key) } else { None } ); - - collections - .customers() - .map(|c| c.cust_key) - .concat(orders) - .count_total() - .map(|(_cust_key, count)| (count-1) as usize) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, - round: usize, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - use timely::dataflow::operators::Map; - use differential_dataflow::AsCollection; - - let arrangements = arrangements.in_scope(scope, experiment); - - let regex = Regex::new("special.*requests").expect("Regex construction failed"); - - let orders = - arrangements - .order - .flat_map_ref(move |_,o| if !regex.is_match(&o.comment) { Some(o.cust_key) } else { None } ) - .inner - .map(move |(d,t,r)| (d, ::std::cmp::max(t,round),r)) - .as_collection(); - - arrangements - .customer - .as_collection(|&c,_| c) - .inner - .map(move |(d,t,r)| (d, ::std::cmp::max(t,round),r)) - .as_collection() - .concat(orders) - .count_total() - .map(|(_cust_key, count)| (count-1) as usize) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query14.rs b/tpchlike/src/queries/query14.rs deleted file mode 100644 index 85b92cb2cc..0000000000 --- a/tpchlike/src/queries/query14.rs +++ /dev/null @@ -1,85 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::difference::DiffPair; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; -use ::types::create_date; - -// -- $ID$ -// -- TPC-H/TPC-R Promotion Effect Query (Q14) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// 100.00 * sum(case -// when p_type like 'PROMO%' -// then l_extendedprice * (1 - l_discount) -// else 0 -// end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue -// from -// lineitem, -// part -// where -// l_partkey = p_partkey -// and l_shipdate >= date ':1' -// and l_shipdate < date ':1' + interval '1' month; -// :n -1 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let lineitems = - collections - .lineitems() - .explode(|l| - if create_date(1995,9,1) <= l.ship_date && l.ship_date < create_date(1995,10,1) { - Some((l.part_key, (l.extended_price * (100 - l.discount) / 100) as isize )) - } - else { None } - ) - .arrange_by_self(); - - collections - .parts() - .explode(|p| Some((p.part_key, DiffPair::new(1, if starts_with(&p.typ.as_bytes(), b"PROMO") { 1 } else { 0 })))) - .arrange_by_self() - .join_core(lineitems, |&_part_key, _, _| Some(())) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .explode(|l| - if create_date(1995,9,1) <= l.ship_date && l.ship_date < create_date(1995,10,1) { - Some((l.part_key, (l.extended_price * (100 - l.discount) / 100) as isize )) - } - else { None } - ) - .arrange_by_self() - .join_core(arrangements.part, |_pk,&(),p| Some(DiffPair::new(1, if starts_with(&p.typ.as_bytes(), b"PROMO") { 1 } else { 0 }))) - .explode(|dp| Some(((),dp))) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query15.rs b/tpchlike/src/queries/query15.rs deleted file mode 100644 index 540592bf82..0000000000 --- a/tpchlike/src/queries/query15.rs +++ /dev/null @@ -1,154 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; -use ::types::create_date; - -// -- $ID$ -// -- TPC-H/TPC-R Top Supplier Query (Q15) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// create view revenue:s (supplier_no, total_revenue) as -// select -// l_suppkey, -// sum(l_extendedprice * (1 - l_discount)) -// from -// lineitem -// where -// l_shipdate >= date ':1' -// and l_shipdate < date ':1' + interval '3' month -// group by -// l_suppkey; -// -// :o -// select -// s_suppkey, -// s_name, -// s_address, -// s_phone, -// total_revenue -// from -// supplier, -// revenue:s -// where -// s_suppkey = supplier_no -// and total_revenue = ( -// select -// max(total_revenue) -// from -// revenue:s -// ) -// order by -// s_suppkey; -// -// drop view revenue:s; -// :n -1 - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - // revenue by supplier - let revenue = - collections - .lineitems() - .explode(|item| - if create_date(1996, 1, 1) <= item.ship_date && item.ship_date < create_date(1996,4,1) { - Some((item.supp_key, (item.extended_price * (100 - item.discount) / 100) as isize)) - } - else { None } - ); - - // suppliers with maximum revenue - let top_suppliers = - revenue - // do a hierarchical min, to improve update perf. - .map(|key| ((key % 1000) as u16, key)) - .reduce(|_k, s, t| { - let max = s.iter().map(|x| x.1).max().unwrap(); - t.extend(s.iter().filter(|x| x.1 == max).map(|&(&a,b)| (a,b))); - }) - .map(|(_,key)| ((key % 100) as u8, key)) - .reduce(|_k, s, t| { - let max = s.iter().map(|x| x.1).max().unwrap(); - t.extend(s.iter().filter(|x| x.1 == max).map(|&(&a,b)| (a,b))); - }) - .map(|(_,key)| ((key % 10) as u8, key)) - .reduce(|_k, s, t| { - let max = s.iter().map(|x| x.1).max().unwrap(); - t.extend(s.iter().filter(|x| x.1 == max).map(|&(&a,b)| (a,b))); - }) - .map(|(_,key)| ((), key)) - .reduce(|_k, s, t| { - let max = s.iter().map(|x| x.1).max().unwrap(); - t.extend(s.iter().filter(|x| x.1 == max).map(|&(&a,b)| (a,b))); - }) - .map(|(_, key)| key) - .count_total(); - - collections - .suppliers() - .map(|s| (s.supp_key, (s.name, s.address, s.phone))) - .join(top_suppliers) - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - // revenue by supplier - let revenue = - experiment - .lineitem(scope) - .explode(|item| - if create_date(1996, 1, 1) <= item.ship_date && item.ship_date < create_date(1996,4,1) { - Some((item.supp_key, (item.extended_price * (100 - item.discount) / 100) as isize)) - } - else { None } - ); - - // suppliers with maximum revenue - let top_suppliers = - revenue - // do a hierarchical min, to improve update perf. - .map(|key| ((key % 1000) as u16, key)) - .reduce(|_k, s, t| { - let max = s.iter().map(|x| x.1).max().unwrap(); - t.extend(s.iter().filter(|x| x.1 == max).map(|&(&a,b)| (a,b))); - }) - .map(|(_,key)| ((key % 100) as u8, key)) - .reduce(|_k, s, t| { - let max = s.iter().map(|x| x.1).max().unwrap(); - t.extend(s.iter().filter(|x| x.1 == max).map(|&(&a,b)| (a,b))); - }) - .map(|(_,key)| ((key % 10) as u8, key)) - .reduce(|_k, s, t| { - let max = s.iter().map(|x| x.1).max().unwrap(); - t.extend(s.iter().filter(|x| x.1 == max).map(|&(&a,b)| (a,b))); - }) - .map(|(_,key)| ((), key)) - .reduce(|_k, s, t| { - let max = s.iter().map(|x| x.1).max().unwrap(); - t.extend(s.iter().filter(|x| x.1 == max).map(|&(&a,b)| (a,b))); - }) - .map(|(_, key)| key) - .count_total(); - - top_suppliers - .join_core(arrangements.supplier, |_sk,&rev,s| Some((s.supp_key, s.name, s.address, s.phone, rev))) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query16.rs b/tpchlike/src/queries/query16.rs deleted file mode 100644 index c7a61bb9fa..0000000000 --- a/tpchlike/src/queries/query16.rs +++ /dev/null @@ -1,127 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use regex::Regex; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Parts/Supplier Relationship Query (Q16) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// p_brand, -// p_type, -// p_size, -// count(distinct ps_suppkey) as supplier_cnt -// from -// partsupp, -// part -// where -// p_partkey = ps_partkey -// and p_brand <> ':1' -// and p_type not like ':2%' -// and p_size in (:3, :4, :5, :6, :7, :8, :9, :10) -// and ps_suppkey not in ( -// select -// s_suppkey -// from -// supplier -// where -// s_comment like '%Customer%Complaints%' -// ) -// group by -// p_brand, -// p_type, -// p_size -// order by -// supplier_cnt desc, -// p_brand, -// p_type, -// p_size; -// :n -1 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let regex = Regex::new("Customer.*Complaints").expect("Regex construction failed"); - - let suppliers = - collections - .suppliers() - .flat_map(move |s| if regex.is_match(&s.comment) { Some(s.supp_key) } else { None } ); - - let parts = collections - .partsupps() - .map(|ps| (ps.supp_key, ps.part_key)) - .antijoin(suppliers) - .map(|(_supp_key, part_key)| part_key); - - collections - .parts() - .flat_map(|p| - if !starts_with(&p.brand, b"Brand#45") && !starts_with(&p.typ.as_bytes(), b"MEDIUM POLISHED") && [49, 14, 23, 45, 19, 3, 36, 9].contains(&p.size) { - Some((p.part_key, (p.brand, p.typ, p.size))) - } - else { None } - ) - .semijoin(parts) - .map(|(_, brand_type_size)| brand_type_size) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, - round: usize, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - use timely::dataflow::operators::Map; - use differential_dataflow::AsCollection; - - let arrangements = arrangements.in_scope(scope, experiment); - - let regex = Regex::new("Customer.*Complaints").expect("Regex construction failed"); - - let suppliers = - arrangements - .supplier - .flat_map_ref(move |_,s| if regex.is_match(&s.comment) { Some(s.supp_key) } else { None } ) - .inner - .map(move |(d,t,r)| (d, ::std::cmp::max(t,round),r)) - .as_collection(); - - arrangements - .partsupp - .as_collection(|&psk,_| psk) - .inner - .map(move |(d,t,r)| (d, ::std::cmp::max(t,round),r)) - .as_collection() - .join_core(arrangements.part, |_pk,&sk,p| { - if !starts_with(&p.brand, b"Brand#45") && !starts_with(&p.typ.as_bytes(), b"MEDIUM POLISHED") && [49, 14, 23, 45, 19, 3, 36, 9].contains(&p.size) { - Some((sk, (p.brand, p.typ, p.size))) - } - else { None } - - }) - .antijoin(suppliers) - .map(|(_sk, stuff)| stuff) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query17.rs b/tpchlike/src/queries/query17.rs deleted file mode 100644 index 700d6dee13..0000000000 --- a/tpchlike/src/queries/query17.rs +++ /dev/null @@ -1,102 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Small-Quantity-Order Revenue Query (Q17) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// sum(l_extendedprice) / 7.0 as avg_yearly -// from -// lineitem, -// part -// where -// p_partkey = l_partkey -// and p_brand = ':1' -// and p_container = ':2' -// and l_quantity < ( -// select -// 0.2 * avg(l_quantity) -// from -// lineitem -// where -// l_partkey = p_partkey -// ); -// :n -1 - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let parts = - collections - .parts() // We fluff out search strings to have the right lengths. \\ - .flat_map(|x| { - if &x.brand[..8] == b"Brand#23" && &x.container[..7] == b"MED BOX" { - Some(x.part_key) - } - else { None } - }); - - collections - .lineitems() - .map(|x| (x.part_key, (x.quantity, x.extended_price))) - .semijoin(parts) - .reduce(|_k, s, t| { - - // determine the total and count of quantity. - let total: i64 = s.iter().map(|x| (x.0).0 * (x.1 as i64)).sum(); - let count: i64 = s.iter().map(|x| x.1 as i64).sum(); - - // produce as output those tuples with below-threshold quantity. - t.extend(s.iter().filter(|&&(&(quantity,_),_)| 5 * quantity * count < total) - .map(|&(&(_,price),count)| (price, count))); - }) - .explode(|(_part, price)| Some(((), price as isize))) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .map(|x| (x.part_key, (x.quantity, x.extended_price))) - .join_core(arrangements.part, |&pk,&(qu,ep),p| { - if &p.brand[..8] == b"Brand#23" && &p.container[..7] == b"MED BOX" { - Some((pk,(qu,ep))) - } - else { None } - - }) - .reduce(|_k, s, t| { - - // determine the total and count of quantity. - let total: i64 = s.iter().map(|x| (x.0).0 * (x.1 as i64)).sum(); - let count: i64 = s.iter().map(|x| x.1 as i64).sum(); - - // produce as output those tuples with below-threshold quantity. - t.extend(s.iter().filter(|&&(&(quantity,_),_)| 5 * quantity * count < total) - .map(|&(&(_,price),count)| (price, count))); - }) - .explode(|(_part, price)| Some(((), price as isize))) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query18.rs b/tpchlike/src/queries/query18.rs deleted file mode 100644 index 496a58752f..0000000000 --- a/tpchlike/src/queries/query18.rs +++ /dev/null @@ -1,88 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Large Volume Customer Query (Q18) -// -- Function Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// c_name, -// c_custkey, -// o_orderkey, -// o_orderdate, -// o_totalprice, -// sum(l_quantity) -// from -// customer, -// orders, -// lineitem -// where -// o_orderkey in ( -// select -// l_orderkey -// from -// lineitem -// group by -// l_orderkey having -// sum(l_quantity) > :1 -// ) -// and c_custkey = o_custkey -// and o_orderkey = l_orderkey -// group by -// c_name, -// c_custkey, -// o_orderkey, -// o_orderdate, -// o_totalprice -// order by -// o_totalprice desc, -// o_orderdate; -// :n 100 - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let orders = - collections - .orders() - .map(|o| (o.order_key, (o.cust_key, o.order_date, o.total_price))); - - collections - .lineitems() - .explode(|l| Some((l.order_key, l.quantity as isize))) - .count_total() - .filter(|&(_key, cnt)| cnt > 300) - .join_map(orders, |&o_key, &quant, &(cust_key, date, price)| (cust_key, (o_key, date, price, quant))) - .join(collections.customers().map(|c| (c.cust_key, c.name))) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .explode(|l| Some((l.order_key, l.quantity as isize))) - .count_total() - .filter(|&(_key, cnt)| cnt > 300) - .join_core(arrangements.order, |_ok,&cnt,o| Some((o.cust_key, (o.order_date, o.total_price, cnt)))) - .join_core(arrangements.customer, |&ck,&(od,tp,cnt),c| Some((ck,c.name,od,tp,cnt))) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query19.rs b/tpchlike/src/queries/query19.rs deleted file mode 100644 index 03e4092dd5..0000000000 --- a/tpchlike/src/queries/query19.rs +++ /dev/null @@ -1,126 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Discounted Revenue Query (Q19) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// sum(l_extendedprice* (1 - l_discount)) as revenue -// from -// lineitem, -// part -// where -// ( -// p_partkey = l_partkey -// and p_brand = ':1' -// and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') -// and l_quantity >= :4 and l_quantity <= :4 + 10 -// and p_size between 1 and 5 -// and l_shipmode in ('AIR', 'AIR REG') -// and l_shipinstruct = 'DELIVER IN PERSON' -// ) -// or -// ( -// p_partkey = l_partkey -// and p_brand = ':2' -// and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') -// and l_quantity >= :5 and l_quantity <= :5 + 10 -// and p_size between 1 and 10 -// and l_shipmode in ('AIR', 'AIR REG') -// and l_shipinstruct = 'DELIVER IN PERSON' -// ) -// or -// ( -// p_partkey = l_partkey -// and p_brand = ':3' -// and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') -// and l_quantity >= :6 and l_quantity <= :6 + 10 -// and p_size between 1 and 15 -// and l_shipmode in ('AIR', 'AIR REG') -// and l_shipinstruct = 'DELIVER IN PERSON' -// ); -// :n -1 - - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let lineitems = - collections - .lineitems() - .explode(|x| - if (starts_with(&x.ship_mode, b"AIR") || starts_with(&x.ship_mode, b"AIR REG")) && starts_with(&x.ship_instruct, b"DELIVER IN PERSON") { - Some(((x.part_key, x.quantity), (x.extended_price * (100 - x.discount) / 100) as isize)) - } - else { None } - ); - - let lines1 = lineitems.filter(|&(_, quant)| quant >= 1 && quant <= 11).map(|x| x.0).arrange_by_self(); - let lines2 = lineitems.filter(|&(_, quant)| quant >= 10 && quant <= 20).map(|x| x.0).arrange_by_self(); - let lines3 = lineitems.filter(|&(_, quant)| quant >= 20 && quant <= 30).map(|x| x.0).arrange_by_self(); - - let parts = collections.parts().map(|p| (p.part_key, (p.brand, p.container, p.size))); - - let parts1 = parts.filter(|&(_key, (brand, container, size))| starts_with(&brand, b"Brand#12") && 1 <= size && size <= 5 && (starts_with(&container, b"SM CASE") || starts_with(&container, b"SM BOX") || starts_with(&container, b"SM PACK") || starts_with(&container, b"MED PKG"))).map(|x| x.0).arrange_by_self(); - let parts2 = parts.filter(|&(_key, (brand, container, size))| starts_with(&brand, b"Brand#23") && 1 <= size && size <= 10 && (starts_with(&container, b"MED BAG") || starts_with(&container, b"MED BOX") || starts_with(&container, b"MED PKG") || starts_with(&container, b"MED PACK"))).map(|x| x.0).arrange_by_self(); - let parts3 = parts.filter(|&(_key, (brand, container, size))| starts_with(&brand, b"Brand#34") && 1 <= size && size <= 15 && (starts_with(&container, b"LG CASE") || starts_with(&container, b"LG BOX") || starts_with(&container, b"LG PACK") || starts_with(&container, b"LG PKG"))).map(|x| x.0).arrange_by_self(); - - let result1 = lines1.join_core(parts1, |_,_,_| Some(())); - let result2 = lines2.join_core(parts2, |_,_,_| Some(())); - let result3 = lines3.join_core(parts3, |_,_,_| Some(())); - - result1 - .concat(result2) - .concat(result3) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .explode(|x| - if (starts_with(&x.ship_mode, b"AIR") || starts_with(&x.ship_mode, b"AIR REG")) && starts_with(&x.ship_instruct, b"DELIVER IN PERSON") { - Some(((x.part_key, x.quantity), (x.extended_price * (100 - x.discount) / 100) as isize)) - } - else { None } - ) - .join_core(arrangements.part, |_pk,&qu,p| { - if qu >= 1 && qu <= 11 && (starts_with(&p.brand, b"Brand#12") && 1 <= p.size && p.size <= 5 && (starts_with(&p.container, b"SM CASE") || starts_with(&p.container, b"SM BOX") || starts_with(&p.container, b"SM PACK") || starts_with(&p.container, b"MED PKG"))) - && qu >= 10 && qu <= 20 && (starts_with(&p.brand, b"Brand#23") && 1 <= p.size && p.size <= 10 && (starts_with(&p.container, b"MED BAG") || starts_with(&p.container, b"MED BOX") || starts_with(&p.container, b"MED PKG") || starts_with(&p.container, b"MED PACK"))) - && qu >= 20 && qu <= 30 && (starts_with(&p.brand, b"Brand#12") && 1 <= p.size && p.size <= 15 && (starts_with(&p.container, b"LG CASE") || starts_with(&p.container, b"LG BOX") || starts_with(&p.container, b"LG PACK") || starts_with(&p.container, b"LG PKG"))) - { - Some(()) - } - else { - None - } - - }) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query20.rs b/tpchlike/src/queries/query20.rs deleted file mode 100644 index 26f0525e6c..0000000000 --- a/tpchlike/src/queries/query20.rs +++ /dev/null @@ -1,140 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::operators::reduce::ReduceCore; -use differential_dataflow::trace::implementations::ValSpine; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; -use ::types::create_date; - -// -- $ID$ -// -- TPC-H/TPC-R Potential Part Promotion Query (Q20) -// -- Function Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// s_name, -// s_address -// from -// supplier, -// nation -// where -// s_suppkey in ( -// select -// ps_suppkey -// from -// partsupp -// where -// ps_partkey in ( -// select -// p_partkey -// from -// part -// where -// p_name like ':1%' -// ) -// and ps_availqty > ( -// select -// 0.5 * sum(l_quantity) -// from -// lineitem -// where -// l_partkey = ps_partkey -// and l_suppkey = ps_suppkey -// and l_shipdate >= date ':2' -// and l_shipdate < date ':2' + interval '1' year -// ) -// ) -// and s_nationkey = n_nationkey -// and n_name = ':3' -// order by -// s_name; -// :n -1 - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - println!("TODO: Q20 uses a `reduce_abelian` to get an arrangement, but could use `count_total`"); - - let partkeys = collections.parts.filter(|p| p.name.as_bytes() == b"forest").map(|p| p.part_key); - - let available = - collections - .lineitems() - .flat_map(|l| - if l.ship_date >= create_date(1994, 1, 1) && l.ship_date < create_date(1995, 1, 1) { - Some((l.part_key, (l.supp_key, l.quantity))) - } - else { None } - ) - .semijoin(partkeys) - .explode(|l| Some(((((l.0 as u64) << 32) + (l.1).0 as u64, ()), (l.1).1 as isize))) - .reduce_abelian::<_,ValSpine<_,_,_,_>>("Reduce", |_k,s,t| t.push((s[0].1, 1))); - - let suppliers = - collections - .partsupps() - .map(|ps| (ps.part_key, (ps.supp_key, ps.availqty))) - .semijoin(partkeys) - .map(|(part_key, (supp_key, avail))| (((part_key as u64) << 32) + (supp_key as u64), avail)) - .join_core(available, |&key, &avail1, &avail2| { - let key: u64 = key; - let avail2: isize = avail2; - if avail1 > avail2 as i32 / 2 { - Some((key & (u32::MAX as u64)) as usize) - } - else { None } - }); - - let nations = collections.nations.filter(|n| starts_with(&n.name, b"CANADA")).map(|n| (n.nation_key, n.name)); - - collections - .suppliers() - .map(|s| (s.supp_key, (s.name, s.address, s.nation_key))) - .semijoin(suppliers) - .map(|(_, (name, addr, nation))| (nation, (name, addr))) - .join(nations) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .explode(|l| - if l.ship_date >= create_date(1994, 1, 1) && l.ship_date < create_date(1995, 1, 1) { - Some(((l.part_key, l.supp_key), l.quantity as isize)) - } - else { None } - ) - .join_core(arrangements.part, |&pk,&sk,p| - if p.name.as_bytes() == b"forest" { Some((pk,sk)) } else { None } - ) - .count_total() - .join_core(arrangements.partsupp, |&(_pk,sk),tot,ps| { - if (ps.availqty as isize) > tot / 2 { Some((sk, ())) } else { None } - }) - .distinct_total() - .join_core(arrangements.supplier, |_sk,&(),s| Some((s.nation_key, (s.name, s.address)))) - .join_core(arrangements.nation, |_nk,&(nm,ad),n| - if starts_with(&n.name, b"CANADA") { Some((nm,ad)) } else { None } - ) - .probe_with(probe); -} diff --git a/tpchlike/src/queries/query21.rs b/tpchlike/src/queries/query21.rs deleted file mode 100644 index 6a91e6efcb..0000000000 --- a/tpchlike/src/queries/query21.rs +++ /dev/null @@ -1,139 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::operators::ThresholdTotal; -use differential_dataflow::lattice::Lattice; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Suppliers Who Kept Orders Waiting Query (Q21) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// s_name, -// count(*) as numwait -// from -// supplier, -// lineitem l1, -// orders, -// nation -// where -// s_suppkey = l1.l_suppkey -// and o_orderkey = l1.l_orderkey -// and o_orderstatus = 'F' -// and l1.l_receiptdate > l1.l_commitdate -// and exists ( -// select -// * -// from -// lineitem l2 -// where -// l2.l_orderkey = l1.l_orderkey -// and l2.l_suppkey <> l1.l_suppkey -// ) -// and not exists ( -// select -// * -// from -// lineitem l3 -// where -// l3.l_orderkey = l1.l_orderkey -// and l3.l_suppkey <> l1.l_suppkey -// and l3.l_receiptdate > l3.l_commitdate -// ) -// and s_nationkey = n_nationkey -// and n_name = ':1' -// group by -// s_name -// order by -// numwait desc, -// s_name; -// :n 100 - - -fn starts_with(source: &[u8], query: &[u8]) -> bool { - source.len() >= query.len() && &source[..query.len()] == query -} - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - let orders = - collections - .orders() - .flat_map(|o| - if starts_with(&o.order_status, b"F") { Some(o.order_key) } - else { None } - ); - - // lineitems relevant to "F" orders. - let lineitems = - collections - .lineitems() - .map(|l| (l.order_key, (l.supp_key, l.receipt_date > l.commit_date))) - .semijoin(orders); - - let lateitems = lineitems.filter(|l| (l.1).1); - let lateorders = lateitems.map(|l| l.0).distinct_total(); - - let problems = - lineitems - .map(|(order_key, (_supp_key, is_late))| (order_key, is_late)) - .semijoin(lateorders) //- on_time and late, but just one late -\\ - .reduce(|_order_key, s, t| if s.len() == 2 && s[1].1 == 1 { t.push(((), 1)); }) - .map(|(order_key, _)| order_key); - - let latesupps = - lateitems - .semijoin(problems) - .map(|(_order_key, (supp_key, _))| supp_key); - - collections - .suppliers() - .map(|s| (s.supp_key, (s.name, s.nation_key))) - .semijoin(latesupps) - .map(|(_, (name, nation))| (nation, name)) - .semijoin(collections.nations().filter(|n| starts_with(&n.name, b"SAUDI ARABIA")).map(|n| n.nation_key)) - .count_total() - .probe_with(probe); -} -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - let arrangements = arrangements.in_scope(scope, experiment); - - experiment - .lineitem(scope) - .map(|l| (l.order_key, (l.receipt_date > l.commit_date, l.supp_key))) - .reduce(|_ok,input,output| { - - let late_supp = (input[0].0).1; - let only_late = input[1..].iter().all(|(x,_)| !x.0); - let other_supp = input[1..].iter().any(|(x,_)| x.1 != late_supp); - - if only_late && other_supp { - output.push((late_supp, 1)); - } - - }) - .join_core(arrangements.order, |_ok,&sk,o| { - if starts_with(&o.order_status, b"F") { Some((sk, ())) } else { None } - }) - .join_core(arrangements.supplier, |_sk,&(),s| Some((s.nation_key, s.name))) - .join_core(arrangements.nation, |_nk,&nm,n| - if starts_with(&n.name, b"SAUDI ARABIA") { Some(nm) } else { None } - ) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/queries/query22.rs b/tpchlike/src/queries/query22.rs deleted file mode 100644 index 3c24c3b7df..0000000000 --- a/tpchlike/src/queries/query22.rs +++ /dev/null @@ -1,159 +0,0 @@ -use timely::order::TotalOrder; -use timely::dataflow::*; -use timely::dataflow::operators::probe::Handle as ProbeHandle; - -use differential_dataflow::operators::*; -use differential_dataflow::difference::DiffPair; -use differential_dataflow::operators::reduce::ReduceCore; -use differential_dataflow::operators::ThresholdTotal; -use differential_dataflow::lattice::Lattice; - -use differential_dataflow::trace::implementations::ValSpine; - -use {Arrangements, Experiment, Collections}; - -// -- $ID$ -// -- TPC-H/TPC-R Global Sales Opportunity Query (Q22) -// -- Functional Query Definition -// -- Approved February 1998 -// :x -// :o -// select -// cntrycode, -// count(*) as numcust, -// sum(c_acctbal) as totacctbal -// from -// ( -// select -// substring(c_phone from 1 for 2) as cntrycode, -// c_acctbal -// from -// customer -// where -// substring(c_phone from 1 for 2) in -// (':1', ':2', ':3', ':4', ':5', ':6', ':7') -// and c_acctbal > ( -// select -// avg(c_acctbal) -// from -// customer -// where -// c_acctbal > 0.00 -// and substring(c_phone from 1 for 2) in -// (':1', ':2', ':3', ':4', ':5', ':6', ':7') -// ) -// and not exists ( -// select -// * -// from -// orders -// where -// o_custkey = c_custkey -// ) -// ) as custsale -// group by -// cntrycode -// order by -// cntrycode; -// :n -1 - -pub fn query(collections: &mut Collections, probe: &mut ProbeHandle) -where G::Timestamp: Lattice+TotalOrder+Ord { - - println!("TODO: Q22 uses a `group` for counting to get an arrangement; could use `count_total`"); - - let customers = - collections - .customers() - .flat_map(|c| { - if c.acctbal > 0 { - match &[c.phone[0], c.phone[1]] { - b"13" | b"31" | b"23" | b"29" | b"30" | b"18" | b"17" => { - Some((((c.phone[1] as u16) << 8) + c.phone[0] as u16, c.acctbal, c.cust_key)) - }, - _ => None, - } - } - else { None } - }); - - let averages = - customers - .explode(|(cc, acctbal, _)| Some(((cc, ()), DiffPair::new(acctbal as isize, 1)))) - .reduce_abelian::<_,ValSpine<_,_,_,_>>("Reduce", |_k,s,t| t.push((s[0].1, 1))); - - customers - .map(|(cc, acct, key)| (key, (cc, acct))) - .antijoin(collections.orders().map(|o| o.cust_key).distinct_total()) - .map(|(_, (cc, acct))| (cc, acct as isize)) - .join_core(averages, |&cc, &acct, &pair| { - let acct : isize = acct; - let pair : DiffPair = pair; - if acct > (pair.element1 / pair.element2) { Some((cc, acct)) } else { None } - }) - .explode(|(cc, acct)| Some((cc, DiffPair::new(acct as isize, 1)))) - .count_total() - // .inspect(|x| println!("{:?}", x)) - .probe_with(probe); -} - -pub fn query_arranged>( - scope: &mut G, - probe: &mut ProbeHandle, - experiment: &mut Experiment, - arrangements: &mut Arrangements, - round: usize, -) -where - G::Timestamp: Lattice+TotalOrder+Ord -{ - use timely::dataflow::operators::Map; - use differential_dataflow::AsCollection; - - let arrangements = arrangements.in_scope(scope, experiment); - - let customers = - arrangements - .customer - .flat_map_ref(|_,c| { - if c.acctbal > 0 { - match &[c.phone[0], c.phone[1]] { - b"13" | b"31" | b"23" | b"29" | b"30" | b"18" | b"17" => { - Some((((c.phone[1] as u16) << 8) + c.phone[0] as u16, c.acctbal, c.cust_key)) - }, - _ => None, - } - } - else { None } - }) - .inner - .map(move |(d,t,r)| (d, ::std::cmp::max(t,round),r)) - .as_collection(); - - let averages = - customers - .explode(|(cc, acctbal, _)| Some(((cc, ()), DiffPair::new(acctbal as isize, 1)))) - .reduce_abelian::<_,ValSpine<_,_,_,_>>("Reduce", |_k,s,t| t.push((s[0].1, 1))); - - let orders = - arrangements - .order - .as_collection(|_,o| o.cust_key) - .inner - .map(move |(d,t,r)| (d, ::std::cmp::max(t,round),r)) - .as_collection() - .distinct_total(); - - customers - .map(|(cc, acct, key)| (key, (cc, acct))) - .antijoin(orders) - .map(|(_, (cc, acct))| (cc, acct as isize)) - .join_core(averages, |&cc, &acct, &pair| { - let acct : isize = acct; - let pair : DiffPair = pair; - if acct > (pair.element1 / pair.element2) { Some((cc, acct)) } else { None } - }) - .explode(|(cc, acct)| Some((cc, DiffPair::new(acct as isize, 1)))) - .count_total() - .probe_with(probe); -} \ No newline at end of file diff --git a/tpchlike/src/types.rs b/tpchlike/src/types.rs deleted file mode 100644 index c5f343d293..0000000000 --- a/tpchlike/src/types.rs +++ /dev/null @@ -1,310 +0,0 @@ -//! Types for TPCH-like queries. - -use arrayvec::ArrayString; -use abomonation::Abomonation; - -pub type Date = u32; - -#[inline] -pub fn create_date(year: u16, month: u8, day: u8) -> u32 { - ((year as u32) << 16) + ((month as u32) << 8) + (day as u32) -} - -fn parse_date(date: &str) -> Date { - let delim = "-"; - let mut fields = date.split(&delim); - let year = fields.next().unwrap().parse().unwrap(); - let month = fields.next().unwrap().parse().unwrap(); - let day = fields.next().unwrap().parse().unwrap(); - create_date(year, month, day) -} - -fn copy_from_to(src: &[u8], dst: &mut [u8]) { - let limit = if src.len() < dst.len() { src.len() } else { dst.len() }; - for index in 0 .. limit { - dst[index] = src[index]; - } -} - -fn read_u01(string: &str) -> [u8;1] { let mut buff = [0;1]; copy_from_to(string.as_bytes(), &mut buff); buff } -fn read_u10(string: &str) -> [u8;10] { let mut buff = [0;10]; copy_from_to(string.as_bytes(), &mut buff); buff } -fn read_u15(string: &str) -> [u8;15] { let mut buff = [0;15]; copy_from_to(string.as_bytes(), &mut buff); buff } -fn read_u25(string: &str) -> [u8;25] { let mut buff = [0;25]; copy_from_to(string.as_bytes(), &mut buff); buff } - -unsafe_abomonate!(AbomonationWrapper>); -unsafe_abomonate!(AbomonationWrapper>); -unsafe_abomonate!(AbomonationWrapper>); - -#[derive(Ord,PartialOrd,Eq,PartialEq,Clone,Copy,Debug,Hash,Default)] -pub struct AbomonationWrapper { - pub element: T, -} - -use ::std::ops::Deref; -impl Deref for AbomonationWrapper { - type Target = T; - fn deref(&self) -> &Self::Target { - &self.element - } -} - -unsafe_abomonate!(Part); - -#[derive(Ord,PartialOrd,Eq,PartialEq,Clone,Debug,Hash)] -pub struct Part { - pub part_key: usize, - pub name: ArrayString<[u8;56]>, - pub mfgr: [u8; 25], - pub brand: [u8; 10], - pub typ: AbomonationWrapper>, - pub size: i32, - pub container: [u8; 10], - pub retail_price: i64, - pub comment: ArrayString<[u8;23]>, -} - -impl<'a> From<&'a str> for Part { - fn from(text: &'a str) -> Part { - - let delim = "|"; - let mut fields = text.split(&delim); - - Part { - part_key: fields.next().unwrap().parse().unwrap(), - name: ArrayString::from(fields.next().unwrap()).unwrap(), - mfgr: read_u25(fields.next().unwrap()), - brand: read_u10(fields.next().unwrap()), - typ: AbomonationWrapper { element: ArrayString::from(fields.next().unwrap()).unwrap() }, - size: fields.next().unwrap().parse().unwrap(), - container: read_u10(fields.next().unwrap()), - retail_price: (fields.next().unwrap().parse::().unwrap() * 100.0) as i64, - comment: ArrayString::from(fields.next().unwrap()).unwrap() - } - } -} - -unsafe_abomonate!(Supplier); - -#[derive(Ord,PartialOrd,Eq,PartialEq,Clone,Debug,Hash)] -pub struct Supplier { - pub supp_key: usize, - pub name: [u8; 25], - pub address: AbomonationWrapper>, - pub nation_key: usize, - pub phone: [u8; 15], - pub acctbal: i64, - pub comment: AbomonationWrapper>, -} - -impl<'a> From<&'a str> for Supplier { - fn from(text: &'a str) -> Supplier { - - let delim = "|"; - let mut fields = text.split(&delim); - - Supplier { - supp_key: fields.next().unwrap().parse().unwrap(), - name: read_u25(fields.next().unwrap()), - address: AbomonationWrapper { element: ArrayString::from(fields.next().unwrap()).unwrap() }, - nation_key: fields.next().unwrap().parse().unwrap(), - phone: read_u15(fields.next().unwrap()), - acctbal: (fields.next().unwrap().parse::().unwrap() * 100.0) as i64, - comment: AbomonationWrapper { element: ArrayString::from(fields.next().unwrap()).unwrap() }, - } - } -} - -unsafe_abomonate!(PartSupp); - -#[derive(Ord,PartialOrd,Eq,PartialEq,Clone,Debug,Hash)] -pub struct PartSupp { - pub part_key: usize, - pub supp_key: usize, - pub availqty: i32, - pub supplycost: i64, - pub comment: ArrayString<[u8; 224]>, -} - -impl<'a> From<&'a str> for PartSupp { - fn from(text: &'a str) -> PartSupp { - - let delim = "|"; - let mut fields = text.split(&delim); - - PartSupp { - part_key: fields.next().unwrap().parse().unwrap(), - supp_key: fields.next().unwrap().parse().unwrap(), - availqty: fields.next().unwrap().parse().unwrap(), - supplycost: (fields.next().unwrap().parse::().unwrap() * 100.0) as i64, - comment: ArrayString::from(fields.next().unwrap()).unwrap(), - } - } -} - -unsafe_abomonate!(Customer); - -#[derive(Ord,PartialOrd,Eq,PartialEq,Clone,Debug,Hash)] -pub struct Customer { - pub cust_key: usize, - pub name: AbomonationWrapper>, - pub address: AbomonationWrapper>, - pub nation_key: usize, - pub phone: [u8; 15], - pub acctbal: i64, - pub mktsegment: [u8; 10], - pub comment: AbomonationWrapper>, -} - -impl<'a> From<&'a str> for Customer { - fn from(text: &'a str) -> Customer { - - // let mut result: Customer = Default::default(); - let delim = "|"; - let mut fields = text.split(&delim); - - Customer { - cust_key: fields.next().unwrap().parse().unwrap(), - name: AbomonationWrapper { element: ArrayString::from(fields.next().unwrap()).unwrap() }, - address: AbomonationWrapper { element: ArrayString::from(fields.next().unwrap()).unwrap() }, - nation_key: fields.next().unwrap().parse().unwrap(), - phone: read_u15(fields.next().unwrap()), - acctbal: (fields.next().unwrap().parse::().unwrap() * 100.0) as i64, - mktsegment: read_u10(fields.next().unwrap()), - comment: AbomonationWrapper { element: ArrayString::from(fields.next().unwrap()).unwrap() }, - } - } -} - -unsafe_abomonate!(Order); - -#[derive(Ord,PartialOrd,Eq,PartialEq,Clone,Debug,Hash)] -pub struct Order { - pub order_key: usize, - pub cust_key: usize, - pub order_status: [u8; 1], - pub total_price: i64, - pub order_date: Date, - pub order_priority: [u8; 15], - pub clerk: [u8; 15], - pub ship_priority: i32, - pub comment: ArrayString<[u8; 96]>, -} - -impl<'a> From<&'a str> for Order { - fn from(text: &'a str) -> Order { - - let delim = "|"; - let mut fields = text.split(&delim); - - Order { - order_key: fields.next().unwrap().parse().unwrap(), - cust_key: fields.next().unwrap().parse().unwrap(), - order_status: read_u01(fields.next().unwrap()), - total_price: (fields.next().unwrap().parse::().unwrap() * 100.0) as i64, - order_date: parse_date(&fields.next().unwrap()), - order_priority: read_u15(fields.next().unwrap()), - clerk: read_u15(fields.next().unwrap()), - ship_priority: fields.next().unwrap().parse().unwrap(), - comment: ArrayString::from(fields.next().unwrap()).unwrap(), - } - } -} - -unsafe_abomonate!(LineItem); - -#[derive(Ord,PartialOrd,Eq,PartialEq,Clone,Debug,Hash)] -pub struct LineItem { - pub order_key: usize, - pub part_key: usize, - pub supp_key: usize, - pub line_number: i32, - pub quantity: i64, - pub extended_price: i64, - pub discount: i64, - pub tax: i64, - pub return_flag: [u8; 1], - pub line_status: [u8; 1], - pub ship_date: Date, - pub commit_date: Date, - pub receipt_date: Date, - pub ship_instruct: [u8; 25], - pub ship_mode: [u8; 10], - pub comment: ArrayString<[u8; 48]>, -} - -impl<'a> From<&'a str> for LineItem { - fn from(text: &'a str) -> LineItem { - - let delim = "|"; - let mut fields = text.split(&delim); - - LineItem { - order_key: fields.next().unwrap().parse().unwrap(), - part_key: fields.next().unwrap().parse().unwrap(), - supp_key: fields.next().unwrap().parse().unwrap(), - line_number: fields.next().unwrap().parse().unwrap(), - quantity: fields.next().unwrap().parse().unwrap(), - // quantity: (fields.next().unwrap().parse::().unwrap() * 100.0) as i64, - extended_price: (fields.next().unwrap().parse::().unwrap() * 100.0) as i64, - discount: (fields.next().unwrap().parse::().unwrap() * 100.0) as i64, - tax: (fields.next().unwrap().parse::().unwrap() * 100.0) as i64, - return_flag: read_u01(fields.next().unwrap()), - line_status: read_u01(fields.next().unwrap()), - ship_date: parse_date(&fields.next().unwrap()), - commit_date: parse_date(&fields.next().unwrap()), - receipt_date: parse_date(&fields.next().unwrap()), - ship_instruct: read_u25(fields.next().unwrap()), - ship_mode: read_u10(fields.next().unwrap()), - comment: ArrayString::from(fields.next().unwrap()).unwrap(), - } - } -} - -unsafe_abomonate!(Nation); - -#[derive(Ord,PartialOrd,Eq,PartialEq,Clone,Debug,Hash)] -pub struct Nation { - pub nation_key: usize, - pub name: [u8; 25], - pub region_key: usize, - // pub comment: String, - pub comment: ArrayString<[u8;160]>, -} - -impl<'a> From<&'a str> for Nation { - fn from(text: &'a str) -> Nation { - - let delim = "|"; - let mut fields = text.split(&delim); - - Nation { - nation_key: fields.next().unwrap().parse().unwrap(), - name: read_u25(fields.next().unwrap()), - region_key: fields.next().unwrap().parse().unwrap(), - comment: ArrayString::from(fields.next().unwrap()).unwrap(), - } - } -} - -unsafe_abomonate!(Region); - -#[derive(Ord,PartialOrd,Eq,PartialEq,Clone,Debug,Hash)] -pub struct Region { - pub region_key: usize, - pub name: [u8; 25], - pub comment: ArrayString<[u8;160]>, -} - -impl<'a> From<&'a str> for Region { - fn from(text: &'a str) -> Region { - - let delim = "|"; - let mut fields = text.split(&delim); - - Region { - region_key: fields.next().unwrap().parse().unwrap(), - name: read_u25(fields.next().unwrap()), - comment: ArrayString::from(fields.next().unwrap()).unwrap(), - } - } -}