From 34214fe17c123e2bf04567ada2a107df27079f33 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 4 Feb 2020 19:14:42 -0500 Subject: [PATCH] sped up brute-force --- .../cracker/storage/DataStorage.java | 3 +- .../cracker/storage/ProgressListener.java | 25 +++++ .../cracker/storage/ScheduledSet.java | 4 + .../cracker/storage/TimeMachine.java | 92 +++++++++++++------ 4 files changed, 94 insertions(+), 30 deletions(-) create mode 100644 src/main/java/kaptainwutax/seedcracker/cracker/storage/ProgressListener.java diff --git a/src/main/java/kaptainwutax/seedcracker/cracker/storage/DataStorage.java b/src/main/java/kaptainwutax/seedcracker/cracker/storage/DataStorage.java index fcb586b..425733f 100644 --- a/src/main/java/kaptainwutax/seedcracker/cracker/storage/DataStorage.java +++ b/src/main/java/kaptainwutax/seedcracker/cracker/storage/DataStorage.java @@ -111,12 +111,11 @@ public class DataStorage { public void clear() { System.out.println("Clearing data storage."); this.scheduledData = new ConcurrentSet<>(); - this.pillarData = null; this.baseSeedData = new ScheduledSet<>(SEED_DATA_COMPARATOR); this.biomeSeedData = new ScheduledSet<>(null); this.hashedSeedData = null; - this.timeMachine.terminate = true; + this.timeMachine.shouldTerminate = true; this.timeMachine = new TimeMachine(this); } diff --git a/src/main/java/kaptainwutax/seedcracker/cracker/storage/ProgressListener.java b/src/main/java/kaptainwutax/seedcracker/cracker/storage/ProgressListener.java new file mode 100644 index 0000000..f16dfc7 --- /dev/null +++ b/src/main/java/kaptainwutax/seedcracker/cracker/storage/ProgressListener.java @@ -0,0 +1,25 @@ +package kaptainwutax.seedcracker.cracker.storage; + +import kaptainwutax.seedcracker.util.Log; + +public class ProgressListener { + + protected float progress; + + public ProgressListener() { + this(0.0F); + } + + public ProgressListener(float progress) { + this.progress = progress; + } + + public synchronized void addPercent(float percent, boolean debug) { + if(debug) { + Log.debug("Progress: " + this.progress + "%"); + } + + this.progress += percent; + } + +} diff --git a/src/main/java/kaptainwutax/seedcracker/cracker/storage/ScheduledSet.java b/src/main/java/kaptainwutax/seedcracker/cracker/storage/ScheduledSet.java index f2d02a3..46c36fc 100644 --- a/src/main/java/kaptainwutax/seedcracker/cracker/storage/ScheduledSet.java +++ b/src/main/java/kaptainwutax/seedcracker/cracker/storage/ScheduledSet.java @@ -32,6 +32,10 @@ public class ScheduledSet implements Iterable { return this.baseSet.contains(e) || this.scheduledSet.contains(e); } + public Set getBaseSet() { + return this.baseSet; + } + @Override public synchronized Iterator iterator() { return this.baseSet.iterator(); diff --git a/src/main/java/kaptainwutax/seedcracker/cracker/storage/TimeMachine.java b/src/main/java/kaptainwutax/seedcracker/cracker/storage/TimeMachine.java index ddb615c..de2ecc5 100644 --- a/src/main/java/kaptainwutax/seedcracker/cracker/storage/TimeMachine.java +++ b/src/main/java/kaptainwutax/seedcracker/cracker/storage/TimeMachine.java @@ -10,16 +10,17 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; public class TimeMachine { - public static ExecutorService SERVICE = Executors.newFixedThreadPool(1); + public static ExecutorService SERVICE = Executors.newFixedThreadPool(5); private LCG inverseLCG = Rand.JAVA_LCG.combine(-2); protected DataStorage dataStorage; public boolean isRunning = false; - public boolean terminate = false; + public boolean shouldTerminate = false; protected List pillarSeeds = null; protected List structureSeeds = null; @@ -30,11 +31,15 @@ public class TimeMachine { } public void poke(Phase phase) { + if(this.isRunning) { + return; + } + this.isRunning = true; final Phase[] finalPhase = {phase}; SERVICE.submit(() -> { - while(finalPhase[0] != null && !this.terminate) { + while(finalPhase[0] != null && !this.shouldTerminate) { if(finalPhase[0] == Phase.PILLARS) { if(!this.pokePillars())break; } else if(finalPhase[0] == Phase.STRUCTURES) { @@ -45,9 +50,9 @@ public class TimeMachine { finalPhase[0] = finalPhase[0].nextPhase(); } - }); - this.isRunning = false; + this.isRunning = false; + }); } protected boolean pokePillars() { @@ -57,7 +62,7 @@ public class TimeMachine { Log.debug("===================================="); Log.warn("Looking for pillar seeds..."); - for(int pillarSeed = 0; pillarSeed < 1 << 16 && !this.terminate; pillarSeed++) { + for(int pillarSeed = 0; pillarSeed < 1 << 16 && !this.shouldTerminate; pillarSeed++) { if(this.dataStorage.pillarData.test(pillarSeed, null)) { Log.warn("Found pillar seed [" + pillarSeed + "]."); this.pillarSeeds.add(pillarSeed); @@ -74,38 +79,69 @@ public class TimeMachine { } protected boolean pokeStructures() { - if(this.pillarSeeds == null || this.structureSeeds != null || this.dataStorage.getBaseBits() < 54.0D)return false; + if(this.pillarSeeds == null || this.dataStorage.getBaseBits() < 54.0D)return false; this.structureSeeds = new ArrayList<>(); Rand rand = new Rand(0L, false); - Log.debug("===================================="); - Log.warn("Looking for structure seeds..."); + + SeedData[] cache = new SeedData[this.dataStorage.baseSeedData.size()]; + int id = 0; + + for(SeedData baseSeedDatum: this.dataStorage.baseSeedData) { + cache[id++] = baseSeedDatum; + } for(int pillarSeed: this.pillarSeeds) { - for(long partialWorldSeed = 0; partialWorldSeed < 1L << 32; partialWorldSeed++) { - if((partialWorldSeed & ((1 << 29) - 1)) == 0) { - Log.debug("Progress: " + ((100.0D * (double)partialWorldSeed) / (double)(1L << 32)) + "%"); - } + Log.debug("===================================="); + Log.warn("Looking for structure seeds with pillar seed [" + pillarSeed + "]..."); - long seed = this.timeMachine(partialWorldSeed, pillarSeed); - boolean matches = true; + AtomicInteger completion = new AtomicInteger(); + ProgressListener progressListener = new ProgressListener(); - for(SeedData baseSeedDatum: this.dataStorage.baseSeedData) { - if(!baseSeedDatum.test(seed, rand)) { - matches = false; - break; + for(int threadId = 0; threadId < 4; threadId++) { + int fThreadId = threadId; + + SERVICE.submit(() -> { + long lower = (long)fThreadId * (1L << 30); + long upper = (long)(fThreadId + 1) * (1L << 30); + + for(long partialWorldSeed = lower; partialWorldSeed < upper && !this.shouldTerminate; partialWorldSeed++) { + if((partialWorldSeed & ((1 << 29) - 1)) == 0) { + progressListener.addPercent(12.5F, true); + } + + long seed = this.timeMachine(partialWorldSeed, pillarSeed); + + boolean matches = true; + + for(SeedData baseSeedDatum: cache) { + boolean test = baseSeedDatum.test(seed, rand); + if(!test) { + matches = false; + break; + } + } + + if(matches) { + this.structureSeeds.add(seed); + Log.warn("Found structure seed [" + seed + "]."); + } } - } - if(matches) { - this.structureSeeds.add(seed); - Log.warn("Found structure seed [" + seed + "]."); - } + completion.getAndIncrement(); + }); + } - if(this.terminate) { + while(completion.get() != 4) { + try {Thread.sleep(50);} + catch(InterruptedException e) {e.printStackTrace();} + + if(this.shouldTerminate) { return false; } } + + progressListener.addPercent(0.0F, true); } if(!this.structureSeeds.isEmpty()) { @@ -134,10 +170,10 @@ public class TimeMachine { continue; } else { this.worldSeeds.add(worldSeed); - Log.warn("Found world seed [" + worldSeed + "]"); + Log.warn("Found world seed [" + worldSeed + "]."); } - if(this.terminate) { + if(this.shouldTerminate) { return false; } } @@ -172,7 +208,7 @@ public class TimeMachine { Log.warn("Found world seed [" + worldSeed + "]."); } - if(this.terminate) { + if(this.shouldTerminate) { return false; } }