pax_global_header 0000666 0000000 0000000 00000000064 11740006171 0014507 g ustar 00root root 0000000 0000000 52 comment=4b41a46a627dd7b4a3dcf8fbf4db5d0a4df84bb4
Multiverse-multiverse-0.7.0/ 0000775 0000000 0000000 00000000000 11740006171 0016047 5 ustar 00root root 0000000 0000000 Multiverse-multiverse-0.7.0/.gitignore 0000664 0000000 0000000 00000000230 11740006171 0020032 0 ustar 00root root 0000000 0000000 *.class
.gradle/
.DS_Store*
out/
multiverse-core/build/
multiverse-site/build/
multiverse-core/target/
*.iml
.idea/
gradle.properties
release.properties Multiverse-multiverse-0.7.0/LICENSE 0000664 0000000 0000000 00000001171 11740006171 0017054 0 ustar 00root root 0000000 0000000 License
This software is licensed under the Apache 2 license, quoted below.
Copyright 2009-2012 Peter Veentjer.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License. Multiverse-multiverse-0.7.0/README.md 0000664 0000000 0000000 00000003362 11740006171 0017332 0 ustar 00root root 0000000 0000000 Multiverse Software Transactional Memory
-------------------------
A software transactional memory implementation for the JVM. Access (read and writes) to shared memory is done through
transactional references, that can be compared to the AtomicReferences of Java. Access to these references will be done
under A (atomicity), C (consistency), I (isolation) semantics. For more information see multiverse.codehaus.org
Example
-------------------------
import org.multiverse.api.references.*;
import static org.multiverse.api.StmUtils.*;
public class Account{
private final TxnRef lastModified = newTxnRef();
private final TxnLong amount = newTxnLong();
public Account(long amount){
this.amount.set(amount);
this.lastModified.set(new Date());
}
public Date getLastModifiedDate(){
return lastModified.get();
}
public long getAmount(){
return amount.get();
}
public static void transfer(final Account from, final Account to, final long amount){
atomic(new Runnable()){
public void run(){
Date date = new Date();
from.lastModified.set(date);
from.amount.dec(amount);
to.lastModified.set(date);
to.amount.inc(amount);
}
}
}
}
And it can be called like this:
Account account1 = new Account(10);
Account account2 = new Account(20)
Account.transfer(account1, account2, 5);
No instrumentation.
-------------------------
Multiverse doesn't rely on instrumentation, so is easy to integrate in existing projects. Multiverse-multiverse-0.7.0/benchmarks/ 0000775 0000000 0000000 00000000000 11740006171 0020164 5 ustar 00root root 0000000 0000000 Multiverse-multiverse-0.7.0/benchmarks/atomic/ 0000775 0000000 0000000 00000000000 11740006171 0021440 5 ustar 00root root 0000000 0000000 Multiverse-multiverse-0.7.0/benchmarks/atomic/atomic_get_benchmark.groovy 0000664 0000000 0000000 00000001116 11740006171 0027033 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.AtomicGetDriver
def benchmark = new Benchmark();
benchmark.name = "atomic_get"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "atomic_get_with_${k}_threads"
testCase.warmupRunIterationCount = k==1?1:0;
testCase.threadCount = k
testCase.transactionsPerThread = 1000 * 1000 * 10000L
testCase.sharedRef = true
testCase.weakGet = false
testCase.driver = AtomicGetDriver.class
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/atomic/atomic_get_display.groovy 0000664 0000000 0000000 00000003612 11740006171 0026551 0 ustar 00root root 0000000 0000000 import org.jfree.data.category.DefaultCategoryDataset
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import static org.benchy.JGraphGraphBuilder.*
def benchmarks = searcher.findAllBenchmarks('atomic_get')
println("Benchy > Found ${benchmarks.size()} results")
def categoryDataSet = new DefaultCategoryDataset();
def xySeriesDataSet = new XYSeriesCollection();
def xyTotalSeriesDataSet = new XYSeriesCollection();
for (def benchmark in benchmarks) {
def series = new XYSeries(benchmark.date);
def totalSeries = new XYSeries(benchmark.date);
def entries = new LinkedList(benchmark.testCases)
entries.sort {it.threadCount}
entries.each {
def testCase = it
def transactionsPerSecondPerThread = testCase.average('transactionsPerSecondPerThread')
categoryDataSet.addValue(transactionsPerSecondPerThread, benchmark.date, testCase.threadCount)
series.add(testCase.threadCount, transactionsPerSecondPerThread)
def transactionsPerSecond = testCase.average('transactionsPerSecond')
totalSeries.add(testCase.threadCount, transactionsPerSecond)
}
xySeriesDataSet.addSeries(series);
xyTotalSeriesDataSet.addSeries(totalSeries);
}
writeLineChartAsPng(xySeriesDataSet, "Atomic Get", "threads", "transaction/second/thread", new File("charts/atomic_get_line_wide.png"))
writeLineChartAsPng(xySeriesDataSet, "Atomic Get", "threads", "transaction/second/thread",600, new File("charts/atomic_get_line_narrow.png"))
writeLineChartAsPng(xyTotalSeriesDataSet, "Atomic Get", "threads", "transaction/second", new File("charts/atomic_get_line_total_wide.png"))
writeLineChartAsPng(xyTotalSeriesDataSet, "Atomic Get", "threads", "transaction/second",600, new File("charts/atomic_get_line_total_narrow.png"))
writeBarChartAsPng(categoryDataSet, "Atomic Get", "threads", "transaction/second/thread", new File("charts/atomic_get_bar.png"))
Multiverse-multiverse-0.7.0/benchmarks/atomic/atomic_get_total_display.groovy 0000664 0000000 0000000 00000002637 11740006171 0027762 0 ustar 00root root 0000000 0000000 import org.jfree.data.category.DefaultCategoryDataset
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import static org.benchy.JGraphGraphBuilder.writeBarChartAsPng
import static org.benchy.JGraphGraphBuilder.writeLineChartAsPng
def benchmarks = searcher.findAllBenchmarks('atomic_weak_get')
println("Benchy > Found ${benchmarks.size()} results")
def categoryDataSet = new DefaultCategoryDataset();
def xySeriesDataSet = new XYSeriesCollection();
for (def benchmark in benchmarks) {
def series = new XYSeries(benchmark.date);
def entries = new LinkedList(benchmark.testCases)
entries.sort {it.threadCount}
entries.each {
def testCase = it
def transactionsPerSecond = testCase.average('transactionsPerSecond')
categoryDataSet.addValue(transactionsPerSecond, benchmark.date, testCase.threadCount)
series.add(testCase.threadCount, transactionsPerSecond)
}
xySeriesDataSet.addSeries(series);
}
writeLineChartAsPng(xySeriesDataSet, "Atomic Weak Get", "threads", "transaction/second/thread", new File("charts/atomic_weak_get_line_total_wide.png"))
writeLineChartAsPng(xySeriesDataSet, "Atomic Weak Get", "threads", "transaction/second/thread", 600, new File("charts/atomic_weak_get_line_total_narrow.png"))
writeBarChartAsPng(categoryDataSet, "Atomic Weak Get", "threads", "transaction/second/thread", new File("charts/atomic_weak_get_total_bar.png"))
Multiverse-multiverse-0.7.0/benchmarks/atomic/atomic_increment_benchmark.groovy 0000664 0000000 0000000 00000001712 11740006171 0030242 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.AtomicIncrementDriver
def benchmark = new Benchmark();
benchmark.name = "atomic_increment"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "atomic_increment_and_no_shared_ref"
testCase.warmupRunIterationCount = k == 1 ? 1 : 0;
testCase.threadCount = k
testCase.transactionsPerThread = 1000 * 1000 * 1000L
testCase.sharedRef = false
testCase.driver = AtomicIncrementDriver.class
benchmark.add(testCase)
}
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "atomic_increment_and_shared_ref"
testCase.warmupRunIterationCount = k == 1 ? 1 : 0;
testCase.threadCount = k
testCase.sharedRef = true
testCase.transactionsPerThread = k == 0 ? 1000 * 1000 * 100L : 1000 * 1000 * 10L
testCase.driver = AtomicIncrementDriver.class
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/atomic/atomic_increment_display.groovy 0000664 0000000 0000000 00000004021 11740006171 0027751 0 ustar 00root root 0000000 0000000 import org.jfree.data.category.DefaultCategoryDataset
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import static org.benchy.JGraphGraphBuilder.writeBarChartAsPng
import static org.benchy.JGraphGraphBuilder.writeLineChartAsPng
def benchmarks = searcher.findAllBenchmarks('atomic_increment')
println("Benchy > Found ${benchmarks.size()} results")
def categoryDataSet = new DefaultCategoryDataset()
def xySeriesDataSet = new XYSeriesCollection()
def totalXySeriesDataSet = new XYSeriesCollection();
for (def benchmark in benchmarks) {
def series = new XYSeries(benchmark.date)
def totalSeries = new XYSeries(benchmark.date)
def entries = new LinkedList(benchmark.testCases)
entries.sort {it.threadCount}
entries.each {
def testCase = it
def transactionsPerSecondPerThread = testCase.average('transactionsPerSecondPerThread')
categoryDataSet.addValue(transactionsPerSecondPerThread, benchmark.date, testCase.threadCount)
series.add(testCase.threadCount, transactionsPerSecondPerThread)
def transactionsPerSecond = testCase.average('transactionsPerSecond')
totalSeries.add(testCase.threadCount, transactionsPerSecond)
}
xySeriesDataSet.addSeries(series)
totalXySeriesDataSet.addSeries(totalSeries);
}
writeLineChartAsPng(xySeriesDataSet, "Atomic Increment", "threads", "transaction/second/thread", new File("charts/atomic_increment_line_wide.png"))
writeLineChartAsPng(xySeriesDataSet, "Atomic Increment", "threads", "transaction/second/thread", 600, new File("charts/atomic_increment_line_narrow.png"))
writeLineChartAsPng(totalXySeriesDataSet, "Atomic Increment", "threads", "transaction/second", new File("charts/atomic_increment_line_total_wide.png"))
writeLineChartAsPng(totalXySeriesDataSet, "Atomic Increment", "threads", "transaction/second", 600, new File("charts/atomic_increment_line_total_narrow.png"))
writeBarChartAsPng(categoryDataSet, "Atomic Increment", "threads", "transaction/second/thread", new File("charts/atomic_increment_bar.png"))
Multiverse-multiverse-0.7.0/benchmarks/atomic/atomic_long_increment_benchmark.groovy 0000664 0000000 0000000 00000001737 11740006171 0031270 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.AtomicLongIncrementDriver
def benchmark = new Benchmark();
benchmark.name = "atomic_long_increment"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "atomic_long_increment_no_shared_ref"
testCase.warmupRunIterationCount = k == 1 ? 1 : 0;
testCase.threadCount = k
testCase.sharedRef = false
testCase.transactionsPerThread = 1000 * 1000 * 1000L
testCase.driver = AtomicLongIncrementDriver.class
benchmark.add(testCase)
}
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "atomic_long_increment_shared_ref"
testCase.warmupRunIterationCount = k == 1 ? 1 : 0;
testCase.threadCount = k
testCase.sharedRef = true
testCase.transactionsPerThread = k == 0 ? 1000 * 1000 * 1000L : 100 * 1000 * 1000L
testCase.driver = AtomicLongIncrementDriver.class
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/atomic/atomic_long_increment_display.groovy 0000664 0000000 0000000 00000004141 11740006171 0030773 0 ustar 00root root 0000000 0000000 import org.jfree.data.category.DefaultCategoryDataset
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import static org.benchy.JGraphGraphBuilder.writeBarChartAsPng
import static org.benchy.JGraphGraphBuilder.writeLineChartAsPng
def benchmarks = searcher.findAllBenchmarks('atomic_long_increment')
println("Benchy > Found ${benchmarks.size()} results")
def categoryDataSet = new DefaultCategoryDataset()
def xySeriesDataSet = new XYSeriesCollection()
def totalXySeriesDataSet = new XYSeriesCollection();
for (def benchmark in benchmarks) {
def series = new XYSeries(benchmark.date)
def totalSeries = new XYSeries(benchmark.date)
def entries = new LinkedList(benchmark.testCases)
entries.sort {it.threadCount}
entries.each {
def testCase = it
def transactionsPerSecondPerThread = testCase.average('transactionsPerSecondPerThread')
categoryDataSet.addValue(transactionsPerSecondPerThread, benchmark.date, testCase.threadCount)
series.add(testCase.threadCount, transactionsPerSecondPerThread)
def transactionsPerSecond = testCase.average('transactionsPerSecond')
totalSeries.add(testCase.threadCount, transactionsPerSecond)
}
xySeriesDataSet.addSeries(series)
totalXySeriesDataSet.addSeries(totalSeries);
}
writeLineChartAsPng(xySeriesDataSet, "AtomicLong.incrementAndGet", "threads", "transaction/second/thread", new File("charts/atomic_long_increment_line_wide.png"))
writeLineChartAsPng(xySeriesDataSet, "AtomicLong.incrementAndGet", "threads", "transaction/second/thread", 600, new File("charts/atomic_long_increment_line_narrow.png"))
writeLineChartAsPng(totalXySeriesDataSet, "AtomicLong.incrementAndGet", "threads", "transaction/second", new File("charts/atomic_increment_long_line_total_wide.png"))
writeLineChartAsPng(totalXySeriesDataSet, "AtomicLong.incrementAndGet", "threads", "transaction/second", 600, new File("charts/atomic_long_increment_line_total_narrow.png"))
writeBarChartAsPng(categoryDataSet, "AtomicLong.incrementAndGet", "threads", "transaction/second/thread", new File("charts/atomic_long_increment_bar.png"))
Multiverse-multiverse-0.7.0/benchmarks/atomic/atomic_weak_get_benchmark.groovy 0000664 0000000 0000000 00000001127 11740006171 0030044 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.AtomicGetDriver
def benchmark = new Benchmark();
benchmark.name = "atomic_weak_get"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "atomic_weak_get_with_${k}_threads"
testCase.threadCount = k
testCase.transactionsPerThread = 1000 * 1000 * 10000L
testCase.sharedRef = true
testCase.weakGet = true
testCase.warmupRunIterationCount = k==1?1:0;
testCase.driver = AtomicGetDriver.class
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/atomic/atomic_weak_get_display.groovy 0000664 0000000 0000000 00000004006 11740006171 0027556 0 ustar 00root root 0000000 0000000 import org.jfree.data.category.DefaultCategoryDataset
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import static org.benchy.JGraphGraphBuilder.writeBarChartAsPng
import static org.benchy.JGraphGraphBuilder.writeLineChartAsPng
def benchmarks = searcher.findAllBenchmarks('atomic_weak_get')
println("Benchy > Found ${benchmarks.size()} results")
def categoryDataSet = new DefaultCategoryDataset()
def xySeriesDataSet = new XYSeriesCollection()
def totalXySeriesDataSet = new XYSeriesCollection();
for (def benchmark in benchmarks) {
def series = new XYSeries(benchmark.date)
def totalSeries = new XYSeries(benchmark.date)
def entries = new LinkedList(benchmark.testCases)
entries.sort {it.threadCount}
entries.each {
def testCase = it
def transactionsPerSecondPerThread = testCase.average('transactionsPerSecondPerThread')
categoryDataSet.addValue(transactionsPerSecondPerThread, benchmark.date, testCase.threadCount)
series.add(testCase.threadCount, transactionsPerSecondPerThread)
def transactionsPerSecond = testCase.average('transactionsPerSecond')
totalSeries.add(testCase.threadCount, transactionsPerSecond)
}
xySeriesDataSet.addSeries(series)
totalXySeriesDataSet.addSeries(totalSeries);
}
writeLineChartAsPng(xySeriesDataSet, "Atomic Weak Get", "threads", "transaction/second/thread", new File("charts/atomic_weak_get_line_wide.png"))
writeLineChartAsPng(xySeriesDataSet, "Atomic Weak Get", "threads", "transaction/second/thread", 600, new File("charts/atomic_weak_get_line_narrow.png"))
writeLineChartAsPng(totalXySeriesDataSet, "Atomic Weak Get", "threads", "transaction/second", new File("charts/atomic_weak_get_line_total_wide.png"))
writeLineChartAsPng(totalXySeriesDataSet, "Atomic Weak Get", "threads", "transaction/second", 600, new File("charts/atomic_weak_get_line_total_narrow.png"))
writeBarChartAsPng(categoryDataSet, "Atomic Weak Get", "threads", "transaction/second/thread", new File("charts/atomic_weak_get_bar.png"))
Multiverse-multiverse-0.7.0/benchmarks/blocking/ 0000775 0000000 0000000 00000000000 11740006171 0021754 5 ustar 00root root 0000000 0000000 Multiverse-multiverse-0.7.0/benchmarks/blocking/intrinsic_lock_stack_benchmark.groovy 0000664 0000000 0000000 00000001246 11740006171 0031437 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.IntrinsicLockStackDriver
def benchmark = new Benchmark();
benchmark.name = "intrinsic_lock_stack"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "intrinsic_lock_stack_with_${k}_threads"
testCase.pushThreadCount = k
testCase.popThreadCount = k
testCase.durationInSeconds=30
testCase.transactionsPerThread = 1000 * 1000 * 10L
testCase.warmupRunIterationCount = k==1?1:0
testCase.capacity = Integer.MAX_VALUE
testCase.driver = IntrinsicLockStackDriver.class
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/blocking/juc_lock_stack_benchmark.groovy 0000664 0000000 0000000 00000001216 11740006171 0030213 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.JucLockStackDriver
def benchmark = new Benchmark();
benchmark.name = "juc_lock_stack"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "juc_lock_stack_with_${k}_threads"
testCase.pushThreadCount = k
testCase.popThreadCount = k
testCase.durationInSeconds=30
testCase.transactionsPerThread = 1000 * 1000 * 10L
testCase.warmupRunIterationCount = k==1?1:0
testCase.capacity = Integer.MAX_VALUE
testCase.driver = JucLockStackDriver.class
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/blocking/simple_stack_benchmark.groovy 0000664 0000000 0000000 00000002055 11740006171 0027715 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.SimpleStackDriver
def benchmark = new Benchmark();
benchmark.name = "simple_stack"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "simple_stack_with_${k}_threads"
testCase.pushThreadCount = k
testCase.popThreadCount = k
testCase.durationInSeconds=30
testCase.transactionsPerThread = 1000 * 1000 * 10L
testCase.warmupRunIterationCount = k==1?1:0;
testCase.driver = SimpleStackDriver.class
benchmark.add(testCase)
}
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "simple_stack_using_pooled_closures_with_${k}_threads"
testCase.pushThreadCount = k
testCase.popThreadCount = k
testCase.durationInSeconds=30
testCase.poolClosures = true
testCase.transactionsPerThread = 1000 * 1000 * 10L
testCase.warmupRunIterationCount = k==1?1:0;
testCase.driver = SimpleStackDriver.class
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/contended_counter_benchmark.groovy 0000664 0000000 0000000 00000002204 11740006171 0027145 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.ContendedCounterDriver
def benchmark = new Benchmark();
benchmark.name = "counter"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "counter_with_${k}_threads"
testCase.dirtyCheck = true
testCase.threadCount = k
if (k > 2) {
testCase.transactionsPerThread = 1000 * 1000 * 5
} else {
testCase.transactionsPerThread = 1000 * 1000 * 20
}
testCase.warmupRunIterationCount = k == 1 ? 1 : 0;
testCase.driver = ContendedCounterDriver.class
benchmark.add(testCase)
}
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "counter_no_dirtyCheck_with_${k}_threads"
testCase.threadCount = k
testCase.dirtyCheck = false
if (k > 2) {
testCase.transactionsPerThread = 1000 * 1000 * 5
} else {
testCase.transactionsPerThread = 1000 * 1000 * 20
}
testCase.warmupRunIterationCount = k == 1 ? 1 : 0;
testCase.driver = ContendedCounterDriver.class
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/contended_counter_display.groovy 0000664 0000000 0000000 00000003334 11740006171 0026665 0 ustar 00root root 0000000 0000000 import org.jfree.data.category.DefaultCategoryDataset
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import static org.benchy.JGraphGraphBuilder.*
def benchmarks = searcher.findAllBenchmarks('counter')
println("Benchy > Found ${benchmarks.size()} results")
def categoryDataSet = new DefaultCategoryDataset();
def xySeriesDataSet = new XYSeriesCollection();
for (def benchmark in benchmarks) {
def seriesNoDirtyCheck = new XYSeries("${benchmark.date} without dirty check");
def seriesDirtyCheck = new XYSeries("${benchmark.date} with dirty check");
def testcases = new LinkedList(benchmark.testCases)
testcases.sort {it.threadCount}
testcases.each {
def testCase = it
def transactionsPerSecondPerThread = testCase.average('transactionsPerSecondPerThread')
categoryDataSet.addValue(transactionsPerSecondPerThread, "${benchmark.date} ${testCase.name}", testCase.threadCount)
if(testCase.dirtyCheck){
seriesDirtyCheck.add(testCase.threadCount, transactionsPerSecondPerThread)
}else{
seriesNoDirtyCheck.add(testCase.threadCount, transactionsPerSecondPerThread)
}
}
xySeriesDataSet.addSeries(seriesNoDirtyCheck);
xySeriesDataSet.addSeries(seriesDirtyCheck);
}
writeLineChartAsPng(xySeriesDataSet, "Contended Counter", "threads", "transaction/second/thread", new File("charts/contended_counter_line_wide.png"))
writeLineChartAsPng(xySeriesDataSet, "Contended Counter", "threads", "transaction/second/thread", 600, new File("charts/contended_counter_line_narrow.png"))
writeBarChartAsPng(categoryDataSet, "Contended Counter", "threads", "transaction/second/thread", new File("charts/contended_counter_update_bar.png"))
Multiverse-multiverse-0.7.0/benchmarks/mono_read_benchmark.groovy 0000664 0000000 0000000 00000001015 11740006171 0025405 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.MonoReadDriver
def benchmark = new Benchmark();
benchmark.name = "mono_read"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "mono_read_with_${k}_threads"
testCase.threadCount = k
testCase.transactionsPerThread = 1000 * 1000 * 500L
testCase.driver = MonoReadDriver.class
testCase.warmupRunIterationCount = k==1?1:0;
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/mono_read_display.groovy 0000664 0000000 0000000 00000002534 11740006171 0025127 0 ustar 00root root 0000000 0000000 import org.jfree.data.category.DefaultCategoryDataset
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import static org.benchy.JGraphGraphBuilder.*
def benchmarks = searcher.findAllBenchmarks('mono_read')
println("Benchy > Found ${benchmarks.size()} results")
def categoryDataSet = new DefaultCategoryDataset();
def xySeriesDataSet = new XYSeriesCollection();
for (def benchmark in benchmarks) {
def series = new XYSeries(benchmark.date);
def entries = new LinkedList(benchmark.testCases)
entries.sort {it.threadCount}
entries.each {
def testCase = it
def transactionsPerSecondPerThread = testCase.average('transactionsPerSecondPerThread')
categoryDataSet.addValue(transactionsPerSecondPerThread, benchmark.date, testCase.threadCount)
series.add(testCase.threadCount, transactionsPerSecondPerThread)
}
xySeriesDataSet.addSeries(series);
}
writeLineChartAsPng(xySeriesDataSet, "Uncontended Mono Read", "threads", "transaction/second/thread", new File("charts/mono_read_line_wide.png"))
writeLineChartAsPng(xySeriesDataSet, "Uncontended Mono Read", "threads", "transaction/second/thread", 600, new File("charts/mono_read_line_narrow.png"))
writeBarChartAsPng(categoryDataSet, "Uncontended Mono Read", "threads", "transaction/second/thread", new File("charts/mono_read_bar.png"))
Multiverse-multiverse-0.7.0/benchmarks/multipleupdatebenchmark.groovy 0000664 0000000 0000000 00000001071 11740006171 0026343 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.MultipleUpdateDriver
def benchmark = new Benchmark()
benchmark.name = "multiple_update"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "multiple_update_with_${k}_refs"
testCase.threadCount = 1
testCase.refCount = k
testCase.transactionsPerThread = 1000 * 1000 * 20
testCase.driver = MultipleUpdateDriver.class
benchmark.add(testCase)
testCase.warmupRunIterationCount = k==1?1:0;
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/orec/ 0000775 0000000 0000000 00000000000 11740006171 0021114 5 ustar 00root root 0000000 0000000 Multiverse-multiverse-0.7.0/benchmarks/orec/read_benchmark.groovy 0000664 0000000 0000000 00000001271 11740006171 0025311 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
def benchmark = new Benchmark();
benchmark.name = "orec_read"
def readNormalTestCase = new GroovyTestCase()
readNormalTestCase.name = "orec_read_normal"
readNormalTestCase.warmupRunIterationCount = 1
readNormalTestCase.operationCount = 1000 * 1000 * 10000L
readNormalTestCase.driver = OrecNormalReadDriver.class
benchmark.add(readNormalTestCase)
def readBiasedUpdate = new GroovyTestCase()
readBiasedUpdate.name = "orec_read_biased"
readBiasedUpdate.warmupRunIterationCount = 1
readBiasedUpdate.operationCount = 1000 * 1000 * 10000L
readBiasedUpdate.driver = OrecReadBiasedReadDriver.class
benchmark.add(readBiasedUpdate)
benchmark
Multiverse-multiverse-0.7.0/benchmarks/orec/update_benchmark.groovy 0000664 0000000 0000000 00000002474 11740006171 0025666 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.orec.OrecCommitLockUpdateDriver
import org.multiverse.stms.beta.benchmarks.orec.OrecNormalUpdateDriver
import org.multiverse.stms.beta.benchmarks.orec.OrecWriteLockUpdateDriver
def benchmark = new Benchmark();
benchmark.name = "orec_update"
def updateTestCase = new GroovyTestCase()
updateTestCase.name = "orec_update_optimistic"
updateTestCase.warmupRunIterationCount = 1
updateTestCase.operationCount = 1000 * 1000 * 1000L
updateTestCase.driver = OrecNormalUpdateDriver.class
benchmark.add(updateTestCase)
def updateWithWriteLockTestCase = new GroovyTestCase()
updateWithWriteLockTestCase.name = "orec_update_with_writelock"
updateWithWriteLockTestCase.warmupRunIterationCount = 1
updateWithWriteLockTestCase.operationCount = 1000 * 1000 * 1000L
updateWithWriteLockTestCase.driver = OrecWriteLockUpdateDriver.class
benchmark.add(updateWithWriteLockTestCase)
def updateWithCommitLockTestCase = new GroovyTestCase()
updateWithCommitLockTestCase.name = "orec_update_with_commitlock"
updateWithCommitLockTestCase.warmupRunIterationCount = 1
updateWithCommitLockTestCase.operationCount = 1000 * 1000 * 1000L
updateWithCommitLockTestCase.driver = OrecCommitLockUpdateDriver.class
benchmark.add(updateWithCommitLockTestCase)
benchmark
Multiverse-multiverse-0.7.0/benchmarks/overhead/ 0000775 0000000 0000000 00000000000 11740006171 0021761 5 ustar 00root root 0000000 0000000 Multiverse-multiverse-0.7.0/benchmarks/overhead/boxing_overhead_benchmark.groovy 0000664 0000000 0000000 00000001741 11740006171 0030410 0 ustar 00root root 0000000 0000000 import org.multiverse.stms.beta.benchmarks.BoxingOverheadDriver
import org.benchy.Benchmark
import org.benchy.GroovyTestCase
def benchmark = new Benchmark();
benchmark.name = "boxing_overhead"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "boxing_overhead_with_${k}_threads_and_boxing"
testCase.threadCount = k
testCase.withBoxing = true
testCase.transactionsPerThread = 1000 * 1000 * 100
testCase.warmupRunIterationCount = k == 1 ? 1 : 0;
testCase.driver = BoxingOverheadDriver.class
benchmark.add(testCase)
}
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "boxing_overhead_with_${k}_threads_and_no_boxing"
testCase.threadCount = k
testCase.withBoxing = false
testCase.transactionsPerThread = 1000 * 1000 * 200
testCase.warmupRunIterationCount = k == 1 ? 1 : 0;
testCase.driver = BoxingOverheadDriver.class
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/overhead/boxing_overhead_display.groovy 0000664 0000000 0000000 00000003251 11740006171 0030121 0 ustar 00root root 0000000 0000000 import org.jfree.data.category.DefaultCategoryDataset
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import static org.benchy.JGraphGraphBuilder.*
def benchmarks = searcher.findAllBenchmarks('boxing_overhead')
println("Benchy > Found ${benchmarks.size()} results")
def categoryDataSet = new DefaultCategoryDataset();
def xySeriesDataSet = new XYSeriesCollection();
for (def benchmark in benchmarks) {
def seriesNoBoxing = new XYSeries("${benchmark.date} no boxing");
def seriesBoxing = new XYSeries("${benchmark.date} with boxing");
def testcases = new LinkedList(benchmark.testCases)
testcases.sort {it.threadCount}
testcases.each {
def testCase = it
def transactionsPerSecondPerThread = testCase.average('transactionsPerThreadPerSecond')
categoryDataSet.addValue(transactionsPerSecondPerThread, "${benchmark.date} ${testCase.name}", testCase.threadCount)
if(testCase.withBoxing){
seriesBoxing.add(testCase.threadCount, transactionsPerSecondPerThread)
}else{
seriesNoBoxing.add(testCase.threadCount, transactionsPerSecondPerThread)
}
}
xySeriesDataSet.addSeries(seriesNoBoxing);
xySeriesDataSet.addSeries(seriesBoxing);
}
writeLineChartAsPng(xySeriesDataSet, "Boxing overhead", "threads", "transaction/second/thread", new File("charts/boxing_overhead_line_wide.png"))
writeLineChartAsPng(xySeriesDataSet, "Boxing overhead", "threads", "transaction/second/thread", 600,new File("charts/boxing_overhead_line_narrow.png"))
writeBarChartAsPng(categoryDataSet, "Boxing overhead", "threads", "transaction/second/thread", new File("charts/boxing_overhead_bar.png"))
Multiverse-multiverse-0.7.0/benchmarks/overhead/boxing_overhead_total_display.groovy 0000664 0000000 0000000 00000002543 11740006171 0031327 0 ustar 00root root 0000000 0000000 import org.jfree.data.category.DefaultCategoryDataset
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import static org.benchy.JGraphGraphBuilder.*
def benchmarks = searcher.findAllBenchmarks('boxing_overhead')
println("Benchy > Found ${benchmarks.size()} results")
def xySeriesDataSet = new XYSeriesCollection();
for (def benchmark in benchmarks) {
def seriesNoBoxing = new XYSeries("${benchmark.date} no boxing");
def seriesBoxing = new XYSeries("${benchmark.date} with boxing");
def testcases = new LinkedList(benchmark.testCases)
testcases.sort {it.threadCount}
testcases.each {
def testCase = it
def transactionsPerSecondPerThread = testCase.average('transactionsPerSecond')
if(testCase.withBoxing){
seriesBoxing.add(testCase.threadCount, transactionsPerSecondPerThread)
}else{
seriesNoBoxing.add(testCase.threadCount, transactionsPerSecondPerThread)
}
}
xySeriesDataSet.addSeries(seriesNoBoxing);
xySeriesDataSet.addSeries(seriesBoxing);
}
writeLineChartAsPng(xySeriesDataSet, "Boxing overhead", "threads", "transaction/second", new File("charts/boxing_overhead_total_line_wide.png"))
writeLineChartAsPng(xySeriesDataSet, "Boxing overhead", "threads", "transaction/second", 600, new File("charts/boxing_overhead_total_line_narrow.png"))
Multiverse-multiverse-0.7.0/benchmarks/uncontended_mono_update_benchmark.groovy 0000664 0000000 0000000 00000001101 11740006171 0030336 0 ustar 00root root 0000000 0000000 import org.benchy.Benchmark
import org.benchy.GroovyTestCase
import org.multiverse.stms.beta.benchmarks.UncontendedMonoUpdateDriver
def benchmark = new Benchmark();
benchmark.name = "uncontended_mono_update"
for (def k in 1..processorCount) {
def testCase = new GroovyTestCase()
testCase.name = "uncontended_mono_update_with_${k}_threads"
testCase.threadCount = k
testCase.transactionsPerThread = 1000 * 1000 * 50
testCase.driver = UncontendedMonoUpdateDriver.class
testCase.warmupRunIterationCount = k==1?1:0;
benchmark.add(testCase)
}
benchmark
Multiverse-multiverse-0.7.0/benchmarks/uncontended_mono_update_display.groovy 0000664 0000000 0000000 00000002632 11740006171 0030063 0 ustar 00root root 0000000 0000000 import org.jfree.data.category.DefaultCategoryDataset
import org.jfree.data.xy.XYSeries
import org.jfree.data.xy.XYSeriesCollection
import static org.benchy.JGraphGraphBuilder.*
def benchmarks = searcher.findAllBenchmarks('uncontended_mono_update')
println("Benchy > Found ${benchmarks.size()} results")
def categoryDataSet = new DefaultCategoryDataset();
def xySeriesDataSet = new XYSeriesCollection();
for (def benchmark in benchmarks) {
def series = new XYSeries(benchmark.date);
def entries = new LinkedList(benchmark.testCases)
entries.sort {it.threadCount}
entries.each {
def testCase = it
def transactionsPerSecondPerThread = testCase.average('transactionsPerSecondPerThread')
categoryDataSet.addValue(transactionsPerSecondPerThread, benchmark.date, testCase.threadCount)
series.add(testCase.threadCount, transactionsPerSecondPerThread)
}
xySeriesDataSet.addSeries(series);
}
writeLineChartAsPng(xySeriesDataSet, "Uncontended Mono Update", "threads", "transaction/second/thread", new File("charts/uncontended_mono_update_line_wide.png"))
writeLineChartAsPng(xySeriesDataSet, "Uncontended Mono Update", "threads", "transaction/second/thread", 600, new File("charts/uncontended_mono_update_line_narrow.png"))
writeBarChartAsPng(categoryDataSet, "Uncontended Mono Update", "threads", "transaction/second/thread", new File("charts/uncontended_mono_update_bar.png"))
Multiverse-multiverse-0.7.0/build.gradle 0000664 0000000 0000000 00000016475 11740006171 0020343 0 ustar 00root root 0000000 0000000 import org.codehaus.groovy.ant.Groovy
def executeBenchmark(String filepath) {
execute("benchy-execute -p ${processorCount} -cp multiverse-gamma/build/classes/main:multiverse-gamma/build/classes/test ${filepath}")
}
def executeDisplay(String filepath) {
execute("benchy-display ${filepath}")
}
def execute(String s) {
Process proc = s.execute()
proc.consumeProcessErrorStream(System.err)
proc.consumeProcessOutputStream(System.out)
if (proc.waitFor() != 0) {
throw new RuntimeException('exec failed')
}
}
allprojects {
// apply plugin: 'base'
defaultTasks 'clean', 'install'
}
project(':multiverse-core') {
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'project-reports'
sourceCompatibility = 1.6
version = '0.7.0'
group = 'org.multiverse'
//install.dependsOn ':build'
def localMavenRepo = 'file://' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath
configurations {
testFixtures {
extendsFrom testRuntime
}
deployerJars
}
javadoc {
title = "Multiverse Core $version"
}
repositories {
mavenRepo(url: localMavenRepo)
mavenCentral()
mavenRepo(url: 'http://download.java.net/maven/2/')
mavenRepo(url: 'https://maven.atlassian.com/content/groups/public')
mavenRepo(url: 'http://snapshots.repository.codehaus.org')
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.10'
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.9.0'
testCompile group: 'org.benchy', name: 'benchy-driver', version: '0.1-SNAPSHOT'
deployerJars "org.apache.maven.wagon:wagon-ssh:2.2"
deployerJars group: 'org.apache.maven.wagon', name: 'wagon-webdav-jackrabbit', version: '2.2'
}
task benchmarkUncontendedMonoUpdate << {
executeBenchmark("benchmarks/uncontended_mono_update_benchmark.groovy")
executeDisplay("benchmarks/uncontended_mono_update_display.groovy")
}
task benchmarkCounter << {
executeBenchmark("benchmarks/contended_counter_benchmark.groovy")
executeDisplay("benchmarks/contended_counter_display.groovy")
}
task benchmarkMonoRead << {
executeBenchmark("benchmarks/mono_read_benchmark.groovy")
executeDisplay("benchmarks/mono_read_display.groovy")
}
task benchmarkAtomicGet << {
executeBenchmark("benchmarks/atomic/atomic_get_benchmark.groovy")
executeDisplay("benchmarks/atomic/atomic_get_display.groovy")
}
task benchmarkAtomicWeakGet << {
executeBenchmark("benchmarks/atomic/atomic_weak_get_benchmark.groovy")
executeDisplay("benchmarks/atomic/atomic_weak_get_display.groovy")
}
task benchmarkAtomicIncrement << {
executeBenchmark("benchmarks/atomic/atomic_increment_benchmark.groovy")
executeDisplay("benchmarks/atomic/atomic_increment_display.groovy")
}
task benchmarkAtomicLongIncrement << {
executeBenchmark("benchmarks/atomic/atomic_long_increment_benchmark.groovy")
executeDisplay("benchmarks/atomic/atomic_long_increment_display.groovy")
}
task benchmarkSimpleStack << {
executeBenchmark("benchmarks/blocking/simple_stack_benchmark.groovy")
}
task benchmarkIntrinsicLockStack << {
executeBenchmark("benchmarks/blocking/intrinsic_lock_stack_benchmark.groovy")
//execute("benchy-display benchmarks/atomic_weak_get_display.groovy")
}
task benchmarkJucLockStack << {
executeBenchmark("benchmarks/blocking/juc_lock_stack_benchmark.groovy")
//execute("benchy-display benchmarks/atomic_weak_get_display.groovy")
}
task benchmarkOrecUpdate << {
executeBenchmark("benchmarks/orec/update_benchmark.groovy")
//execute("benchy-display benchmarks/atomic_weak_get_display.groovy")
}
task benchmarkOrecRead << {
executeBenchmark("benchmarks/orec/update_benchmark.groovy")
//execute("benchy-display benchmarks/atomic_weak_get_display.groovy")
}
task benchmarkBoxingOverhead << {
executeBenchmark("benchmarks/overhead/boxing_overhead_benchmark.groovy")
executeDisplay("benchmarks/overhead/boxing_overhead_display.groovy")
executeDisplay("benchmarks/overhead/boxing_overhead_total_display.groovy")
}
task benchmark(dependsOn: [
benchmarkUncontendedMonoUpdate,
benchmarkCounter,
benchmarkMonoRead,
benchmarkAtomicGet,
benchmarkAtomicWeakGet,
benchmarkSimpleStack,
benchmarkIntrinsicLockStack,
benchmarkJucLockStack,
benchmarkAtomicIncrement,
benchmarkAtomicLongIncrement,
benchmarkOrecUpdate,
benchmarkOrecRead,
benchmarkBoxingOverhead]) << {}
test {
exclude("**/*AbstractTest*")
exclude("**/*Benchmark*")
exclude("**/*StressTest*")
exclude("**/*stressTest*")
exclude("**/*LongTest*")
exclude("**/*PerformanceTest*")
exclude("**/*performanceTest*")
exclude("**/*Driver*")
}
task shortintegrationtest(type: Test) {
include("**/*StressTest*")
include("**/*stressTest*")
include("**/*LongTest*")
include("**/*longTest*")
}
task integrationtest(type: Test) {
include("**/*StressTest*")
include("**/*stressTest*")
include("**/*LongTest*")
include("**/*longTest*")
}
shortintegrationtest {
jvmArgs = ["-Dorg.multiverse.integrationtest.durationMs=10000", "-Dorg.multiverse.bugshaker.enabled=true"]
}
task deploy(dependsOn: ['clean', 'javadoc', 'install', 'uploadArchives']) << {
}
// custom tasks for creating source/javadoc jars
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
// add javadoc/source jar tasks as artifacts
artifacts {
archives sourcesJar
archives javadocJar
}
uploadArchives() {
repositories.mavenDeployer {
name = 'sshDeployer'
uniqueVersion = false
configuration = configurations.deployerJars
repository(
url: 'dav.codehaus.org/repository/multiverse/') {
authentication(userName: "$codehaus_loginname", password: "$codehaus_password")
}
snapshotRepository(
url: 'dav.codehaus.org/snapshots.repository/multiverse/') {
authentication(userName: "$codehaus_loginname", password: "$codehaus_password")
}
}
}
}
project(':multiverse-site') {
task clean << {
ant.delete(dir: "${projectDir}/build")
}
task install(dependsOn: clean) << {
def binding = new Binding()
def parent = Groovy.class.getClassLoader()
def loader = new GroovyClassLoader(parent)
def shell = new GroovyShell(loader, binding)
shell.evaluate(new java.io.File("multiverse-site/menu.groovy"))
println "Copying charts"
ant.copy(todir: "${projectDir}/build/site") {
fileset(dir: "../charts")
}
println "Finished copying charts"
}
}
Multiverse-multiverse-0.7.0/charts/ 0000775 0000000 0000000 00000000000 11740006171 0017333 5 ustar 00root root 0000000 0000000 Multiverse-multiverse-0.7.0/charts/atomic_get_bar.png 0000664 0000000 0000000 00000057451 11740006171 0023014 0 ustar 00root root 0000000 0000000 ‰PNG
IHDR ô Å@Ix ^ðIDATxÚíÝ}PVw~ÿÿÌt:N§Óé?Nÿètv¦ÓéN§l’M²¬……º²ýá~uõ»"k´Ü¨aÁl"Ñ%¢¢Œ–àz1ÞÅ›HL51ÊjQ‚+òµºø©Ä”à5X>ßóþÈuýÎuqÝœs®ÃÅ<_Î{¼8çpÎŹÎÝãúœ›g!„B!„Ä(Ï0!„B! „B!„@!„B!€B!„B !„L·|ç;ßQÏ<óŒ¯þú¯ÿzêí&ãgB! „B¦aòóóƒçææ9~ü¸ßtþüÏÿ\íÙ³G
êþG£OZGž}öY B! „B¦OþçþGýÙŸý™ï õOþäOüœ9ص—ÿüÏÿÔ§XyçËýÑ©;wîL)`B !„â8çÏŸ÷;h}õÕWý~þøãÃäZ9èÖ[*;;[ýÕ_ý•úƒ?ø}Ä_þå_ên7oÞ´|0ýæ›ojÉ8¤å@Þ»¤««KË{Åßÿýß«ƒÚ>@ïììTk×®UÏ?ÿ¼úÃ?üC=.ÙOúSõ›ßüÆÒü\¿~½ß4Ö[çès´HËÔßþíßúÞ‹üíóæÍsjœ“Ï„B !„ ÉÏ~ö3ߪä
éÿ½ÝäBéhvwïÞ~ï÷~/ì°UUU± Àö»r·˜ëwèÐ!Ë ‘k6¤µ"Úx¹¸Üü;¶?ù›YáÞ‹@€B !„I•ááaýíº÷ 5--MwONNöu“þ2\$ ‹|SoFZä¥ÞÞÞ1ꑾ՗;I Žäàûì3¿~2l¸ñËEÛ¹€;°ßÕ«Wu?9Ø7wXyÏrZ“¹ûöíÛÏS3d‚Í—HYYY~ÝïÞ½ëëø·'$$ B „2y2kÖ,¿Ö/¾øBw—ÿÍÝe8' 1_ŒØ ßè›ûɰáÆoþÝpý Ô{6_x/%ÏïpšH- ‘ ø^•U`B „2ᑃlóµrQ¸9æë*ä ¾¯¯ÏöÁ®Ö ÖêøÝîé}ÚÉK/½ä7.;Ù{/v®ë „@!$nóî»ïÚ:Е‹Éíì†k <(RÈxös³$ð.Xæ‹Å¼—Ày&óÉò΀B !„x\?` N®7póñìçæ5 r½ù èòZnló,Øí„!„ B™T‘âÀƒUy†9ííía‡ ¼õmà]¬$wÁ’gwÈ]°¤äŽXánWK€È5/æSŸäÚ
ï]°¼‡<ÄjΞ=ë79½íƒ>ðµ É]·B½—Ày&óY°&‘ß—ß•Û{‚º•Ï„B !„˜§¼¼Üï@U®[–À[åÊݱ¼)**²t]‚ÈGzÈ;ï¼3vCC€Hä–¶§?EÓ¢ =ñáèZ+ó,Øû±ú™B „ÓÈ“ÂÃ]ßáÀÀ<Ü?üÃ?øúÉ·ñr}ÃßýÝßE¼ˆ[ZäßùÎwô°RòTté&ßèÝÐÇ i2? Ý{
•´~xoõk'òl™‡?ùÉOôu&òw,ä9#2/å–»•••êË/¿9ÏþæoþÆ÷{$yFË믿ôâv;Ÿ !„ B!„B „B!„ B!„B! „B!„@!„B!€B!„B !„B!„ B!„B !„B!„ B!„B „B!„ B!„B! „B!„@ˆ»yýõ×ý~ÎÏÏW¯¾ú*EQEQE¹ZÇ €è,]ºT}öÙgEQEQåj@(Š¢(Š¢( B EQEQ@ ¡(Š¢(Š¢¨é„„„1˜šš•’’¢«ººÚv·ÇïÓ EQEQ p9{ö¬ÊËËSº
t7«ýÝ_¼O€PEQEQ $
€ÈÁwss³ïgy››k¹¿Ûã‹÷銢(Š¢(
€D HZZšJLLTóçÏWð럜œ¬FFF|?Ëkéfµ`¢_¼O€PEQEQ Äb:::TQQ‘ÚµkWØÁŠÕþVZ\ìŒ/Þ§@(Š¢(Š¢( b#ƒƒƒúbkZ@ìOO o™#OBooo×§oÉ‚"ÿó3?ó3?ó3?ó3?ó3?Gûó”H°k ¤›ÕþV®É°3¾xŸ- EQEQ- aRVV¦:;;õ먒’UQQ1æ.Pýýýaïªà)LÑŽ/Þ¦@(Š¢(Š¢( b#õõõjÑ¢EúÀ=33S_ÿáñxü†‘g_„{F¸þÁ®¡ˆf|ñ6= BQEQE8JRRÒ”ž ¡(Š¢(Š¢ EQEQ „¢(Š¢(Š¢ Ô˜ºô駪áìYÕÐРΜQ
~ø´¤[]jøè#=óŠ¢(Š¢( B u :Œïé‡8{¶Róæ)µhÑÓnË—+µj•&ÞÿŽë\WÝÛºUw‰QoµÑ¨MFm5ªÒ¨²nuåÜ>sŠ¢(Š €PS gΨ<ãßlãß<ãß"ãßRãßrãß*ãßãŸÍ4šßkVj¥ü
F‚1 ão0ÊøŒI(õeü
Sú³¼ví”jkk3j—QÕFյרFR_|q€ež¢(Š €P €¸SÑ2èLZÎ2Põõçù¶/$ÚÚÚ~‡a^QE@¨ä7| .\¸à«X ¤±ñ˜jnn6ê=£jzߨ£FI÷êúõS €D¿üËRÿfÁY¢‡a^QE@¨dÛš5úóöÖÙ³g]ÈÉ+'Õ'Ÿ|â«þþ‚°ÓÝÝlä`ÅAõÎ;ïøÊ ¦¼õEMÍÓÓvíRmÕÕªM~Þ»Wµ8 ÚR'N BQE@¨xÈšmþÓø¯ÿÊs ÛÖló›Æ¿ýÛ¿9žoC?ÿyØyÖ¾m[Üä¿ÿ;O>|ØWGÕóM·4ÉÿµF½oÔQ£Žu¢Y]ýè* EQ „
€L€ü|èç£s ø|{·í][ éïÕïïÿÕ¯~õtÐп¢ÚªÛ¦=@êêöi¬yKZèØvPE@¨iŽŽ7Ô‡~è«ë¿¾× 9uêš>ek×®6UmÔ×Ô´©½{ÛÔmêÐ!ùÿ § Ù°lÖÕÕ±í (Š €PÓ
Ÿžë7üé_Ž+€üvýzuðàA_mÛÖnpãÿ! @(Š¢( B Î òYAß´6n¼ê:@ª[«ÕÅ‹}5 i®löki:þ<