Skip to content

Use multi thread to increase speed and use CommitEvent to decrease conflict

Bruce Yang CL edited this page Jan 23, 2021 · 9 revisions

example: GroupBy is slow, sometimes you need realtime numbers when each new Record inserted. Use multi-thread can increase speed and use CommitEvent can decrease conflict.

package example;

import iboxdb.localserver.*;
import java.io.File;
import java.text.NumberFormat;
import java.util.Random;
import java.util.concurrent.*;

public class MainClass {

    public static class ThreadRegion {

        private final ExecutorService ess;

        public ThreadRegion(int length) {
            ess = Executors.newFixedThreadPool(length);
        }

        public Future<?> put(Runnable task) {
            return ess.submit(task);
        }

        public void close() {
            ess.shutdown();
        }
    }

    public static void main(String[] args) throws Exception {
        int taskCount = 10000;
        int batchCount = 10;

        String path = "../DATA_TEST";
        new File(path).mkdirs();
        System.out.println("Path: " + new File(path).getAbsolutePath());
        DB.root(path);
        BoxSystem.DBDebug.DeleteDBFiles(1);

        DB db = new DB(1);
        db.getConfig()
                .ensureTable(Record.class, "Record", "id")
                .ensureTable(RegionCount.class, "RegionCount", "region");

        try (Database _tmp = db.open().getDatabase()) {

            AutoBox auto = db.open();

            ThreadRegion threadRegion = new ThreadRegion(11);
            Random random = new Random();

            long beginTime = System.currentTimeMillis();
            CountDownLatch countDown = new CountDownLatch(taskCount);
            for (int i = 0; i < taskCount; i++) {
                String region = ("Region-" + (random.nextInt(8) + 1));
                Future<?> future = threadRegion.put(() -> {

                    try (Box box = auto.cube()) {
                        for (int j = 0; j < batchCount; j++) {
                            int id = (int) box.newId(0, 1);
                            Record r = new Record(id, "Game-" + id, region);
                            box.d("Record").insert(r);

                        }
                        CommitResult cr = box.commit(
                                () -> {
                                    Binder bindRC = box.d("RegionCount", region);
                                    RegionCount rc = bindRC.select(RegionCount.class);
                                    if (rc == null) {
                                        rc = new RegionCount();
                                        rc.region = region;
                                        rc.count = 0;
                                    }
                                    rc.count += batchCount;
                                    bindRC.replace(rc);
                                }
                        );
                        if (cr != CommitResult.OK) {
                            System.out.println("Debug: ");
                        }
                    } finally {
                        countDown.countDown();
                    }

                });
            }
            countDown.await();
            long endTime = System.currentTimeMillis();

            long count = 0;
            for (RegionCount rc : auto.select(RegionCount.class, "from RegionCount")) {
                count += rc.count;
                System.out.println(rc.region + " : " + rc.count);
            }
            if (count != (taskCount * batchCount)) {
                System.out.println("Debug: ");
            } else {
                double t = ((endTime - beginTime) / 1000.0);
                System.out.println("Realtime Counting " + NumberFormat.getInstance().format(count)
                        + " objects, elapsed: " + t + "s"
                        + ", avg: " + NumberFormat.getInstance().format((int) (count / t)) + "/s");
            }

            threadRegion.close();
        }
    }

    public static class Record {

        public Record() {
        }

        public Record(int id, String name, String region) {
            this.id = id;
            this.name = name;
            this.region = region;
        }
        public int id;
        public String name;
        public String region;
    }

    public static class RegionCount {

        public String region;
        public long count;
    }
}

SS-Transaction

try (Box box = auto.cube()) {
  //Application Point
  //MVCC-based database Snapshot isolation
  ...
  box.commit(() -> {
     //Database Point
     //Lock-based database Serializable isolation
     ...
  });
}

public Future<?> put(Runnable task) {
  return ess.submit(task);
}

Clone this wiki locally