├── IO ├── MMapConfig.java └── NoIOConfig.java ├── README.md ├── Replication ├── BoxReplication.cs ├── BoxReplication.java ├── FileBackup.cs ├── HotFileBackup.java ├── IOutBox.cs └── rsyncsh.sh ├── benchmark ├── BenchmarkDBTest.java └── BenchmarkDBTestMySQL.java ├── demos ├── KeyOnly.java └── README.md ├── images ├── js.gif └── show.png └── java9 ├── README.md └── module-info.class /IO/MMapConfig.java: -------------------------------------------------------------------------------- 1 | package iBoxDB.XT.IO; 2 | 3 | import java.io.*; 4 | import java.nio.*; 5 | import java.nio.channels.FileChannel.MapMode; 6 | import java.util.*; 7 | 8 | import iBoxDB.LocalServer.IO.*; 9 | 10 | public class MMapConfig extends BoxFileStreamConfig { 11 | 12 | private int MaxFile = 1024; 13 | private long FileSize = 1024 * 1024 * 256; 14 | private long maxMemory = FileSize * 4; 15 | 16 | HashMap map = new HashMap(); 17 | 18 | public MMapConfig() { 19 | this.ReadStreamCount = 1; 20 | } 21 | 22 | @Override 23 | public IBStream CreateStream(String path, StreamAccess access) { 24 | if (path.endsWith(".swp") || path.endsWith(".buf") 25 | || path.endsWith(".frag")) { 26 | return super.CreateStream(path, access); 27 | } 28 | path = BoxFileStreamConfig.RootPath + path; 29 | MManager manager = map.get(path); 30 | if (manager == null) { 31 | manager = new MManager(path); 32 | map.put(path, manager); 33 | } 34 | return manager.get(access); 35 | } 36 | 37 | @Override 38 | public void close() { 39 | for (MManager m : map.values()) { 40 | m.close(); 41 | } 42 | map.clear(); 43 | super.close(); 44 | System.gc(); 45 | System.runFinalization(); 46 | } 47 | 48 | private class MManager { 49 | 50 | private String fullPath; 51 | private long length; 52 | 53 | private RandomAccessFile[] files = new RandomAccessFile[MaxFile]; 54 | private MappedByteBuffer[] mapReaders = new MappedByteBuffer[MaxFile]; 55 | private MappedByteBuffer[] mapWriters = new MappedByteBuffer[MaxFile]; 56 | 57 | public MManager(String fPath) { 58 | fullPath = fPath; 59 | 60 | length = 0; 61 | if ((new File(fullPath)).exists()) { 62 | length += FileSize; 63 | } 64 | } 65 | 66 | public void close() { 67 | flush(); 68 | if (files != null) { 69 | try { 70 | for (RandomAccessFile m : files) { 71 | if (m != null) { 72 | m.close(); 73 | } 74 | } 75 | } catch (Exception e) { 76 | e.printStackTrace(); 77 | } 78 | } 79 | files = null; 80 | mapWriters = null; 81 | mapReaders = null; 82 | } 83 | 84 | public void flush() { 85 | synchronized (this) { 86 | if (mapWriters != null) { 87 | for (MappedByteBuffer m : mapWriters) { 88 | if (m != null) { 89 | m.force(); 90 | } 91 | } 92 | } 93 | } 94 | } 95 | 96 | private IBStream get(StreamAccess access) { 97 | return new MStream(access == StreamAccess.Read ? mapReaders 98 | : mapWriters); 99 | } 100 | 101 | private class MStream implements IPartitionStream { 102 | 103 | MappedByteBuffer[] bufs; 104 | 105 | public MStream(MappedByteBuffer[] mappedByteBuffers) { 106 | this.bufs = mappedByteBuffers; 107 | } 108 | 109 | @Override 110 | public void Dispose() { 111 | bufs = null; 112 | } 113 | 114 | @Override 115 | public void BeginWrite(long appID, int maxLen) 116 | { 117 | 118 | } 119 | 120 | @Override 121 | public void EndWrite() 122 | { 123 | 124 | } 125 | 126 | @Override 127 | public void Flush() { 128 | } 129 | 130 | @Override 131 | public long Length() { 132 | return length; 133 | } 134 | 135 | @Override 136 | public void SetLength(long value) { 137 | } 138 | 139 | @Override 140 | public int Read(long position, byte[] buffer, int offset, int count) { 141 | synchronized (mapReaders) { 142 | GetCurrent(position).get(buffer, offset, count); 143 | return count; 144 | } 145 | } 146 | 147 | @Override 148 | public void Write(long position, byte[] buffer, int offset, 149 | int count) { 150 | GetCurrent(position).put(buffer, offset, count); 151 | } 152 | 153 | @Override 154 | public boolean Suitable(long position, int len) { 155 | int fileOffset = (int) (position / FileSize); 156 | int fileOffset1 = (int) ((position + len) / FileSize); 157 | return fileOffset == fileOffset1; 158 | } 159 | 160 | private MappedByteBuffer GetCurrent(long position) { 161 | int fileOffset = (int) (position / FileSize); 162 | MappedByteBuffer current = bufs[fileOffset]; 163 | if (current == null) { 164 | synchronized (mapWriters) { 165 | current = bufs[fileOffset]; 166 | if (current == null) { 167 | try { 168 | String pfile = fileOffset == 0 ? fullPath 169 | : fullPath + fileOffset; 170 | files[fileOffset] = new RandomAccessFile(pfile, 171 | "rw"); 172 | length += FileSize; 173 | mapWriters[fileOffset] = files[fileOffset] 174 | .getChannel().map(MapMode.READ_WRITE, 175 | 0, FileSize); 176 | mapReaders[fileOffset] = (MappedByteBuffer) mapWriters[fileOffset] 177 | .duplicate(); 178 | } catch (Throwable e) { 179 | files = null; 180 | mapWriters = null; 181 | mapReaders = null; 182 | e.printStackTrace(); 183 | } 184 | if (position > maxMemory) { 185 | flush(); 186 | } 187 | } 188 | } 189 | current = bufs[fileOffset]; 190 | } 191 | current.position((int) (position - (fileOffset * FileSize))); 192 | return current; 193 | } 194 | } 195 | 196 | } 197 | 198 | } 199 | -------------------------------------------------------------------------------- /IO/NoIOConfig.java: -------------------------------------------------------------------------------- 1 | package iBoxDB.XT.IO; 2 | 3 | import iBoxDB.LocalServer.DatabaseConfig; 4 | import iBoxDB.LocalServer.SwapType; 5 | import iBoxDB.LocalServer.IO.IBStream; 6 | import iBoxDB.LocalServer.IO.StreamAccess; 7 | 8 | // In-Memory Config 9 | public class NoIOConfig extends DatabaseConfig { 10 | 11 | public NoIOConfig() { 12 | this.ReadStreamCount = 8; 13 | this.CacheLength = Long.MAX_VALUE; 14 | this.FileIncSize = Integer.MAX_VALUE; 15 | } 16 | 17 | @Override 18 | public IBStream CreateStream(String path, StreamAccess access) { 19 | return new BStream(); 20 | } 21 | 22 | @Override 23 | public boolean ExistsStream(String path) { 24 | return false; 25 | } 26 | 27 | @Override 28 | public SwapType GetSwapType() { 29 | return SwapType.None; 30 | } 31 | 32 | private final class BStream implements IBStream { 33 | 34 | @Override 35 | public void BeginWrite(long pos, int maxLen) { 36 | } 37 | 38 | @Override 39 | public void Dispose() { 40 | } 41 | 42 | @Override 43 | public void EndWrite() { 44 | } 45 | 46 | @Override 47 | public void Flush() { 48 | } 49 | 50 | @Override 51 | public long Length() { 52 | return 0; 53 | } 54 | 55 | @Override 56 | public int Read(long position, byte[] buffer, int offset, int count) { 57 | return 0; 58 | } 59 | 60 | @Override 61 | public void SetLength(long len) { 62 | } 63 | 64 | @Override 65 | public void Write(long position, byte[] buffer, int offset, int count) { 66 | } 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MMF IOs, Examples... for iBoxDB Fast Transactional Table Style Document NoSQL Application Database 2 | 3 | 4 | [Goto Web Site http://www.iboxdb.com](http://www.iboxdb.com) 5 | 6 | [Goto Web Site Mirror](https://github.com/iboxdb/iboxdb.github.io) 7 | 8 | 9 | ![](https://github.com/iboxdb/forjava/raw/master/images/js.gif) 10 | 11 | [Wiki Code](https://github.com/iboxdb/forjava/wiki) 12 | 13 | [Full Text Search Project](https://github.com/iboxdb/ftserver) 14 | 15 | 16 | -------------------------------------------------------------------------------- /Replication/BoxReplication.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using iBoxDB.LocalServer.Helper; 4 | using iBoxDB.LocalServer.IO; 5 | 6 | namespace iBoxDB.LocalServer.Replication 7 | { 8 | 9 | public sealed class BoxReplication 10 | { 11 | 12 | public static IBox MasterReplicate(IDatabase self, params BoxData[] data) 13 | { 14 | return MasterReplicate(self, long.MaxValue, data); 15 | } 16 | public static IBox MasterReplicate(IDatabase self, long dest, params BoxData[] data) 17 | { 18 | if (data == null || data.Length < 1) { return null; } 19 | IBox box = null; 20 | 21 | foreach (var d in data) 22 | { 23 | var actions = d.GetActions(); 24 | if (actions != null && actions.Count > 0) 25 | { 26 | box = box == null ? self.Cube(dest) : box; 27 | foreach (var e in actions) 28 | { 29 | MasterAction(e, (ILocalBox)box); 30 | } 31 | } 32 | } 33 | return box; 34 | 35 | } 36 | 37 | private static bool MasterAction(BEntity op, ILocalBox box) 38 | { 39 | switch (op.ActionType) 40 | { 41 | case ActionType.Insert: 42 | return box.Insert(op.TableName, op.Value, op.Length).Has(); 43 | case ActionType.Delete: 44 | return box.Delete(op.TableName, op.Key).Has(); 45 | case ActionType.Update: 46 | if (box.Update(op.TableName, op.Key, op.Value).Has()) 47 | { 48 | return true; 49 | } 50 | else 51 | { 52 | return box.Insert(op.TableName, op.Value, op.Length).Has(); 53 | } 54 | } 55 | throw new Exception(""); 56 | } 57 | 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Replication/BoxReplication.java: -------------------------------------------------------------------------------- 1 | package iBoxDB.LocalServer.Replication; 2 | 3 | import iBoxDB.LocalServer.ActionType; 4 | import iBoxDB.LocalServer.BEntity; 5 | import iBoxDB.LocalServer.Box; 6 | import iBoxDB.LocalServer.Database; 7 | import iBoxDB.LocalServer.LocalBox; 8 | 9 | import java.util.ArrayList; 10 | 11 | //BoxReplication.masterReplicate(masterA, new BoxData(p.OutBox)).commit().Assert(); 12 | public final class BoxReplication { 13 | 14 | public static Box masterReplicate(Database self, BoxData... data) { 15 | return masterReplicate(self, Long.MAX_VALUE, data); 16 | } 17 | 18 | public static Box masterReplicate(Database self, long dest, BoxData... data) { 19 | if (data == null || data.length < 1) { 20 | return null; 21 | } 22 | Box box = null; 23 | 24 | for (final BoxData d : data) { 25 | ArrayList actions = new ArrayList() { 26 | { 27 | for (BEntity b : d.getActions()) { 28 | this.add(b); 29 | } 30 | } 31 | }; 32 | 33 | if (actions != null && actions.size() > 0) { 34 | box = box == null ? self.cube(dest) : box; 35 | 36 | for (BEntity e : actions) { 37 | MasterAction(e, (LocalBox) box); 38 | } 39 | } 40 | } 41 | return box; 42 | 43 | } 44 | 45 | private static boolean MasterAction(BEntity op, LocalBox box) { 46 | switch (op.ActionType.Ord) { 47 | case ActionType.Ord_Insert: 48 | return box.Insert(op.TableName, op.Value, op.Length).has(); 49 | case ActionType.Ord_Delete: 50 | return box.Delete(op.TableName, op.Key).has(); 51 | case ActionType.Ord_Update: 52 | if (box.Update(op.TableName, op.Key, op.Value).has()) { 53 | return true; 54 | } else { 55 | return box.Insert(op.TableName, op.Value, op.Length).has(); 56 | } 57 | } 58 | throw new RuntimeException(""); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /Replication/FileBackup.cs: -------------------------------------------------------------------------------- 1 | using iBoxDB.DBDebug; 2 | using iBoxDB.LocalServer.IO; 3 | using System; 4 | using System.Linq; 5 | using System.Collections.Generic; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace iBoxDB.LocalServer.Replication 10 | { 11 | //Phase 1, copy main file 12 | //Phase 2, copy changed data 13 | public class FileBackupBoxRecycler : IBoxRecycler2 14 | { 15 | volatile bool receiving = false; 16 | volatile List list; 17 | volatile Mirror mirror; 18 | 19 | public void Backup(IDatabase database, long backupAddress, string backuproot = null) 20 | { 21 | Phase1(database, backupAddress, backuproot); 22 | Phase2(); 23 | } 24 | public void Phase1(IDatabase database, long backupAddress, string backuproot = null) 25 | { 26 | lock (this) 27 | { 28 | if (list != null || mirror != null) { throw new Exception(); } 29 | list = new List(); 30 | } 31 | 32 | var bakConfig = new BoxFileStreamConfig(); 33 | if (backuproot != null) 34 | { 35 | bakConfig.LocalRootPath = backuproot; 36 | } 37 | bakConfig.SwapFileBuffer = 0; 38 | //bakConfig.ReadStreamCount = 0; 39 | //bakConfig.FileIncSize = 0; 40 | mirror = new Mirror(bakConfig, backupAddress); 41 | 42 | using (var reader = database.CreateFileReader()) 43 | { 44 | long pos = 0; 45 | long len = reader.Length; 46 | var buf = new byte[1024 * 1024 * 1]; 47 | while (pos < len) 48 | { 49 | int count = reader.Read(pos, buf, 0, buf.Length); 50 | mirror.Write(pos, buf, 0, count); 51 | pos += count; 52 | } 53 | } 54 | } 55 | public void Phase2() 56 | { 57 | while (receiving) 58 | { 59 | //Thread.Sleep(10); 60 | } 61 | List backupList; 62 | lock (this) 63 | { 64 | backupList = list; 65 | list = null; 66 | } 67 | mirror.Write(backupList.ToArray()); 68 | mirror.Dispose(); 69 | mirror = null; 70 | } 71 | 72 | public void OnReceiving(Socket socket) 73 | { 74 | receiving = true; 75 | } 76 | public void OnReceived(Socket socket, BoxData outBox, bool normal) 77 | { 78 | lock (this) 79 | { 80 | if (list != null) 81 | { 82 | list.Add(outBox); 83 | } 84 | } 85 | } 86 | public void OnFlushed(Socket socket) 87 | { 88 | receiving = false; 89 | } 90 | 91 | public void Dispose() 92 | { 93 | 94 | } 95 | } 96 | 97 | public class BackupTest 98 | { 99 | public class DBObject : IEquatable 100 | { 101 | public long ID; 102 | public String Value; 103 | public DateTime DT; 104 | 105 | public bool Equals(DBObject other) 106 | { 107 | return ID == other.ID && Value == other.Value && DT == other.DT; 108 | } 109 | 110 | } 111 | public static bool Test(bool background) 112 | { 113 | var bakAddr = 0 - Math.Abs(DateTime.Now.Ticks); 114 | 115 | DDebug.DeleteDBFiles(1); 116 | DB server = new DB(1); 117 | server.SetBoxRecycler(new FileBackupBoxRecycler()); 118 | server.GetConfig().EnsureTable("DBObject", "ID"); 119 | DB.AutoBox auto = server.Open(); 120 | 121 | Parallel.For(0, 300, (i) => 122 | { 123 | var obj = new DBObject(); 124 | obj.ID = auto.NewId(0); 125 | obj.Value = "Value " + obj.ID; 126 | obj.DT = DateTime.Now; 127 | auto.Insert("DBObject", obj); 128 | }); 129 | 130 | 131 | // Export 132 | if (background) 133 | { 134 | Thread backupThread = new Thread(() => 135 | { 136 | ((FileBackupBoxRecycler)auto.GetDatabase().GetBoxRecycler()).Phase1(auto.GetDatabase(), bakAddr); 137 | }); 138 | backupThread.Start(); 139 | 140 | Parallel.For(0, 300, (i) => 141 | { 142 | var obj = new DBObject(); 143 | obj.ID = auto.NewId(0); 144 | obj.Value = "Value " + obj.ID; 145 | obj.DT = DateTime.Now; 146 | auto.Insert("DBObject", obj); 147 | }); 148 | 149 | backupThread.Join(); 150 | ((FileBackupBoxRecycler)auto.GetDatabase().GetBoxRecycler()).Phase2(); 151 | } 152 | else 153 | { 154 | ((FileBackupBoxRecycler)auto.GetDatabase().GetBoxRecycler()).Backup(auto.GetDatabase(), bakAddr); 155 | } 156 | 157 | 158 | //Import 159 | DB bakserver = new DB(bakAddr); 160 | bakserver.GetConfig().DBConfig.SwapFileBuffer = 0; 161 | DB.AutoBox bakauto = bakserver.Open(); 162 | 163 | DBObject[] s1 = auto.Select("from DBObject").ToArray(); 164 | DBObject[] s2 = bakauto.Select("from DBObject").ToArray(); 165 | 166 | server.Dispose(); 167 | bakserver.Dispose(); 168 | DDebug.DeleteDBFiles(bakAddr); 169 | return s1.SequenceEqual(s2); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /Replication/HotFileBackup.java: -------------------------------------------------------------------------------- 1 | package iBoxDB.XT.Replication; 2 | 3 | import java.util.*; 4 | 5 | import iBoxDB.LocalServer.*; 6 | import iBoxDB.LocalServer.BoxSystem.DBDebug; 7 | import iBoxDB.LocalServer.IO.*; 8 | import iBoxDB.LocalServer.Replication.*; 9 | 10 | //Phase 1, copy main file 11 | //Phase 2, copy changed data 12 | public class HotFileBackup implements IBoxRecycler2 { 13 | volatile boolean receiving = false; 14 | volatile ArrayList list; 15 | volatile Mirror mirror; 16 | 17 | public void backup(Database database, long backupAddress, String backuproot) { 18 | phase1(database, backupAddress, backuproot); 19 | phase2(); 20 | } 21 | 22 | public void phase1(Database database, long backupAddress, String backuproot) { 23 | synchronized (this) { 24 | if (list != null || mirror != null) { 25 | throw new RuntimeException(); 26 | } 27 | list = new ArrayList(); 28 | } 29 | 30 | BoxFileStreamConfig bakConfig = new BoxFileStreamConfig(); 31 | if (backuproot != null) { 32 | bakConfig.LocalRootPath = backuproot; 33 | } 34 | bakConfig.SwapFileBuffer = 0; 35 | // bakConfig.ReadStreamCount = 0; 36 | // bakConfig.FileIncSize = 0; 37 | mirror = new Mirror(bakConfig, backupAddress); 38 | 39 | IBStreamReader reader = database.createFileReader(); 40 | try { 41 | long pos = 0; 42 | long len = reader.length(); 43 | byte[] buf = new byte[1024 * 1024 * 1]; 44 | while (pos < len) { 45 | int count = reader.read(pos, buf, 0, buf.length); 46 | mirror.write(pos, buf, 0, count); 47 | pos += count; 48 | } 49 | } finally { 50 | reader.close(); 51 | } 52 | } 53 | 54 | public void phase2() { 55 | while (receiving) { 56 | /* 57 | try { 58 | Thread.sleep(10); 59 | } catch (InterruptedException e) { 60 | } 61 | */ 62 | } 63 | ArrayList backupList; 64 | synchronized (this) { 65 | backupList = list; 66 | list = null; 67 | } 68 | mirror.write(backupList.toArray(new BoxData[backupList.size()])); 69 | mirror.close(); 70 | mirror = null; 71 | } 72 | 73 | @Override 74 | public void onReceiving(Socket socket) { 75 | receiving = true; 76 | 77 | } 78 | 79 | @Override 80 | public void onReceived(Socket socket, BoxData outBox, boolean normal) { 81 | synchronized (this) { 82 | if (list != null) { 83 | list.add(outBox); 84 | } 85 | } 86 | } 87 | 88 | @Override 89 | public void onFlushed(Socket socket) { 90 | receiving = false; 91 | } 92 | 93 | @Override 94 | public void close() { 95 | 96 | } 97 | 98 | public static class BackupTest { 99 | public static boolean Test(boolean background) { 100 | final long bakAddr = 0 - Math.abs(System.currentTimeMillis()); 101 | DBDebug.DeleteDBFiles(1); 102 | DB server = new DB(1); 103 | server.setBoxRecycler(new HotFileBackup()); 104 | server.getConfig().ensureTable(DBObject.class, "DBObject", "ID"); 105 | final DB.AutoBox auto = server.open(); 106 | 107 | for (int i = 0; i < 300; i++) { 108 | DBObject obj = new DBObject(); 109 | obj.ID = auto.newId(0); 110 | obj.Value = "Value " + obj.ID; 111 | obj.DT = new Date(); 112 | auto.insert("DBObject", obj); 113 | } 114 | 115 | // Export 116 | if (background) { 117 | Thread backupThread = new Thread(new Runnable() { 118 | public void run() { 119 | ((HotFileBackup) auto.getDatabase().getBoxRecycler()) 120 | .phase1(auto.getDatabase(), bakAddr, null); 121 | } 122 | }); 123 | backupThread.start(); 124 | for (int i = 0; i < 300; i++) { 125 | DBObject obj = new DBObject(); 126 | obj.ID = auto.newId(0); 127 | obj.Value = "Value " + obj.ID; 128 | obj.DT = new Date(); 129 | auto.insert("DBObject", obj); 130 | } 131 | try { 132 | backupThread.join(); 133 | } catch (InterruptedException e) { 134 | e.printStackTrace(); 135 | } 136 | ((HotFileBackup) auto.getDatabase().getBoxRecycler()).phase2(); 137 | } else { 138 | ((HotFileBackup) auto.getDatabase().getBoxRecycler()).backup( 139 | auto.getDatabase(), bakAddr, null); 140 | } 141 | 142 | DB bakserver = new DB(bakAddr); 143 | bakserver.getConfig().DBConfig.SwapFileBuffer = 0; 144 | DB.AutoBox bakauto = bakserver.open(); 145 | 146 | DBObject[] s1 = toArray( 147 | auto.select(DBObject.class, "from DBObject"), 148 | new DBObject[0]); 149 | 150 | DBObject[] s2 = toArray( 151 | bakauto.select(DBObject.class, "from DBObject"), 152 | new DBObject[0]); 153 | 154 | server.close(); 155 | bakserver.close(); 156 | DBDebug.DeleteDBFiles(bakAddr); 157 | return Arrays.equals(s1, s2); 158 | } 159 | 160 | public static class DBObject { 161 | public long ID; 162 | public String Value; 163 | public Date DT; 164 | 165 | @Override 166 | public boolean equals(Object obj) { 167 | DBObject other = (DBObject) obj; 168 | return ID == other.ID && Value.equals(other.Value) 169 | && DT.equals(other.DT); 170 | } 171 | } 172 | 173 | private static E[] toArray(Iterable iterable, E[] t) { 174 | ArrayList list = new ArrayList(); 175 | if (iterable != null) { 176 | for (E e : iterable) { 177 | list.add(e); 178 | } 179 | } 180 | return list.toArray(t); 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /Replication/IOutBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using iBoxDB.LocalServer.Helper; 4 | using iBoxDB.LocalServer.IO; 5 | 6 | namespace iBoxDB.LocalServer.Replication 7 | { 8 | 9 | public sealed class BoxReplication 10 | { 11 | 12 | public static IBox MasterReplicate(IDatabase self, params BoxData[] data) 13 | { 14 | return MasterReplicate(self, long.MaxValue, data); 15 | } 16 | public static IBox MasterReplicate(IDatabase self, long dest, params BoxData[] data) 17 | { 18 | if (data == null || data.Length < 1) { return null; } 19 | IBox box = null; 20 | 21 | foreach (var d in data) 22 | { 23 | var actions = d.GetActions(); 24 | if (actions != null && actions.Count > 0) 25 | { 26 | box = box == null ? self.Cube(dest) : box; 27 | foreach (var e in actions) 28 | { 29 | MasterAction(e, (ILocalBox)box); 30 | } 31 | } 32 | } 33 | return box; 34 | 35 | } 36 | 37 | private static bool MasterAction(BEntity op, ILocalBox box) 38 | { 39 | switch (op.ActionType) 40 | { 41 | case ActionType.Insert: 42 | return box.Insert(op.TableName, op.Value); 43 | case ActionType.Delete: 44 | return box.Delete(op.TableName, op.Key); 45 | case ActionType.Update: 46 | if (box.Update(op.TableName, op.Key, op.Value)) 47 | { 48 | return true; 49 | } 50 | else 51 | { 52 | return box.Insert(op.TableName, op.Value); 53 | } 54 | } 55 | throw new Exception(""); 56 | } 57 | 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Replication/rsyncsh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # set backup path 4 | src=corex 5 | 6 | # run backup 7 | mkdir -p $src-backup 8 | 9 | mydate="`date +%Y%m%d_%H%M%S`" 10 | dest=$src-backup/$src-${mydate} 11 | 12 | counter=0 13 | while : 14 | do 15 | counter=$(($counter+1)) 16 | echo "$counter : rsync -iavzP $src $dest" 17 | tmpfile=$(mktemp) 18 | rsync -iavzP $src $dest | grep '^>' > "$tmpfile" 19 | 20 | if [[ $(wc -l < "$tmpfile") == "0" ]]; then 21 | break 22 | else 23 | cat $tmpfile 24 | fi 25 | 26 | rm $tmpfile 27 | sleep 2s 28 | done 29 | 30 | echo "" 31 | echo "BACKUP: $dest" 32 | -------------------------------------------------------------------------------- /benchmark/BenchmarkDBTest.java: -------------------------------------------------------------------------------- 1 | package benchmark; 2 | 3 | import java.util.*; 4 | import java.util.concurrent.*; 5 | import java.util.concurrent.atomic.*; 6 | 7 | import iBoxDB.LocalServer.*; 8 | import iBoxDB.LocalServer.IO.*; 9 | 10 | import com.mongodb.*; 11 | import com.mongodb.client.MongoCollection; 12 | import com.mongodb.client.MongoCursor; 13 | import com.mongodb.client.MongoDatabase; 14 | import org.bson.Document; 15 | 16 | // iBoxDB.java v2.8.3 17 | // mongodb-linux-x86_64-ubuntu1604-4.0.0, mongodb-driver-3.8.0.jar 18 | public class BenchmarkDBTest { 19 | 20 | static int threadCount = 100000; 21 | static int batchCount = 10; 22 | 23 | public static boolean UseMMAP = false; 24 | public static boolean UseMem = false; 25 | 26 | public static void main(String[] args) { 27 | try { 28 | 29 | System.out.println("threadCount=" + threadCount + " , batchCount=" 30 | + batchCount); 31 | 32 | // -Xmx1024m , following needs more memory 33 | iBoxDB.LocalServer.DB.root("/tmp"); 34 | UseMMAP = UseMem = false; 35 | System.out.println("iBoxDB(File Mode)"); 36 | TestiBoxDB(); 37 | System.out.println(); 38 | 39 | System.gc(); 40 | System.runFinalization(); 41 | UseMMAP = UseMem = false; 42 | UseMMAP = true; 43 | System.out.println("iBoxDB(MemoryMappedFile Mode)"); 44 | TestiBoxDB(); 45 | System.out.println(); 46 | 47 | System.gc(); 48 | System.runFinalization(); 49 | Thread.sleep(1000 * 15); 50 | 51 | UseMMAP = UseMem = false; 52 | UseMem = true; 53 | System.out.println("iBoxDB(InMemory Mode)"); 54 | TestiBoxDB(); 55 | 56 | System.out.println("MongoDB(Default)"); 57 | TestMongoDB(); 58 | 59 | System.out.println("Test End."); 60 | 61 | } catch (Exception e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | 66 | public static void TestiBoxDB() { 67 | BoxSystem.DBDebug.DeleteDBFiles(1); 68 | 69 | try (iBoxDBServer server = new iBoxDBServer()) { 70 | final Database db = server.getInstance(); 71 | System.out.print("Database Transaction Test: "); 72 | Box box1 = db.cube(); 73 | box1.d("T1").insert(T1.M(-1, Integer.toString(-1))); 74 | 75 | Box box2 = db.cube(); 76 | box2.d("T1").insert(T1.M(-2, Integer.toString(-2))); 77 | 78 | List transaction1 = T1 79 | .toArray(box1.select("from T1")); 80 | List transaction2 = T1 81 | .toArray(box2.select("from T1")); 82 | if (transaction1.size() == 1 83 | && transaction1.get(0).get("_id").equals(-1) 84 | && transaction2.size() == 1 85 | && transaction2.get(0).get("_id").equals(-2)) { 86 | System.out.println("Succeeded"); 87 | } else { 88 | System.out.println("Failed"); 89 | } 90 | box1.commit().Assert(); 91 | box2.commit().Assert(); 92 | 93 | long watch = System.currentTimeMillis(); 94 | final AtomicInteger count = new AtomicInteger(0); 95 | ExecutorService pool = CreatePool(); 96 | for (int i = 0; i < threadCount; i++) { 97 | final int p = i; 98 | pool.execute(new Runnable() { 99 | @Override 100 | public void run() { 101 | { 102 | Box box = db.cube(); 103 | for (int i = 0; i < batchCount; i++) { 104 | int id = (p * batchCount) + i; 105 | box.d("T1").insert(T1.M(id, Integer.toString(id))); 106 | } 107 | box.commit().Assert(); 108 | } 109 | { 110 | AutoBox box = db.get(); 111 | int minId = p * batchCount + 0; 112 | int maxId = p * batchCount + batchCount; 113 | Iterator reader = box 114 | .select("from T1 where _id>=? & _id m : box.select("from T1")) { 217 | //System.out.println(m.get("_id")); 218 | } 219 | } 220 | 221 | } catch (Exception e) { 222 | e.printStackTrace(); 223 | } 224 | } 225 | 226 | public static void TestMongoDB() throws Exception { 227 | MongoClient mongo = new MongoClient(); 228 | 229 | mongo.dropDatabase("test"); 230 | MongoDatabase db = mongo.getDatabase("test"); 231 | 232 | //System.out.print("Database Transaction Test: "); 233 | final MongoCollection coll = db.getCollection("T1"); 234 | 235 | long watch = System.currentTimeMillis(); 236 | final AtomicInteger count = new AtomicInteger(0); 237 | ExecutorService pool = CreatePool(); 238 | for (int i = 0; i < threadCount; i++) { 239 | final int p = i; 240 | pool.execute(new Runnable() { 241 | @Override 242 | public void run() { 243 | List list = new ArrayList<>(batchCount); 244 | for (int i = 0; i < batchCount; i++) { 245 | int id = (p * batchCount) + i; 246 | list.add(T1.O(id, Integer.toString(id))); 247 | } 248 | coll.insertMany(list); 249 | 250 | int minId = p * batchCount + 0; 251 | int maxId = p * batchCount + batchCount; 252 | Document bd = new Document(); 253 | bd.put("$gte", minId); 254 | bd.put("$lt", maxId); 255 | Document q = new Document(); 256 | q.put("_id", bd); 257 | 258 | try (MongoCursor reader = coll.find(q).iterator()) { 259 | int ti = minId; 260 | while (reader.hasNext()) { 261 | Integer iv = (Integer) reader.next().get("_id"); 262 | if (ti != iv.intValue()) { 263 | System.out.println("e"); 264 | throw new RuntimeException(ti + " " + iv); 265 | } 266 | ti++; 267 | count.incrementAndGet(); 268 | } 269 | if (ti != maxId) { 270 | System.out.println("e"); 271 | throw new RuntimeException(); 272 | } 273 | } 274 | 275 | } 276 | }); 277 | } 278 | pool.shutdown(); 279 | pool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); 280 | watch = System.currentTimeMillis() - watch; 281 | if (count.get() != (batchCount * threadCount)) { 282 | throw new Exception(count + " " + (batchCount * threadCount)); 283 | } 284 | int avg = (int) (count.get() / (watch / 1000.0)); 285 | System.out.println("MongoDB Insert&Counting:" 286 | + Integer.toString(count.get()) + " AVG:" 287 | + Integer.toString(avg) + " objects/s"); 288 | 289 | // ---------------Update----------------------------- 290 | watch = System.currentTimeMillis(); 291 | count.set(0); 292 | pool = CreatePool(); 293 | for (int i = 0; i < threadCount; i++) { 294 | final int p = i; 295 | pool.execute(new Runnable() { 296 | @Override 297 | public void run() { 298 | for (int i = 0; i < batchCount; i++) { 299 | int id = (p * batchCount) + i; 300 | count.incrementAndGet(); 301 | Document q = new Document(); 302 | q.put("_id", id); 303 | coll.findOneAndUpdate(q, new Document()); 304 | } 305 | } 306 | }); 307 | } 308 | pool.shutdown(); 309 | pool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); 310 | watch = System.currentTimeMillis() - watch; 311 | if (count.get() != (batchCount * threadCount)) { 312 | throw new Exception(count + " " + (batchCount * threadCount)); 313 | } 314 | avg = (int) (count.get() / (watch / 1000.0)); 315 | System.out.println("MongoDB findOneAndUpdate:" + Integer.toString(count.get()) 316 | + " AVG:" + Integer.toString(avg) + " objects/s"); 317 | mongo.close(); 318 | } 319 | 320 | private static ExecutorService CreatePool() { 321 | return Executors.newFixedThreadPool(8); 322 | } 323 | 324 | public static class T1 { 325 | 326 | //public int _id; 327 | public static org.bson.Document O(int id, String s) { 328 | Document o = new Document(); 329 | o.append("_id", id); 330 | o.append("s", s); 331 | return o; 332 | } 333 | 334 | public static HashMap M(int id, String s) { 335 | HashMap o = new HashMap(); 336 | o.put("_id", id); 337 | o.put("s", s); 338 | return o; 339 | } 340 | 341 | public static List toArray(Iterable it) { 342 | ArrayList list = new ArrayList<>(); 343 | for (T t : it) { 344 | list.add(t); 345 | } 346 | return list; 347 | } 348 | } 349 | 350 | public static class iBoxDBServer extends LocalDatabaseServer { 351 | 352 | @Override 353 | protected DatabaseConfig BuildDatabaseConfig(long address) { 354 | if (UseMem) { 355 | return new InMemoryConfig(); 356 | } else if (UseMMAP) { 357 | return new MMPConfig(); 358 | } else { 359 | return new FileConfig(); 360 | } 361 | } 362 | 363 | public static class FileConfig extends BoxFileStreamConfig { 364 | 365 | public FileConfig() { 366 | W.ensureTable("T1", T1.M(0, ""), "_id"); 367 | } 368 | } 369 | 370 | public static class InMemoryConfig extends BoxMemoryStreamConfig { 371 | 372 | public InMemoryConfig() { 373 | W.ensureTable("T1", T1.M(0, ""), "_id"); 374 | this.FileIncSize = 1024 * 1024 * 512; 375 | this.CacheLength = 1024 * 1024 * 512; 376 | } 377 | } 378 | 379 | public static class MMPConfig extends MMapConfig { 380 | 381 | public MMPConfig() { 382 | W.ensureTable("T1", T1.M(0, ""), "_id"); 383 | } 384 | } 385 | } 386 | 387 | } 388 | -------------------------------------------------------------------------------- /benchmark/BenchmarkDBTestMySQL.java: -------------------------------------------------------------------------------- 1 | package benchmark; 2 | //this file's new version in https://github.com/iboxdb/teadb 3 | 4 | import java.util.*; 5 | import java.util.concurrent.*; 6 | import java.util.concurrent.atomic.*; 7 | 8 | import iBoxDB.LocalServer.*; 9 | import iBoxDB.LocalServer.IO.*; 10 | 11 | import java.sql.DriverManager; 12 | import java.sql.SQLException; 13 | import java.util.logging.Level; 14 | import java.util.logging.Logger; 15 | 16 | /* 17 | iBoxDB.java v2.15.0 18 | */ 19 | /* 20 | MySQL, mysql-8.0.19-linux-x86_64-minimal , mysql-connector-java-8.0.19.jar 21 | 22 | sudo mv /etc/my.cnf /etc/my.cnf.bak 23 | rm -rf /tmp/mysqldata 24 | 25 | ./mysqld --initialize --datadir=/tmp/mysqldata 26 | ./mysqld --datadir=/tmp/mysqldata 27 | 28 | ./mysql -u root -p 29 | 30 | ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; 31 | create database test; 32 | */ 33 | public class BenchmarkDBTestMySQL { 34 | 35 | static int threadCount = 100_000; 36 | static int batchCount = 10; 37 | static int reinterationSelect = 3; 38 | 39 | public static void main(String[] args) { 40 | try { 41 | 42 | System.out.println(System.getProperty("java.version")); 43 | System.out.format("threadCount= %,d batchCount= %,d reinterationSelect= %,d %n", 44 | threadCount, batchCount, reinterationSelect); 45 | 46 | //never set root = "" or "./" when inside IDE 47 | //the IDE would block writing. 48 | String root = "../"; //"/tmp" 49 | iBoxDB.LocalServer.DB.root(root); 50 | System.out.println("iBoxDB"); 51 | TestiBoxDB(); 52 | System.out.println(); 53 | 54 | System.gc(); 55 | System.runFinalization(); 56 | 57 | System.out.println("MySQL"); 58 | TestMySQL(); 59 | 60 | System.out.println("Test End."); 61 | 62 | } catch (Exception e) { 63 | e.printStackTrace(); 64 | } 65 | } 66 | 67 | public static void TestiBoxDB() { 68 | BoxSystem.DBDebug.DeleteDBFiles(1); 69 | 70 | try (iBoxDBServer server = new iBoxDBServer()) { 71 | final Database db = server.getInstance(); 72 | System.out.print("Database Transaction Test: "); 73 | Box box1 = db.cube(); 74 | box1.d("T1").insert(new T1(-1, Integer.toString(-1))); 75 | 76 | Box box2 = db.cube(); 77 | box2.d("T1").insert(new T1(-2, Integer.toString(-2))); 78 | 79 | List transaction1 = T1 80 | .toArray(box1.select(T1.class, "from T1")); 81 | List transaction2 = T1 82 | .toArray(box2.select(T1.class, "from T1")); 83 | if (transaction1.size() == 1 84 | && transaction1.get(0).getId() == -1 85 | && transaction2.size() == 1 86 | && transaction2.get(0).getId() == -2) { 87 | System.out.println("Succeeded"); 88 | } else { 89 | System.out.println("Failed"); 90 | } 91 | box1.commit(); 92 | box2.commit(); 93 | 94 | long watch = System.currentTimeMillis(); 95 | final AtomicInteger count = new AtomicInteger(0); 96 | ExecutorService pool = CreatePool(); 97 | for (int i = 0; i < threadCount; i++) { 98 | final int p = i; 99 | pool.execute(new Runnable() { 100 | @Override 101 | public void run() { 102 | 103 | try (Box box = db.cube()) { 104 | for (int i = 0; i < batchCount; i++) { 105 | int id = (p * batchCount) + i; 106 | box.d("T1").insert(new T1(id, Integer.toString(id))); 107 | count.incrementAndGet(); 108 | } 109 | var cr = box.commit(); 110 | } 111 | 112 | for (int r = 0; r < reinterationSelect; r++) { 113 | AutoBox auto = db.get(); 114 | int minId = p * batchCount + 0; 115 | int maxId = p * batchCount + batchCount; 116 | var reader = auto 117 | .select(T1.class, "from T1 where Id>=? & Id=? & Id m : box.select("from T1")) { 243 | //System.out.println(m.get("Id")); 244 | } 245 | } 246 | 247 | } catch (Exception e) { 248 | e.printStackTrace(); 249 | } 250 | } 251 | 252 | public static void TestMySQL() { 253 | 254 | var connPool = CreateConnectionPool(); 255 | try { 256 | { 257 | var conn = connPool.take(); 258 | conn.setAutoCommit(true); 259 | var stmt = conn.createStatement(); 260 | try { 261 | stmt.execute("drop table T1"); 262 | } catch (Exception ex) { 263 | //Logger.getLogger(BenchmarkDBTestMySQL.class.getName()).log(Level.INFO, null, ex); 264 | } 265 | stmt.execute("CREATE TABLE T1 ( Id INT NOT NULL PRIMARY KEY, Value VARCHAR(100) )"); 266 | connPool.put(conn); 267 | } 268 | 269 | { 270 | 271 | System.out.print("Database Transaction Test: "); 272 | 273 | var conn1 = connPool.take(); 274 | conn1.setAutoCommit(false); 275 | var stmt1 = conn1.prepareStatement("insert into T1 values (? , ?)"); 276 | stmt1.setInt(1, -1); 277 | stmt1.setString(2, Integer.toString(-1)); 278 | stmt1.execute(); 279 | 280 | var conn2 = connPool.take(); 281 | conn2.setAutoCommit(false); 282 | var stmt2 = conn2.prepareStatement("insert into T1 values (? , ?)"); 283 | stmt2.setInt(1, -2); 284 | stmt2.setString(2, Integer.toString(-2)); 285 | stmt2.execute(); 286 | 287 | stmt1 = conn1.prepareStatement("select * from T1"); 288 | List< T1> transaction1 = T1 289 | .toArray(stmt1.executeQuery()); 290 | 291 | stmt2 = conn2.prepareStatement("select * from T1"); 292 | List transaction2 = T1 293 | .toArray(stmt2.executeQuery()); 294 | if (transaction1.size() == 1 295 | && transaction1.get(0).getId() == -1 296 | && transaction2.size() == 1 297 | && transaction2.get(0).getId() == -2) { 298 | System.out.println("Succeeded"); 299 | } else { 300 | System.out.println("Failed"); 301 | } 302 | 303 | stmt1.close(); 304 | stmt2.close(); 305 | conn1.commit(); 306 | conn2.commit(); 307 | connPool.put(conn1); 308 | connPool.put(conn2); 309 | 310 | } 311 | 312 | long watch = System.currentTimeMillis(); 313 | final AtomicInteger count = new AtomicInteger(0); 314 | ExecutorService pool = CreatePool(); 315 | for (int i = 0; i < threadCount; i++) { 316 | final int p = i; 317 | pool.execute(new Runnable() { 318 | @Override 319 | public void run() { 320 | 321 | try { 322 | var conn = connPool.take(); 323 | conn.setAutoCommit(false); 324 | var stmt = conn.prepareStatement("insert into T1(Id,Value) values( ?, ? )"); 325 | 326 | for (int i = 0; i < batchCount; i++) { 327 | int id = (p * batchCount) + i; 328 | 329 | stmt.setInt(1, id); 330 | stmt.setString(2, Integer.toString(id)); 331 | stmt.addBatch(); 332 | count.incrementAndGet(); 333 | } 334 | stmt.executeBatch(); 335 | stmt.close(); 336 | 337 | conn.commit(); 338 | connPool.put(conn); 339 | 340 | } catch (Exception ex) { 341 | ex.printStackTrace(); 342 | } 343 | 344 | for (int r = 0; r < reinterationSelect; r++) { 345 | try { 346 | var conn = connPool.take(); 347 | conn.setAutoCommit(true); 348 | var stmt = conn.prepareStatement("select Id,Value from T1 where Id>=? and Id=? and Id CreateConnectionPool() { 551 | 552 | //put/take 553 | LinkedBlockingQueue queue = new LinkedBlockingQueue(poolSize * 2); 554 | for (int i = 0; i < poolSize * 2; i++) { 555 | try { 556 | var conn 557 | = DriverManager.getConnection("jdbc:mysql://localhost/test?" 558 | + "user=root&password=123456"); 559 | 560 | queue.put(conn); 561 | } catch (Exception ex) { 562 | Logger.getLogger(BenchmarkDBTestMySQL.class.getName()).log(Level.SEVERE, null, ex); 563 | } 564 | } 565 | return queue; 566 | } 567 | 568 | private static ExecutorService CreatePool() { 569 | return Executors.newFixedThreadPool(poolSize); 570 | } 571 | 572 | public static class T1 { 573 | 574 | public T1() { 575 | } 576 | 577 | public T1(int id, String val) { 578 | setId(id); 579 | setValue(val); 580 | } 581 | 582 | private int _id; 583 | 584 | public final int getId() { 585 | return _id; 586 | } 587 | 588 | public final void setId(int id) { 589 | _id = id; 590 | } 591 | private String _value; 592 | 593 | public final String getValue() { 594 | return _value; 595 | } 596 | 597 | public final void setValue(String val) { 598 | _value = val; 599 | } 600 | 601 | public static List toArray(Iterable it) { 602 | ArrayList list = new ArrayList<>(); 603 | for (T t : it) { 604 | list.add(t); 605 | } 606 | return list; 607 | } 608 | 609 | public static List toArray(java.sql.ResultSet it) throws SQLException { 610 | ArrayList list = new ArrayList<>(); 611 | while (it.next()) { 612 | T1 t1 = new T1(); 613 | t1.setId(it.getInt(1)); 614 | t1.setValue(it.getString(2)); 615 | list.add(t1); 616 | } 617 | return list; 618 | } 619 | } 620 | 621 | public static class iBoxDBServer extends LocalDatabaseServer { 622 | 623 | @Override 624 | protected DatabaseConfig BuildDatabaseConfig(long address) { 625 | return new FileConfig(); 626 | 627 | } 628 | 629 | public static class FileConfig extends BoxFileStreamConfig { 630 | 631 | public FileConfig() { 632 | //this.FileIncSize = (int) mb(4); 633 | //this.CacheLength = mb(512); 634 | //this.ReadStreamCount = 8; 635 | 636 | //getId -> Id 637 | EnsureTable(T1.class, "T1", "Id"); 638 | 639 | } 640 | } 641 | 642 | } 643 | 644 | } 645 | -------------------------------------------------------------------------------- /demos/KeyOnly.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | import iboxdb.localserver.*; 4 | import iboxdb.localserver.replication.*; 5 | import java.io.*; 6 | import java.util.concurrent.*; 7 | import java.util.concurrent.atomic.*; 8 | import java.text.*; 9 | import java.util.*; 10 | 11 | public class KeyOnly { 12 | 13 | public static void main(String[] args) throws InterruptedException { 14 | System.out.println("MEM: " + helper.format(java.lang.Runtime.getRuntime().maxMemory())); 15 | System.out.println("CPU: " + java.lang.Runtime.getRuntime().availableProcessors()); 16 | String path = "../DATA_TEST"; 17 | 18 | new File(path).mkdirs(); 19 | System.out.println("Path: " + new File(path).getAbsolutePath()); 20 | DB.root(path); 21 | helper.deleteDB(); 22 | 23 | DB db = new DB(1); 24 | // JVM=2G, DB=0.5G 25 | DatabaseConfig cfg = db.getConfig(); 26 | cfg.CacheLength = cfg.mb(512); 27 | cfg.ensureTable(ShortMSG.class, "/shortmsg", "productId", "time", "userId", "msg(30)"); 28 | final AutoBox auto = db.open(); 29 | 30 | final long count = 100; 31 | 32 | //Insert 33 | long begin = System.currentTimeMillis(); 34 | 35 | //long total = SingleInsert(auto, count); 36 | long total = BatchInsert(auto, count); 37 | 38 | double sec = (System.currentTimeMillis() - begin) / 1000.0; 39 | long avg = (long) (total / sec); 40 | IBStreamReader reader = auto.getDatabase().createFileReader(); 41 | long length = reader.length(); 42 | System.out.println("Insert TotalObjects: " + helper.format(total) 43 | + " FileSize: " + helper.format(length / 1024.0 / 1024.0) + "MB"); 44 | System.out.println("Elapsed " + helper.getDou(sec) + "s, AVG " 45 | + helper.format(avg) + " o/sec"); 46 | reader.close(); 47 | 48 | System.out.println(); 49 | //Select 50 | begin = System.currentTimeMillis(); 51 | 52 | total = SelectObjects(auto, count); 53 | total += SelectObjects(auto, count); 54 | 55 | sec = (System.currentTimeMillis() - begin) / 1000.0; 56 | avg = (long) (total / sec); 57 | System.out.println("Select TotalObjects: " + helper.format(total)); 58 | System.out.println("Elapsed " + helper.getDou(sec) + "s, AVG " 59 | + helper.format(avg) + " o/sec"); 60 | 61 | //Reopen Select 62 | db.close(); 63 | 64 | System.gc(); 65 | System.out.println(); 66 | 67 | AutoBox auto2 = db.open(); 68 | 69 | begin = System.currentTimeMillis(); 70 | total = SelectObjects(auto2, count); 71 | total += SelectObjects(auto2, count); 72 | 73 | sec = (System.currentTimeMillis() - begin) / 1000.0; 74 | avg = (long) (total / sec); 75 | System.out.println("Select TotalObjects: " + helper.format(total) + " -Reopen"); 76 | System.out.println("Elapsed " + helper.getDou(sec) + "s, AVG " 77 | + helper.format(avg) + " o/sec"); 78 | 79 | System.out.println(); 80 | begin = System.currentTimeMillis(); 81 | total = SelectObjects(auto2, count); 82 | total += SelectObjects(auto2, count); 83 | 84 | sec = (System.currentTimeMillis() - begin) / 1000.0; 85 | avg = (long) (total / sec); 86 | System.out.println("Select TotalObjects: " + helper.format(total) + " -Reopen2"); 87 | System.out.println("Elapsed " + helper.getDou(sec) + "s, AVG " 88 | + helper.format(avg) + " o/sec"); 89 | 90 | } 91 | 92 | private static long SelectObjects(final AutoBox auto, final long count) throws InterruptedException { 93 | ExecutorService pool = Executors.newFixedThreadPool( 94 | java.lang.Runtime.getRuntime().availableProcessors() * 2); 95 | 96 | final AtomicLong total = new AtomicLong(0); 97 | for (long proId = 1; proId <= count; proId++) { 98 | final long fproId = proId; 99 | pool.execute(() -> { 100 | try (Box box = auto.cube()) { 101 | for (ShortMSG smsg : box.select(ShortMSG.class, "from /shortmsg where productId==?", fproId)) { 102 | if (smsg.productId != fproId) { 103 | System.out.println("Unreachable"); 104 | } 105 | String cs = smsg.productId + "-" + (smsg.time.getTime()) + "-" + smsg.userId; 106 | if (!smsg.msg.equals(cs)) { 107 | System.out.println("Unreachable"); 108 | } 109 | total.incrementAndGet(); 110 | } 111 | } 112 | }); 113 | } 114 | pool.shutdown(); 115 | pool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); 116 | return total.get(); 117 | } 118 | 119 | private static long BatchInsert(final AutoBox auto, final long count) throws InterruptedException { 120 | ExecutorService pool = Executors.newFixedThreadPool( 121 | java.lang.Runtime.getRuntime().availableProcessors() * 2); 122 | final long fakeTime = System.currentTimeMillis(); 123 | final AtomicLong total = new AtomicLong(0); 124 | for (long proId = 1; proId <= count; proId++) { 125 | for (long ft = 1; ft <= count; ft++) { 126 | final long fproId = proId; 127 | final long fft = ft; 128 | pool.execute(() -> { 129 | try (Box box = auto.cube()) { 130 | for (long userid = 1; userid <= count; userid++) { 131 | ShortMSG smsg = new ShortMSG(); 132 | smsg.productId = fproId; 133 | smsg.time = new Date(fakeTime + fft); 134 | smsg.userId = userid; 135 | smsg.msg = smsg.productId + "-" + (fakeTime + fft) + "-" + smsg.userId; 136 | box.d("/shortmsg").insert(smsg); 137 | } 138 | if (box.commit().equals(CommitResult.OK)) { 139 | total.addAndGet(count); 140 | } 141 | } 142 | }); 143 | } 144 | } 145 | pool.shutdown(); 146 | pool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); 147 | return total.get(); 148 | } 149 | 150 | private static long SingleInsert(final AutoBox auto, long count) throws InterruptedException { 151 | ExecutorService pool = Executors.newFixedThreadPool( 152 | java.lang.Runtime.getRuntime().availableProcessors() * 2); 153 | final long fakeTime = System.currentTimeMillis(); 154 | final AtomicLong total = new AtomicLong(0); 155 | for (long proId = 1; proId <= count; proId++) { 156 | for (long ft = 1; ft <= count; ft++) { 157 | for (long userid = 1; userid <= count; userid++) { 158 | final long fproId = proId; 159 | final long fft = ft; 160 | final long fuserid = userid; 161 | pool.execute(() -> { 162 | ShortMSG smsg = new ShortMSG(); 163 | smsg.productId = fproId; 164 | smsg.time = new Date(fakeTime + fft); 165 | smsg.userId = fuserid; 166 | smsg.msg = smsg.productId + "-" + (fakeTime + fft) + "-" + smsg.userId; 167 | if (auto.insert("/shortmsg", smsg)) { 168 | total.incrementAndGet(); 169 | } 170 | }); 171 | } 172 | } 173 | } 174 | pool.shutdown(); 175 | pool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); 176 | return total.get(); 177 | } 178 | 179 | public static class ShortMSG { 180 | 181 | public long productId; 182 | public java.util.Date time; 183 | public long userId; 184 | public String msg; 185 | } 186 | 187 | private static class helper { 188 | 189 | public static void deleteDB() { 190 | BoxSystem.DBDebug.DeleteDBFiles(1); 191 | } 192 | 193 | public static String getDou(double d) { 194 | long l = (long) (d * 1000); 195 | return Double.toString(l / 1000.0); 196 | } 197 | 198 | public static String format(double d) { 199 | return NumberFormat.getInstance().format((int) d); 200 | } 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /demos/README.md: -------------------------------------------------------------------------------- 1 | ### DEMOS 2 | 3 | ##### KeyOnly.java Output [KeyOnly.java Link](https://github.com/iboxdb/forjava/blob/master/demos/KeyOnly.java) 4 | 5 | ``` 6 | Insert TotalObjects: 1,000,000 FileSize: 161MB 7 | Elapsed 14.981s, AVG 66,751 o/sec 8 | 9 | Select TotalObjects: 2,000,000 10 | Elapsed 1.312s, AVG 1,524,390 o/sec 11 | 12 | Select TotalObjects: 2,000,000 -Reopen 13 | Elapsed 2.822s, AVG 708,717 o/sec 14 | 15 | Select TotalObjects: 2,000,000 -Reopen2 16 | Elapsed 0.514s, AVG 3,891,050 o/sec 17 | ``` 18 | 19 | 20 | **KeyOnly table doesn't have 'Value', not support update the 'Value', use 'delete() and insert()' to update KeyOnly table** 21 | 22 | ```` 23 | void update(Box box, Object oldKey, object newKey){ 24 | box.d("/N", oldKey).delete(); 25 | box.d("/N").insert(newKey); 26 | } 27 | box.commit(); 28 | ```` 29 | -------------------------------------------------------------------------------- /images/js.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iboxdb/forjava/d9cc1b54d6d6165dfd84a2b7e31338c62d276cae/images/js.gif -------------------------------------------------------------------------------- /images/show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iboxdb/forjava/d9cc1b54d6d6165dfd84a2b7e31338c62d276cae/images/show.png -------------------------------------------------------------------------------- /java9/README.md: -------------------------------------------------------------------------------- 1 | ### Java6+Jar to Java 9 Module Jar 2 | 3 | 4 | #### Update Jar to module 5 | Download [module-info.class(295 bytes)](https://github.com/iboxdb/forjava/blob/master/java9/module-info.class) 6 | ```bush 7 | $ jar --update --file iBoxDBv28.jar --module-version 2.8 module-info.class 8 | ``` 9 | 10 | 11 | #### Build a JRE, set launcher = newmodule/app.NewClass.Main() 12 | ```bush 13 | $jlink --module-path /home/user/jdk-9/jmods:/home/user/Downloads/iBoxDBv21600_27/JavaDB/iBoxDBv27.jar:. --add-modules java.base,iBoxDB,newmodule --launcher run=newmodule/app.NewClass --output ujre 14 | ``` 15 | 16 | #### List the modules 17 | ```bush 18 | $./ujre/bin/java --list-modules 19 | ``` 20 | 21 | 22 | #### Execute the App 23 | ```bush 24 | $./ujre/bin/run 25 | ``` 26 | 27 | 28 | #### the App module 29 | ```java 30 | module-info.java 31 | module newmodule { 32 | requires iBoxDB; 33 | exports app; 34 | } 35 | ``` 36 | 37 | #### Show Java Class 38 | ```sh 39 | $javap module-info.class 40 | ``` 41 | 42 | -------------------------------------------------------------------------------- /java9/module-info.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iboxdb/forjava/d9cc1b54d6d6165dfd84a2b7e31338c62d276cae/java9/module-info.class --------------------------------------------------------------------------------