├── .classpath
├── .gitattributes
├── .gitignore
├── .project
├── .settings
├── org.eclipse.core.resources.prefs
└── org.eclipse.jdt.core.prefs
├── README.md
├── src
└── tenndb
│ ├── IBase.java
│ ├── base
│ ├── Catalog.java
│ ├── Cell.java
│ └── TennBase.java
│ ├── bstar
│ ├── BTreeNode.java
│ ├── IdxBlock.java
│ ├── IdxOld.java
│ ├── InsertVar.java
│ ├── RandomInsertBStarTree.java
│ └── SplitLeafVar.java
│ ├── common
│ ├── ByteUtil.java
│ ├── DateFormatUtil.java
│ ├── FileDeco.java
│ ├── FileMgr.java
│ ├── FileUtil.java
│ ├── GraphFindCycle.java
│ ├── SystemTime.java
│ └── test
│ │ └── TestSystemTime.java
│ ├── data
│ ├── ByteBufferMgr.java
│ ├── Colunm.java
│ ├── DBBlock.java
│ ├── DBPage.java
│ ├── DBPageMgr.java
│ ├── Filed.java
│ ├── PageBuffer.java
│ ├── PageBufferMgr.java
│ └── PageUnusedIndex.java
│ ├── dist
│ ├── DistMgr.java
│ └── DistPage.java
│ ├── disttest
│ ├── DemoThread.java
│ ├── Test.java
│ ├── TestDist.java
│ ├── TestFileName.java
│ └── TestRoute.java
│ ├── index
│ ├── IBTree.java
│ ├── IndexMgr.java
│ └── IndexPage.java
│ ├── log
│ ├── CellLogMgr.java
│ ├── LogMgr.java
│ └── LogRecord.java
│ ├── route
│ └── RouteMgr.java
│ ├── routetest
│ └── TestRoute.java
│ ├── test
│ ├── TestAbortTransException.java
│ ├── TestByte.java
│ ├── TestCell.java
│ ├── TestDBPageMgr.java
│ ├── TestFileMgr.java
│ ├── TestIndexMgr.java
│ ├── TestLogMgr.java
│ ├── TestRun.java
│ └── TestTennBase.java
│ ├── thread
│ ├── DistThread.java
│ ├── FlushHook.java
│ ├── ImportThread.java
│ └── ShutdownHook.java
│ ├── threadtest
│ ├── InsertThread.java
│ └── TestTennBase.java
│ ├── tx
│ ├── AbortTransException.java
│ ├── BlkID.java
│ ├── Trans.java
│ └── TransMgr.java
│ └── txtest
│ └── TestInsertTx.java
└── 简易数据库存储系统的JAVA实现.ppt
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 | entries
5 | format
6 | wc.db
7 | wc.db-journal
8 |
9 | # Folder config file
10 | Desktop.ini
11 |
12 | # Recycle Bin used on file shares
13 | $RECYCLE.BIN/
14 |
15 | # Windows Installer files
16 | *.cab
17 | *.msi
18 | *.msm
19 | *.msp
20 | *.svn-base
21 | *.class
22 |
23 | # Windows shortcuts
24 | *.lnk
25 |
26 | # =========================
27 | # Operating System Files
28 | # =========================
29 |
30 | # OSX
31 | # =========================
32 |
33 | .DS_Store
34 | .AppleDouble
35 | .LSOverride
36 |
37 | # Thumbnails
38 | ._*
39 |
40 | # Files that might appear in the root of a volume
41 | .DocumentRevisions-V100
42 | .fseventsd
43 | .Spotlight-V100
44 | .TemporaryItems
45 | .Trashes
46 | .VolumeIcon.icns
47 |
48 | # Directories potentially created on remote AFP share
49 | .AppleDB
50 | .AppleDesktop
51 | Network Trash Folder
52 | Temporary Items
53 | .apdisk
54 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | TennBase5
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | #Fri Jul 08 08:44:06 CST 2016
2 | eclipse.preferences.version=1
3 | encoding/=UTF-8
4 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #Fri Jun 24 14:47:25 CST 2016
2 | eclipse.preferences.version=1
3 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.compliance=1.6
7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
12 | org.eclipse.jdt.core.compiler.source=1.6
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TennBase
2 | a lightweight datastore based on B*tree implements some basic function of hbase.
3 |
4 | thread-safe, simple transaction, reach by b-start tree, append new data to data file in order to insert and update quickly.
5 |
6 | consist of three parts, b-start tree index, data file and logs.
7 |
--------------------------------------------------------------------------------
/src/tenndb/IBase.java:
--------------------------------------------------------------------------------
1 | package tenndb;
2 |
3 | import java.util.List;
4 |
5 | import tenndb.data.Colunm;
6 | import tenndb.tx.AbortTransException;
7 | import tenndb.tx.Trans;
8 |
9 | public interface IBase {
10 |
11 | public boolean insert(int key, byte[] buff, int offset, int len);
12 |
13 | public boolean update(int key, byte[] buff, int offset, int len);
14 |
15 |
16 | public boolean insert(int key, Colunm colunm);
17 |
18 | public boolean update(int key, Colunm colunm);
19 |
20 | public boolean delete(int key);
21 |
22 | public Colunm search(int key);
23 |
24 |
25 | public boolean insert(int key, Colunm colunm, Trans tid) throws AbortTransException;
26 |
27 | public boolean update(int key, Colunm colunm, Trans tid) throws AbortTransException;
28 |
29 | public boolean delete(int key, Trans tid) throws AbortTransException;
30 |
31 | public boolean rollback(int key, Trans tid);
32 |
33 | public boolean commit(int key, Trans tid);
34 |
35 | public Colunm search(int key, Trans tid);
36 |
37 | public int count(int fromKey, int toKey);
38 |
39 | public List range(int fromKey, int toKey, boolean isInc);
40 |
41 | public void printTreeNext();
42 |
43 | public void printTreePrior();
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/tenndb/base/Catalog.java:
--------------------------------------------------------------------------------
1 | package tenndb.base;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Hashtable;
5 | import java.util.Map;
6 | import java.util.Set;
7 | import java.util.concurrent.locks.ReadWriteLock;
8 | import java.util.concurrent.locks.ReentrantReadWriteLock;
9 |
10 | import tenndb.common.FileMgr;
11 | import tenndb.data.ByteBufferMgr;
12 | import tenndb.data.DBPage;
13 | import tenndb.log.LogMgr;
14 | import tenndb.tx.BlkID;
15 | import tenndb.tx.Trans;
16 | import tenndb.tx.TransMgr;
17 |
18 | public class Catalog {
19 |
20 | protected final String cataName;
21 | protected final String root;
22 |
23 | protected final FileMgr fileMgr;
24 | protected final LogMgr logMgr;
25 | protected final TransMgr transMgr;
26 |
27 | protected final ByteBufferMgr bufMgr;
28 | protected Map tabNameToCells = null;
29 | protected Map tabIdToCells = null;
30 |
31 | protected final ReadWriteLock lock = new ReentrantReadWriteLock(false);
32 |
33 | public Catalog(String root){
34 | this.cataName = "tennbase";
35 | this.root = root;
36 | this.fileMgr = new FileMgr(this.root);
37 |
38 | this.logMgr = new LogMgr(this.cataName, this.root);
39 | this.bufMgr = new ByteBufferMgr(DBPage.PAGE_SIZE);
40 | this.tabNameToCells = new Hashtable();
41 | this.tabIdToCells = new Hashtable();
42 | this.transMgr = new TransMgr();
43 | }
44 |
45 | public Trans beginTrans(){
46 | Trans trans = new Trans();
47 |
48 | this.logMgr.logBegin(trans);
49 | this.transMgr.setTransState(trans, Trans.ACTIVE);
50 |
51 | return trans;
52 | }
53 |
54 | public void recover(){
55 | this.logMgr.recover(this);
56 | }
57 |
58 | public void flush(){
59 |
60 | try{
61 | this.lockRead();
62 | Set set = this.tabNameToCells.keySet();
63 | for(String dbName : set){
64 | Cell cell = this.tabNameToCells.get(dbName);
65 | cell.flush();
66 | }
67 | }catch(Exception e){}
68 | finally{
69 | this.unLockRead();
70 | }
71 | }
72 |
73 | public boolean rollback(Trans tid){
74 | boolean b = false;
75 |
76 | if(null != tid && tid.getTransID() > 0 && null != this.transMgr){
77 | try{
78 | this.logMgr.logRollback(tid);
79 | this.lockRead();
80 | ArrayList blks = this.transMgr.getTransBlks(tid);
81 | if(null != blks && blks.size() > 0){
82 |
83 | for(int i = blks.size() - 1; i >= 0; --i){
84 | BlkID blk = blks.get(i);
85 | Cell cell = this.tabNameToCells.get(blk.getDbName());
86 | if(null != cell){
87 | cell.rollback(blk.getKey(), tid);
88 | }
89 | }
90 | }
91 | this.transMgr.delTransBlks(tid);
92 | b = true;
93 | }catch(Exception e){}
94 | finally{
95 | this.unLockRead();
96 | }
97 | this.logMgr.logTerminated(tid);
98 | }
99 |
100 | return b;
101 | }
102 |
103 | public byte state(Trans tid){
104 | return this.transMgr.getTransState(tid);
105 | }
106 |
107 | public boolean commit(Trans tid){
108 | boolean b = false;
109 |
110 | if(null != tid && tid.getTransID() > 0 && null != this.transMgr){
111 |
112 | if(tid.getState() == Trans.ACTIVE){
113 | try{
114 | this.logMgr.logCommit(tid);
115 |
116 | this.lockRead();
117 | ArrayList blks = this.transMgr.getTransBlks(tid);
118 | if(null != blks && blks.size() > 0){
119 |
120 | for(int i = blks.size() - 1; i >= 0; --i){
121 | BlkID blk = blks.get(i);
122 | Cell cell = this.tabNameToCells.get(blk.getDbName());
123 | if(null != cell){
124 | cell.commit(blk.getKey(), tid);
125 | }
126 | }
127 | }
128 | this.transMgr.delTransBlks(tid);
129 | b = true;
130 | }catch(Exception e){}
131 | finally{
132 | this.unLockRead();
133 | }
134 | this.logMgr.logTerminated(tid);
135 | }
136 | }
137 |
138 | return b;
139 | }
140 |
141 | public boolean addCell(String dbName, int dbID){
142 | boolean b = false;
143 | if(!tabNameToCells.containsKey(dbName)){
144 | Cell cell = new Cell(dbName, dbID, this.fileMgr, this.transMgr, this.logMgr);
145 | cell.init();
146 | // System.out.println("addCell " + dbName);
147 |
148 | try{
149 | this.lockWrite();
150 | this.tabNameToCells.put(dbName, cell);
151 | this.tabIdToCells.put(dbID, cell);
152 | b = true;
153 | }catch(Exception e){}
154 | finally{
155 | this.unLockWrite();
156 | }
157 | }
158 | return b;
159 | }
160 |
161 | public final Cell getCell(int dbID){
162 | return this.tabIdToCells.get(dbID);
163 | }
164 |
165 | public final Cell getCell(String dbName){
166 | return this.tabNameToCells.get(dbName);
167 | }
168 |
169 | protected void lockRead() { this.lock.readLock().lock(); }
170 |
171 | protected void unLockRead() { this.lock.readLock().unlock(); }
172 |
173 | protected void lockWrite() { this.lock.writeLock().lock(); }
174 |
175 | protected void unLockWrite() { this.lock.writeLock().unlock(); }
176 | }
177 |
--------------------------------------------------------------------------------
/src/tenndb/base/Cell.java:
--------------------------------------------------------------------------------
1 | package tenndb.base;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.concurrent.locks.ReadWriteLock;
6 | import java.util.concurrent.locks.ReentrantReadWriteLock;
7 |
8 | import tenndb.IBase;
9 | import tenndb.bstar.IdxBlock;
10 | import tenndb.common.FileMgr;
11 | import tenndb.data.DBBlock;
12 | import tenndb.data.DBPageMgr;
13 | import tenndb.data.Colunm;
14 | import tenndb.index.IBTree;
15 | import tenndb.index.IndexMgr;
16 | import tenndb.log.CellLogMgr;
17 | import tenndb.log.LogMgr;
18 | import tenndb.thread.FlushHook;
19 | import tenndb.tx.AbortTransException;
20 | import tenndb.tx.Trans;
21 | import tenndb.tx.TransMgr;
22 |
23 |
24 | public class Cell implements IBase{
25 |
26 | protected IBTree index = null;
27 |
28 | protected final IndexMgr indexMgr;
29 | protected final DBPageMgr pageMgr;
30 |
31 | protected final FileMgr fileMgr;
32 | protected final TransMgr transMgr;
33 | protected final CellLogMgr logMgr;
34 |
35 | protected final String dbName;
36 | protected final int tabID;
37 |
38 | protected FlushHook flushHook = null;
39 |
40 |
41 |
42 | protected final ReadWriteLock lock = new ReentrantReadWriteLock(false);
43 |
44 | protected volatile boolean initialized = false;
45 |
46 |
47 | public Cell(String dbName, int tabID, FileMgr fileMgr, TransMgr transMgr, LogMgr logMgr) {
48 | super();
49 | this.dbName = dbName;
50 | this.tabID = tabID;
51 | this.fileMgr = fileMgr;
52 | this.transMgr = transMgr;
53 | this.logMgr = new CellLogMgr(this.tabID, logMgr);
54 | this.pageMgr = new DBPageMgr(this.dbName, fileMgr);
55 | this.indexMgr = new IndexMgr(this.dbName, fileMgr, transMgr);
56 | }
57 |
58 | public String getDbName() {
59 | return dbName;
60 | }
61 |
62 | public final IBTree getIndex() {
63 | return index;
64 | }
65 |
66 | public void init(){
67 | if(false == this.initialized){
68 | try{
69 | this.lockWrite();
70 | if(false == this.initialized){
71 | this.indexMgr.load();
72 | this.pageMgr.load();
73 | this.index = this.indexMgr.getBTree();
74 |
75 | this.flushHook = new FlushHook(this);
76 | this.flushHook.start();
77 |
78 | this.initialized = true;
79 | }
80 | }catch(Exception e){
81 | System.out.println(e);
82 | }finally{
83 | this.unLockWrite();
84 | }
85 | }
86 | }
87 |
88 | public boolean flushNewPages(){
89 | return this.indexMgr.flushNewPages();
90 | }
91 |
92 | public void flush(){
93 | this.indexMgr.flush();
94 | this.pageMgr.flush();
95 | }
96 |
97 | public void print(){
98 | List strList = new ArrayList();
99 | this.index.print(strList);
100 | if(null != strList){
101 | for(String str : strList){
102 | System.out.println(str);
103 | }
104 | }
105 | }
106 |
107 | @Override
108 | public void printTreePrior(){
109 | this.index.printTreePrior();
110 | }
111 |
112 | @Override
113 | public void printTreeNext(){
114 | this.index.printNext();
115 | }
116 |
117 | @Override
118 | public boolean insert(int key, byte[] buff, int offset, int len){
119 | boolean b = false;
120 | if(null != buff && buff.length > 0 && offset >= 0 && len > 0 && (offset + len) <= buff.length){
121 |
122 | DBBlock bblk = this.pageMgr.nextDBBlock(key, 1, buff, offset, len);
123 |
124 | if(null != bblk){
125 |
126 | IdxBlock newblk = new IdxBlock(key);
127 | newblk.setPageID(bblk.getPageID());
128 | newblk.setOffset(bblk.getOffset());
129 | newblk.setTag(IdxBlock.VALID);
130 |
131 | try {
132 | this.index.insert(key, newblk, null, this.logMgr);
133 | } catch (AbortTransException e) {
134 | e.printStackTrace();
135 | }
136 |
137 | b = true;
138 | }
139 | }
140 | return b;
141 | }
142 |
143 | @Override
144 | public boolean update(int key, byte[] buff, int offset, int size){
145 | boolean b = false;
146 | IdxBlock oldblk = null;
147 |
148 | if(null != buff){
149 |
150 | DBBlock bblk = this.pageMgr.nextDBBlock(key, 0, buff, offset, size);
151 |
152 | if(null != bblk){
153 |
154 | IdxBlock newblk = new IdxBlock(key);
155 | newblk.setPageID(bblk.getPageID());
156 | newblk.setOffset(bblk.getOffset());
157 |
158 | try {
159 | oldblk = this.index.update(key, newblk, null, this.logMgr);
160 | } catch (AbortTransException e) {
161 | e.printStackTrace();
162 | }
163 |
164 | if(null != oldblk){
165 | b = true;
166 | }
167 | }
168 | }
169 |
170 | return b;
171 | }
172 |
173 | @Override
174 | public boolean insert(int key, Colunm colunm){
175 | boolean b = false;
176 |
177 | try {
178 | b = this.insert(key, colunm, null);
179 | } catch (AbortTransException e) {
180 | System.out.println(e);
181 | }
182 |
183 | return b;
184 | }
185 |
186 | @Override
187 | public boolean update(int key, Colunm colunm) {
188 | boolean b = false;
189 |
190 | try {
191 | b = this.update(key, colunm, null);
192 | } catch (AbortTransException e) {
193 | System.out.println(e);
194 | }
195 |
196 | return b;
197 | }
198 |
199 | @Override
200 | public boolean delete(int key){
201 | boolean b = false;
202 | try {
203 | b = this.delete(key, null);
204 | } catch (AbortTransException e) {
205 | System.out.println(e);
206 | }
207 | return b;
208 | }
209 |
210 | @Override
211 | public Colunm search(int key){
212 | return this.search(key, null);
213 | }
214 |
215 | @Override
216 | public boolean rollback(int key, Trans tid){
217 |
218 | return this.index.rollback(key, tid, logMgr);
219 | }
220 |
221 | @Override
222 | public boolean commit(int key, Trans tid){
223 |
224 | return this.index.commit(key, tid, logMgr);
225 | }
226 |
227 | public boolean recoverDelete(int key){
228 | boolean b = false;
229 | IdxBlock blk = this.index.search(key, null);
230 | if(null != blk){
231 | blk.setTag(IdxBlock.INVALID);
232 | b = this.indexMgr.flushBlock(blk);
233 | }
234 | return b;
235 | }
236 |
237 | public boolean recoverInsert(int key, int pageID, int offset){
238 | boolean b = false;
239 | IdxBlock blk = this.index.search(key, null);
240 | if(null != blk){
241 | blk.setPageID(pageID);
242 | blk.setOffset(offset);
243 | b = this.indexMgr.flushBlock(blk);
244 | }
245 | return b;
246 | }
247 |
248 | public boolean recoverUpdate(int key, int pageID, int offset){
249 | boolean b = false;
250 | IdxBlock blk = this.index.search(key, null);
251 | if(null != blk){
252 | blk.setPageID(pageID);
253 | blk.setOffset(offset);
254 | b = this.indexMgr.flushBlock(blk);
255 | }
256 | return b;
257 | }
258 |
259 | @Override
260 | public boolean insert(int key, Colunm colunm, Trans tid) throws AbortTransException{
261 | boolean b = false;
262 | if(null != colunm){
263 |
264 | DBBlock bblk = this.pageMgr.nextDBBlock(colunm);
265 |
266 | if(null != bblk){
267 |
268 | IdxBlock newblk = new IdxBlock(key);
269 | newblk.setPageID(bblk.getPageID());
270 | newblk.setOffset(bblk.getOffset());
271 | newblk.setTag(IdxBlock.VALID);
272 |
273 | this.index.insert(key, newblk, tid, this.logMgr);
274 |
275 | b = true;
276 | }
277 | }
278 | return b;
279 | }
280 |
281 |
282 | @Override
283 | public boolean update(int key, Colunm colunm, Trans tid) throws AbortTransException{
284 | boolean b = false;
285 | IdxBlock oldblk = null;
286 |
287 | if(null != colunm){
288 |
289 | DBBlock bblk = this.pageMgr.nextDBBlock(colunm);
290 |
291 | if(null != bblk){
292 |
293 | IdxBlock newblk = new IdxBlock(key);
294 | newblk.setPageID(bblk.getPageID());
295 | newblk.setOffset(bblk.getOffset());
296 |
297 | oldblk = this.index.update(key, newblk, tid, this.logMgr);
298 |
299 | if(null != oldblk){
300 | b = true;
301 | }
302 | }
303 | }
304 |
305 | return b;
306 | }
307 |
308 | @Override
309 | public boolean delete(int key, Trans tid) throws AbortTransException{
310 | boolean b = false;
311 | IdxBlock oldblk = null;
312 |
313 | oldblk = this.index.delete(key, tid, this.logMgr);
314 |
315 | if(null != oldblk){
316 | b = true;
317 | }
318 |
319 | return b;
320 | }
321 |
322 | public IdxBlock getIdxBlock(int key){
323 | return this.index.search(key, null);
324 | }
325 |
326 | @Override
327 | public Colunm search(int key, Trans tid){
328 | Colunm colunm = null;
329 |
330 | IdxBlock iblk = this.index.search(key, tid);
331 | if(null != iblk){
332 |
333 | DBBlock bblk = this.pageMgr.getDBBlock(iblk.getPageID(), iblk.getOffset());
334 | if(null != bblk){
335 | colunm = bblk.getColunm();
336 | colunm.setTime(iblk.getTime());
337 | }
338 | }
339 | return colunm;
340 | }
341 |
342 | @Override
343 | public int count(int fromKey, int toKey){
344 |
345 | return this.index.count(fromKey, toKey);
346 | }
347 |
348 | @Override
349 | public List range(int fromKey, int toKey, boolean isInc){
350 |
351 | List bbList = new ArrayList();
352 |
353 | List idxBList = this.index.range(fromKey, toKey, isInc);
354 |
355 | if(null != idxBList && idxBList.size() > 0){
356 |
357 | DBBlock temp = null;
358 | for(int i = 0; i < idxBList.size(); ++i){
359 | IdxBlock blk = idxBList.get(i);
360 | temp = this.pageMgr.getDBBlock(blk.getPageID(), blk.getOffset());
361 | if(null != temp){
362 | bbList.add(temp.getColunm());
363 | }
364 | }
365 | }
366 |
367 | return bbList;
368 | }
369 |
370 |
371 | protected void lockRead() { this.lock.readLock().lock(); }
372 |
373 | protected void unLockRead() { this.lock.readLock().unlock(); }
374 |
375 | protected void lockWrite() { this.lock.writeLock().lock(); }
376 |
377 | protected void unLockWrite() { this.lock.writeLock().unlock(); }
378 | }
379 |
--------------------------------------------------------------------------------
/src/tenndb/base/TennBase.java:
--------------------------------------------------------------------------------
1 | package tenndb.base;
2 |
3 | import java.util.concurrent.atomic.AtomicReference;
4 |
5 | import tenndb.thread.ShutdownHook;
6 |
7 | public class TennBase {
8 |
9 | private static AtomicReference _instance = new AtomicReference(new TennBase());
10 |
11 | protected final Catalog catalog;
12 | protected final ShutdownHook shutdown;
13 |
14 | private TennBase(){
15 | String root = "J:\\tennbase";
16 | this.catalog = new Catalog(root);
17 | this.catalog.recover();
18 | this.shutdown = new ShutdownHook(this.catalog);
19 | Runtime.getRuntime().addShutdownHook(this.shutdown);
20 | }
21 |
22 | public static Catalog getCatalog(){
23 | return _instance.get().catalog;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/tenndb/bstar/BTreeNode.java:
--------------------------------------------------------------------------------
1 | package tenndb.bstar;
2 |
3 | import java.nio.ByteBuffer;
4 | import java.util.List;
5 | import java.util.concurrent.locks.ReadWriteLock;
6 | import java.util.concurrent.locks.ReentrantReadWriteLock;
7 |
8 | import tenndb.common.ByteUtil;
9 | import tenndb.common.SystemTime;
10 | import tenndb.data.ByteBufferMgr;
11 | import tenndb.index.IndexPage;
12 | import tenndb.log.CellLogMgr;
13 | import tenndb.tx.AbortTransException;
14 | import tenndb.tx.BlkID;
15 | import tenndb.tx.Trans;
16 | import tenndb.tx.TransMgr;
17 |
18 |
19 |
20 | public class BTreeNode {
21 |
22 | protected final static int NODE_BRANCH = 0;
23 | protected final static int NODE_LEAF = 1;
24 | protected final static int NODE_ROOT = 2;
25 | protected final static int MAX_SIZE = RandomInsertBStarTree.BALANCE_SIZE;
26 | protected int[] keys;
27 | protected BTreeNode[] children;
28 | protected IdxBlock[] values;
29 |
30 | protected int numKeys = 0;
31 |
32 | protected BTreeNode parent = null;
33 | protected BTreeNode next = null;
34 | protected BTreeNode prior = null;
35 |
36 | protected String dbName = null;
37 |
38 | protected boolean isLeaf = false;
39 |
40 | //index page file
41 | // protected int nodeID = -1;
42 |
43 | protected int pageID = -1;
44 | protected int parentID = -1;
45 | protected int priorID = -1;
46 | protected int nextID = -1;
47 |
48 | public int size() { return this.numKeys; }
49 |
50 | public boolean leaf() { return this.isLeaf; }
51 |
52 | public IdxBlock getBlock(int index) {
53 | IdxBlock blk = null;
54 |
55 | if(index < this.numKeys){
56 | blk = this.values[index];
57 | }
58 |
59 | return blk;
60 | }
61 |
62 | public static ByteBufferMgr buffMgr = new ByteBufferMgr(IndexPage.PAGE_SIZE);
63 |
64 | protected IndexPage refPage = null;
65 |
66 | protected ReadWriteLock lock = new ReentrantReadWriteLock(false);
67 |
68 | protected void lockRead() { this.lock.readLock().lock(); }
69 |
70 | protected void unLockRead() { this.lock.readLock().unlock(); }
71 |
72 | protected void lockWrite() { this.lock.writeLock().lock(); }
73 |
74 | protected void unLockWrite() { this.lock.writeLock().unlock(); }
75 |
76 | public IndexPage getRefPage() {
77 | return refPage;
78 | }
79 |
80 | public void setRefPage(IndexPage refPage) {
81 | this.refPage = refPage;
82 | }
83 |
84 | public void setPageID(int pageID){
85 | this.pageID = pageID;
86 | }
87 |
88 | public int getPageID(){
89 | return this.pageID;
90 | }
91 |
92 | public BTreeNode(String dbName, boolean isLeaf, int num, int[] keys, IdxBlock[] values, BTreeNode[] children, BTreeNode parent, BTreeNode next, BTreeNode prior){
93 | this.dbName = dbName;
94 | this.isLeaf = isLeaf;
95 | this.numKeys = num;
96 | // System.out.println("num = " + num);
97 | this.keys = new int[MAX_SIZE + 1];
98 |
99 | for(int i = 0; i < numKeys; ++i){
100 | this.keys[i] = keys[i];
101 | }
102 |
103 | if(this.isLeaf){
104 | this.values = new IdxBlock[MAX_SIZE + 2];
105 |
106 | for(int i = 0; i < num + 2; ++i){
107 | if(i < values.length)
108 | this.values[i] = values[i];
109 | else
110 | this.values[i] = null;
111 | }
112 | }else{
113 |
114 | this.children = new BTreeNode[MAX_SIZE + 2];
115 | if(null != children){
116 |
117 | for(int i = 0; i < num + 2; ++i){
118 | if(i < children.length)
119 | this.children[i] = children[i];
120 | else
121 | this.children[i] = null;
122 | }
123 | }
124 | }
125 |
126 | this.parent = parent;
127 | this.next = next;
128 | this.prior = prior;
129 | }
130 |
131 | public void toByteBuffer(ByteBuffer buffer, BTreeNode rootNode){
132 | buffer.rewind();
133 |
134 | byte type = (byte)(true == this.isLeaf ? NODE_LEAF : NODE_BRANCH);
135 |
136 | if(this == rootNode){
137 | type = NODE_ROOT;
138 | }
139 |
140 | buffer.put(type);
141 |
142 | buffer.putInt(this.getPageID());
143 | if(null != this.parent)
144 | buffer.putInt(this.parent.getPageID());
145 | else
146 | buffer.putInt(0);
147 |
148 | if(null != this.prior)
149 | buffer.putInt(this.prior.getPageID());
150 | else
151 | buffer.putInt(0);
152 |
153 | if(null != this.next)
154 | buffer.putInt(this.next.getPageID());
155 | else
156 | buffer.putInt(0);
157 |
158 | buffer.putInt(this.numKeys);
159 |
160 | if(this.isLeaf){
161 |
162 | for(int i = 0; i < this.numKeys ; ++i){
163 | buffer.putInt(this.keys[i]);
164 | buffer.putInt(this.values[i].pageID);
165 | buffer.putInt(this.values[i].offset);
166 | buffer.putInt(this.values[i].time);
167 | buffer.put(this.values[i].tag);
168 | }
169 |
170 | for(int i = this.numKeys ; i < MAX_SIZE + 2; ++i){
171 | buffer.putInt(0);
172 | buffer.putInt(0);
173 | buffer.putInt(0);
174 | buffer.putInt(0);
175 | buffer.put(IdxBlock.INVALID);
176 | }
177 |
178 | }else{
179 |
180 | for(int i = 0; i < this.numKeys + 1; ++i){
181 | if(i < this.numKeys + 1)
182 | buffer.putInt(this.keys[i]);
183 | else
184 | buffer.putInt(0);
185 | buffer.putInt(this.children[i].getPageID());
186 | buffer.putInt(0);
187 | buffer.putInt(0);
188 | buffer.put(IdxBlock.VALID);
189 | }
190 |
191 | for(int i = this.numKeys + 1; i < MAX_SIZE + 2; ++i){
192 | buffer.putInt(0);
193 | buffer.putInt(0);
194 | buffer.putInt(0);
195 | buffer.put(IdxBlock.INVALID);
196 | }
197 |
198 | }
199 | }
200 |
201 | ////type + pageid + parentid + priorid + nextid + size + (key + offset) * BALANCE_SIZE
202 | public void toByteBuffer(List list, BTreeNode rootNode){
203 |
204 | // ByteBuffer buffer = ByteBuffer.allocate(IndexPage.PAGE_SIZE);
205 | ByteBuffer buffer = buffMgr.pinBuffer();
206 | buffer.rewind();
207 |
208 | this.lockRead();
209 |
210 | this.toByteBuffer(buffer, rootNode);
211 |
212 | list.add(buffer);
213 |
214 | if(false == this.isLeaf){
215 |
216 | if(null != this.children[0]){
217 | this.children[0].toByteBuffer(list, rootNode);
218 | }
219 |
220 | for(int i = 0; i < this.numKeys ; ++i){
221 | this.children[i+1].toByteBuffer(list, rootNode);
222 | }
223 | }
224 |
225 | this.unLockRead();
226 | }
227 |
228 |
229 | public void toString(List list){
230 |
231 | // this.lockRead();
232 |
233 | if(!this.isLeaf){
234 | if(null != children[0]){
235 | children[0].toString(list);
236 | for( int i = 0; i < numKeys; ++i ){
237 | children[i+1].toString(list);
238 | }
239 | }
240 | }else{
241 | String output = "[L";
242 | for( int i = 0; i < numKeys; ++i ){
243 | long key = keys[i];
244 | if(key < 0){
245 | key += ByteUtil.INT_MAX_VALUE;
246 | }
247 | output += " " + key + ":" + values[i].pageID + ":" + values[i].offset + ", ";
248 | }
249 |
250 | if(null != next){
251 | long key = next.keys[0];
252 | if(key < 0){
253 | key += ByteUtil.INT_MAX_VALUE;
254 | }
255 | output += "next = "+ key +": ";
256 | }
257 | output += "]";
258 | list.add(output);
259 | }
260 |
261 | // this.unLockRead();
262 | }
263 |
264 |
265 | public String toString(){
266 | String output = "[L";
267 |
268 | // this.lockRead();
269 |
270 | if(!this.isLeaf){
271 | if(null != children[0]){
272 | output += "["+children[0].toString()+"], ";
273 | for( int i = 0; i < numKeys; ++i ){
274 | output += keys[i] + ":" + children[i+1].toString();
275 | if( i < numKeys - 1 ) output += ", ";
276 | }
277 | }
278 | }else{
279 |
280 | for( int i = 0; i < numKeys; ++i ){
281 | output += " " + keys[i] + ":" + values[i].pageID + ":" + values[i].offset + ", ";
282 | }
283 |
284 | if(null != next)
285 | output += "next = "+ next.keys[0] +": ";
286 | }
287 |
288 | // this.unLockRead();
289 |
290 | return output + "]";
291 | }
292 |
293 | public BTreeNode(String dbName, BTreeNode left, BTreeNode right, int key){
294 | this.dbName = dbName;
295 | this.keys = new int[MAX_SIZE + 1];
296 | this.keys[0] = key;
297 | this.numKeys = 1;
298 |
299 | this.children = new BTreeNode[MAX_SIZE + 2];
300 | this.children[0] = left;
301 | this.children[1] = right;
302 |
303 | this.isLeaf = false;
304 | }
305 |
306 | public BTreeNode(String dbName, int key, IdxBlock obj, TransMgr transMgr, Trans tid){
307 | this.dbName = dbName;
308 | this.keys = new int[MAX_SIZE + 1];
309 | this.keys[0] = key;
310 | this.numKeys = 1;
311 |
312 | this.values = new IdxBlock[MAX_SIZE + 2];
313 | this.values[0] = obj;
314 | this.values[0].time = SystemTime.getSystemTime().currentTime();
315 | this.isLeaf = true;
316 |
317 | if(null != transMgr && null != tid && tid.getTransID() > 0){
318 |
319 | if(transMgr.lockBlk(new BlkID(this.dbName, key), tid)){
320 | // System.out.println("addValue.0 " + key);
321 | this.values[0].drity = true;
322 | this.values[0].tid = tid.getTransID();
323 | this.values[0].tag = IdxBlock.INVALID;
324 |
325 | transMgr.setTransState(tid, Trans.ACTIVE);
326 | }else{
327 | transMgr.setTransState(tid, Trans.ROLLBACK);
328 | }
329 | }
330 | }
331 |
332 | public boolean isLeaf() {
333 | return isLeaf;
334 | }
335 |
336 | public void setLeaf(boolean isLeaf) {
337 | this.isLeaf = isLeaf;
338 | }
339 |
340 | public int getMiddle(){
341 | return this.keys[keys.length/2];
342 | }
343 |
344 | public int lowerBound(){
345 | return this.keys[0];
346 | }
347 |
348 | public int upperBound(){
349 | return this.keys[this.numKeys - 1];
350 | }
351 |
352 | public BTreeNode splitBranch(int key, BTreeNode node){
353 | BTreeNode newNode = null;
354 |
355 | try{
356 | this.lockWrite();
357 | if(!this.isLeaf){
358 |
359 | if(this.numKeys == MAX_SIZE){
360 |
361 | int i = 0;
362 | for(; i < MAX_SIZE;){
363 | if(key >= this.keys[i])
364 | ++i;
365 | else
366 | break;
367 | }
368 |
369 | if(this.keys[i] != key){
370 | for(int t = MAX_SIZE; t > i; --t){
371 | this.keys[t] = this.keys[t-1];
372 | this.children[t + 1] = this.children[t];
373 | }
374 |
375 | this.keys[i] = key;
376 | this.children[i + 1] = node;
377 |
378 | int[] newKeys = new int[MAX_SIZE + 1];
379 | BTreeNode[] newChildren = new BTreeNode[MAX_SIZE + 2];
380 |
381 | {
382 | {
383 | int from = (MAX_SIZE + 1)/2 + 1;
384 | int to = MAX_SIZE + 1;
385 | int newLength = to - from;
386 |
387 | for(int t = 0; t < newLength; ++t){
388 | if( t + from < to ) {
389 | newKeys[t] = this.keys[from+t];
390 | }
391 | else{
392 | newKeys[t] = -1;
393 | }
394 | }
395 | }
396 |
397 | {
398 | int from = (MAX_SIZE + 2 + 1)/2;
399 | int to = MAX_SIZE + 2;
400 | int newLength = to - from;
401 |
402 | for(int t = 0; t < newLength; ++t){
403 | if( t + from < to ) {
404 | newChildren[t] = this.children[from+t];
405 | }else{
406 | newChildren[t] = null;
407 | }
408 | }
409 | }
410 |
411 | int newNum = (MAX_SIZE + 1)/2;
412 | newNode = new BTreeNode(this.dbName, false, newNum, newKeys, null, newChildren, this.parent, this.next, this);
413 | for( int t = 0; t <= newNum ; ++t ) {
414 | if(null != newNode.children[t])
415 | newNode.children[t].parent = newNode;
416 | }
417 |
418 | this.numKeys = (MAX_SIZE + 1)/2;
419 | this.next = newNode;
420 | }
421 | }
422 | }
423 | }
424 | }catch(Exception e){}
425 | finally{
426 | this.unLockWrite();
427 | }
428 |
429 | return newNode;
430 | }
431 |
432 |
433 | public SplitLeafVar splitLeaf(int key, IdxBlock value, TransMgr transMgr, Trans tid, CellLogMgr logMgr){
434 |
435 | SplitLeafVar slVar = new SplitLeafVar();
436 |
437 | try{
438 | this.lockWrite();
439 | if(this.isLeaf){
440 |
441 | if(key > this.upperBound()){
442 | int from = MAX_SIZE - 1;
443 | int to = MAX_SIZE;
444 | int newLength = to - from;
445 |
446 | int[] newKeys = new int[MAX_SIZE + 1];
447 | IdxBlock[] newValues = new IdxBlock[MAX_SIZE + 2];
448 |
449 | for(int i = 0; i < newLength; ++i){
450 | if( i + from < to ) {
451 | newKeys[i] = this.keys[from+i];
452 | newValues[i] = this.values[from+i];
453 | }
454 | }
455 |
456 | slVar.newRight = new BTreeNode(this.dbName, true, 1, newKeys, newValues, null, this.parent, this.next, this);
457 | this.next = slVar.newRight;
458 | this.numKeys = MAX_SIZE - 1;;
459 |
460 | if(key >= slVar.newRight.lowerBound()){
461 | slVar.oldVar = slVar.newRight.addValue(key, value, transMgr, tid, logMgr);
462 | }else{
463 | slVar.oldVar = this.addValue(key, value, transMgr, tid, logMgr);
464 | }
465 | }else{
466 | int from = MAX_SIZE/2;
467 | int to = MAX_SIZE;
468 | int newLength = to - from;
469 |
470 | int[] newKeys = new int[MAX_SIZE + 1];
471 | IdxBlock[] newValues = new IdxBlock[MAX_SIZE + 2];
472 |
473 | for(int i = 0; i < newLength; ++i){
474 | if( i + from < to ) {
475 | newKeys[i] = this.keys[from+i];
476 | newValues[i] = this.values[from+i];
477 | }
478 | }
479 |
480 | slVar.newRight = new BTreeNode(this.dbName, true, MAX_SIZE/2, newKeys, newValues, null, this.parent, this.next, this);
481 | this.next = slVar.newRight;
482 | this.numKeys = MAX_SIZE/2;
483 |
484 | if(key >= slVar.newRight.lowerBound()){
485 | slVar.oldVar = slVar.newRight.addValue(key, value, transMgr, tid, logMgr);
486 | }else{
487 | slVar.oldVar = this.addValue(key, value, transMgr, tid, logMgr);
488 | }
489 | }
490 | }
491 | }catch(Exception e){}
492 | finally{
493 | this.unLockWrite();
494 | }
495 |
496 | return slVar;
497 | }
498 |
499 | public boolean addChild(int key, BTreeNode node){
500 | boolean b = false;
501 |
502 | try{
503 |
504 | this.lockWrite();
505 | if(!this.isLeaf && this.numKeys < MAX_SIZE){
506 | int i = 0;
507 | for(; i < this.numKeys; ){
508 | if(this.keys[i] < key)
509 | ++i;
510 | else
511 | break;
512 | }
513 |
514 | if(i < MAX_SIZE){
515 |
516 | for(int t = this.numKeys; t > i; --t){
517 | this.keys[t] = this.keys[t - 1];
518 | this.children[t+1] = this.children[t];
519 | }
520 |
521 | this.keys[i] = key;
522 | this.children[i+1] = node;
523 | this.numKeys++;
524 |
525 | b = true;
526 | }
527 | }
528 | }catch(Exception e){}
529 | finally{
530 | this.unLockWrite();
531 | }
532 |
533 | return b;
534 | }
535 |
536 | public InsertVar addValue(int key, IdxBlock newValue, TransMgr transMgr, Trans tid, CellLogMgr logMgr){
537 |
538 | InsertVar var = new InsertVar();
539 | var.inserted = true;
540 | var.oldValue = null;
541 |
542 | try{
543 | this.lockWrite();
544 |
545 | if(this.isLeaf){
546 | int i = 0;
547 | for(; i < this.numKeys; ){
548 | if(this.keys[i] < key)
549 | ++i;
550 | else
551 | break;
552 | }
553 |
554 | if(i != this.numKeys && this.keys[i] == key){
555 |
556 | if(null != transMgr && null != tid && tid.getTransID() > 0){
557 | BlkID bid = new BlkID(this.dbName, key);
558 |
559 | var.inserted = false;
560 | logMgr.logUpdate(tid, key, newValue, this.values[i]);
561 | if(transMgr.lockBlk(bid, tid)){
562 |
563 | var.oldValue = this.values[i];
564 | this.values[i] = newValue;
565 | var.inserted = true;
566 |
567 | this.values[i].drity = true;
568 | this.values[i].tid = tid.getTransID();
569 | this.values[i].tag = IdxBlock.VALID;
570 | this.values[i].newTag = IdxBlock.VALID;
571 | this.values[i].old = var.oldValue;
572 | this.values[i].time = SystemTime.getSystemTime().currentTime();
573 | transMgr.setTransState(tid, Trans.ACTIVE);
574 | }else{
575 | transMgr.setTransState(tid, Trans.ROLLBACK);
576 | var.conflict = true;
577 | }
578 | }else{
579 | if(false == this.values[i].drity){
580 |
581 | var.oldValue = this.values[i];
582 | this.values[i] = newValue;
583 | this.values[i].time = SystemTime.getSystemTime().currentTime();
584 | var.inserted = true;
585 |
586 | this.values[i].tag = IdxBlock.VALID;
587 | }else{
588 | var.inserted = false;
589 | }
590 | }
591 | }else if(this.numKeys != MAX_SIZE){
592 |
593 | for(int t = this.numKeys; t > i; --t){
594 | this.keys[t] = this.keys[t - 1];
595 | this.values[t] = this.values[t - 1];
596 | }
597 |
598 | if(null != transMgr && null != tid && tid.getTransID() > 0){
599 |
600 | var.inserted = false;
601 |
602 | logMgr.logInsert(tid, key, newValue);
603 |
604 | if(transMgr.lockBlk(new BlkID(this.dbName, key), tid)){
605 |
606 | this.keys[i] = key;
607 | this.values[i] = newValue;
608 |
609 | // System.out.println("addValue.0 " + key);
610 | this.values[i].drity = true;
611 | this.values[i].tid = tid.getTransID();
612 | this.values[i].old = null;
613 | this.values[i].tag = IdxBlock.INVALID;
614 | this.values[i].newTag = IdxBlock.VALID;
615 | this.values[i].time = SystemTime.getSystemTime().currentTime();
616 | this.numKeys++;
617 | var.inserted = true;
618 |
619 | }else{
620 |
621 | var.conflict = true;
622 | }
623 | }else{
624 | // System.out.println("addValue.0 " + key);
625 | this.keys[i] = key;
626 | this.values[i] = newValue;
627 | this.values[i].time = SystemTime.getSystemTime().currentTime();
628 |
629 | this.numKeys++;
630 | var.inserted = true;
631 | }
632 | }else{
633 | var.inserted = false;
634 | }
635 | }
636 | }catch(Exception e){}
637 | finally{
638 | this.unLockWrite();
639 | }
640 |
641 | return var;
642 | }
643 |
644 | public BTreeNode getChild(int key){
645 | BTreeNode child = null;
646 |
647 | try{
648 | this.lockRead();
649 |
650 | if(!this.isLeaf){
651 | int i = 0;
652 | for(; i < this.numKeys; ){
653 | if(this.keys[i] <= key)
654 | ++i;
655 | else
656 | break;
657 | }
658 | child = children[i];
659 | }
660 | }
661 | catch(Exception e){
662 | System.out.println(e);
663 | }
664 | finally{
665 | this.unLockRead();
666 | }
667 |
668 | return child;
669 | }
670 |
671 | public IdxBlock delValue(int key, TransMgr transMgr, Trans tid, CellLogMgr logMgr) throws AbortTransException{
672 | IdxBlock oldObj = null;
673 |
674 | try{
675 | this.lockWrite();
676 |
677 | if(this.isLeaf){
678 | int i = 0;
679 | for(; i < this.numKeys; ){
680 | if(this.keys[i] < key)
681 | ++i;
682 | else
683 | break;
684 | }
685 |
686 | if(this.keys[i] == key && IdxBlock.VALID == this.values[i].tag){
687 |
688 | if(null != transMgr && null != tid && tid.getTransID() > 0){
689 | logMgr.logDelete(tid, key);
690 |
691 | if((false == this.values[i].drity)
692 | ||(this.values[i].drity && this.values[i].tid == tid.getTransID())){
693 |
694 | if(transMgr.lockBlk(new BlkID(this.dbName, key), tid)){
695 | oldObj = this.values[i];
696 |
697 | this.values[i].drity = true;
698 | this.values[i].tid = tid.getTransID();
699 | this.values[i].tag = IdxBlock.VALID;
700 | this.values[i].newTag = IdxBlock.INVALID;
701 | this.values[i].time = SystemTime.getSystemTime().currentTime();
702 | this.values[i].old = oldObj;
703 | transMgr.setTransState(tid, Trans.ACTIVE);
704 | }else{
705 | transMgr.setTransState(tid, Trans.ROLLBACK);
706 | }
707 | }else{
708 | transMgr.setTransState(tid, Trans.ROLLBACK);
709 | tid.setState(Trans.ROLLBACK);
710 | ////////// conflict
711 | throw new AbortTransException("delValue: key = " + key);
712 | }
713 | }else{
714 | if(false == this.values[i].drity){
715 | this.values[i].tag = IdxBlock.INVALID;
716 | }
717 | }
718 | }
719 | }
720 | }
721 | catch(AbortTransException ate){
722 | throw ate;
723 | }
724 | catch(Exception e){
725 | System.out.println(e);
726 | }
727 | finally{
728 | this.unLockWrite();
729 | }
730 |
731 | return oldObj;
732 | }
733 |
734 | public IdxBlock setValue(int key, IdxBlock newObj, TransMgr transMgr, Trans tid, CellLogMgr logMgr) throws AbortTransException{
735 | IdxBlock oldObj = null;
736 |
737 | try{
738 | this.lockWrite();
739 |
740 | if(this.isLeaf){
741 | int i = 0;
742 | for(; i < this.numKeys; ){
743 | if(this.keys[i] < key)
744 | ++i;
745 | else
746 | break;
747 | }
748 |
749 | if(this.keys[i] == key){
750 |
751 | if(null != transMgr && null != tid && tid.getTransID() > 0){
752 |
753 | logMgr.logUpdate(tid, key, newObj, this.values[i]);
754 |
755 | if((false == this.values[i].drity)||
756 | (this.values[i].tid == tid.getTransID())){
757 |
758 | if(transMgr.lockBlk(new BlkID(this.dbName, key), tid)){
759 | oldObj = this.values[i];
760 | this.values[i] = newObj;
761 |
762 | this.values[i].drity = true;
763 | this.values[i].tid = tid.getTransID();
764 | this.values[i].tag = IdxBlock.VALID;
765 | this.values[i].newTag = IdxBlock.VALID;
766 | this.values[i].old = oldObj;
767 | this.values[i].time = SystemTime.getSystemTime().currentTime();
768 |
769 | transMgr.setTransState(tid, Trans.ACTIVE);
770 | }else{
771 | transMgr.setTransState(tid, Trans.ROLLBACK);
772 | }
773 | }else{
774 | transMgr.setTransState(tid, Trans.ROLLBACK);
775 | tid.setState(Trans.ROLLBACK);
776 | ////////// conflict
777 | throw new AbortTransException("setValue: key = " + key);
778 | }
779 | }else{
780 | if(false == this.values[i].drity){
781 | oldObj = this.values[i];
782 | this.values[i] = newObj;
783 | }
784 | }
785 | }
786 | }
787 | }catch(AbortTransException ate){
788 | throw ate;
789 | }catch(Exception e){
790 | System.out.println(e);
791 | }finally{
792 | this.unLockWrite();
793 | }
794 |
795 | return oldObj;
796 | }
797 |
798 | public IdxBlock rollback(int key, TransMgr transMgr, Trans tid){
799 | IdxBlock value = null;
800 |
801 | try{
802 | this.lockWrite();
803 |
804 | if(this.isLeaf){
805 | int i = 0;
806 | for(; i < this.numKeys; ){
807 | if(this.keys[i] < key)
808 | ++i;
809 | else
810 | break;
811 | }
812 |
813 | if(this.keys[i] == key){
814 | if(null != transMgr && null != tid && tid.getTransID() > 0){
815 | if((true == this.values[i].drity)&&
816 | (this.values[i].tid == tid.getTransID())){
817 |
818 | IdxBlock old = this.values[i].old;
819 | if(null != old){
820 | this.values[i] = old;
821 | this.values[i].old = null;
822 | this.values[i].tid = 0;
823 | this.values[i].drity = false;
824 |
825 | }else{
826 | this.values[i].tag = IdxBlock.INVALID;
827 | this.values[i].tid = 0;
828 | this.values[i].drity = false;
829 | }
830 |
831 | value = this.values[i].copyData();
832 | value.idxOffset = i;
833 | }
834 | }
835 | }
836 | }
837 | }catch(Exception e){}
838 | finally{
839 | this.unLockWrite();
840 | }
841 |
842 | return value;
843 | }
844 |
845 | public IdxBlock commit(int key, TransMgr transMgr, Trans tid){
846 | IdxBlock value = null;
847 |
848 | try{
849 | this.lockWrite();
850 |
851 | if(this.isLeaf){
852 | int i = 0;
853 | for(; i < this.numKeys; ){
854 | if(this.keys[i] < key)
855 | ++i;
856 | else
857 | break;
858 | }
859 |
860 | if(this.keys[i] == key){
861 | if(null != transMgr && null != tid && tid.getTransID() > 0){
862 | if((false == this.values[i].drity)||
863 | (this.values[i].tid == tid.getTransID())){
864 |
865 | this.values[i].old = null;
866 | this.values[i].drity = false;
867 | this.values[i].tag = this.values[i].newTag;
868 | this.values[i].tid = 0;
869 | this.values[i].time = SystemTime.getSystemTime().currentTime();
870 | value = this.values[i].copyData();
871 | value.idxOffset = i;
872 | }
873 | }
874 | }
875 | }
876 | }catch(Exception e){}
877 | finally{
878 | this.unLockWrite();
879 | }
880 |
881 | return value;
882 | }
883 |
884 | public IdxBlock getValue(int key, TransMgr transMgr, Trans tid){
885 | IdxBlock value = null;
886 |
887 | try{
888 |
889 | this.lockRead();
890 | if(this.isLeaf){
891 | int i = 0;
892 | for(; i < this.numKeys; ){
893 | if(this.keys[i] < key)
894 | ++i;
895 | else
896 | break;
897 | }
898 |
899 | // System.out.println("getValue.1 i = " + i + ", " + this.keys[i]);
900 | if(this.keys[i] == key && IdxBlock.VALID == this.values[i].tag)
901 | {
902 | // System.out.println("getValue.2 i = " + i + ", " + this.keys[i]);
903 | if(null != transMgr && null != tid && tid.getTransID() > 0){
904 | if((false == this.values[i].drity)
905 | ||(this.values[i].tid == tid.getTransID())){
906 |
907 | this.values[i].tid = tid.getTransID();
908 | value = this.values[i].copyData();
909 | }else{
910 | if(null != this.values[i].old){
911 | value = this.values[i].old.copyData();
912 | }
913 | }
914 | }else{
915 | if(false == this.values[i].drity){
916 | // System.out.println("getValue.3 i = " + i + ", " + this.keys[i]);
917 | value = this.values[i].copyData();
918 | // System.out.println("getValue.4 " + value.idxPageID + ", " + value.idxOffset + ", " + value.pageID + ", " + value.offset);
919 | }else{
920 | if(null != this.values[i].old){
921 | value = this.values[i].old.copyData();
922 | }
923 | }
924 | }
925 | }
926 | }
927 | }catch(Exception e){
928 | System.out.println(e);
929 | }
930 | finally{
931 | this.unLockRead();
932 | }
933 | return value;
934 | }
935 | }
936 |
--------------------------------------------------------------------------------
/src/tenndb/bstar/IdxBlock.java:
--------------------------------------------------------------------------------
1 | package tenndb.bstar;
2 |
3 | import java.nio.ByteBuffer;
4 |
5 | public class IdxBlock {
6 |
7 | protected int tabId;
8 | protected int idxPos;
9 | protected int idxPageID;
10 | protected int idxOffset;
11 |
12 |
13 |
14 | protected int key;
15 |
16 | protected int pageID;
17 |
18 | protected int offset;
19 |
20 | protected int time;
21 |
22 | protected byte tag;
23 |
24 | protected boolean drity;
25 | //
26 | protected byte newTag;
27 |
28 | protected int tid;
29 |
30 | protected IdxBlock old;
31 |
32 | public static final byte INVALID = (byte)0;
33 | public static final byte VALID = (byte)1;
34 |
35 | public int getTabId() {
36 | return tabId;
37 | }
38 |
39 | public void setTabId(int tabId) {
40 | this.tabId = tabId;
41 | }
42 |
43 | public int getIdxPos() {
44 | return idxPos;
45 | }
46 |
47 | public void setIdxPos(int idxPos) {
48 | this.idxPos = idxPos;
49 | }
50 |
51 | public int getIdxPageID() {
52 | return idxPageID;
53 | }
54 |
55 | public void setIdxPageID(int idxPageID) {
56 | this.idxPageID = idxPageID;
57 | }
58 |
59 | public int getIdxOffset() {
60 | return idxOffset;
61 | }
62 |
63 | public void setIdxOffset(int idxOffset) {
64 | this.idxOffset = idxOffset;
65 | }
66 |
67 | public static void toByteBuffer(IdxBlock blk, ByteBuffer buff){
68 | if(null != blk){
69 |
70 | buff.putInt(blk.key);
71 | buff.putInt(blk.pageID);
72 | buff.putInt(blk.offset);
73 | buff.putInt(blk.time);
74 | buff.put(blk.tag);
75 | }
76 | }
77 |
78 | public IdxBlock(int key) {
79 | super();
80 | this.idxPos = 0;
81 | this.idxPageID = 0;
82 | this.idxOffset = 0;
83 |
84 | this.key = key;
85 | this.pageID = 0;
86 | this.offset = 0;
87 | this.time = 0;
88 | this.drity = false;
89 | this.tid = 0;
90 | this.tag = VALID;
91 | this.newTag = VALID;
92 | this.old = null;
93 | }
94 |
95 | public IdxBlock copyData(){
96 | IdxBlock blk = new IdxBlock(this.key);
97 | blk.pageID = this.pageID;
98 | blk.offset = this.offset;
99 | blk.time = this.time;
100 | return blk;
101 | }
102 |
103 | public int getTime(){
104 | return this.time;
105 | }
106 |
107 | public int getKey() {
108 | return key;
109 | }
110 |
111 | public void setKey(int key) {
112 | this.key = key;
113 | }
114 |
115 | public byte getTag() {
116 | return tag;
117 | }
118 |
119 | public void setTag(byte tag) {
120 | this.tag = tag;
121 | }
122 |
123 | public int getPageID() {
124 | return pageID;
125 | }
126 |
127 | public void setPageID(int pageID) {
128 | this.pageID = pageID;
129 | }
130 |
131 | public int getOffset() {
132 | return offset;
133 | }
134 |
135 | public void setOffset(int offset) {
136 | this.offset = offset;
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/src/tenndb/bstar/IdxOld.java:
--------------------------------------------------------------------------------
1 | package tenndb.bstar;
2 |
3 | public class IdxOld{
4 | public int pageID;
5 | public int offset;
6 | public int time;
7 | };
--------------------------------------------------------------------------------
/src/tenndb/bstar/InsertVar.java:
--------------------------------------------------------------------------------
1 | package tenndb.bstar;
2 |
3 | public class InsertVar {
4 |
5 | protected boolean inserted = true;
6 | protected boolean conflict = false;
7 |
8 | protected IdxBlock oldValue = null;
9 | }
10 |
--------------------------------------------------------------------------------
/src/tenndb/bstar/RandomInsertBStarTree.java:
--------------------------------------------------------------------------------
1 | package tenndb.bstar;
2 |
3 | import java.nio.ByteBuffer;
4 | import java.util.ArrayList;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 | import java.util.concurrent.locks.ReadWriteLock;
9 | import java.util.concurrent.locks.ReentrantReadWriteLock;
10 |
11 | import tenndb.index.IBTree;
12 | import tenndb.index.IndexMgr;
13 | import tenndb.index.IndexPage;
14 | import tenndb.log.CellLogMgr;
15 | import tenndb.tx.AbortTransException;
16 | import tenndb.tx.Trans;
17 | import tenndb.tx.TransMgr;
18 |
19 |
20 | public class RandomInsertBStarTree implements IBTree {
21 |
22 | public final static int BALANCE_SIZE = 256;
23 |
24 | protected String dbName;
25 | protected final int size;
26 | protected BTreeNode root;
27 | protected IndexMgr indexMgr;
28 | protected TransMgr transMgr;
29 |
30 | protected ReadWriteLock lock = new ReentrantReadWriteLock(false);
31 |
32 | public void lockRead() { this.lock.readLock().lock(); }
33 |
34 | public void unLockRead() { this.lock.readLock().unlock(); }
35 |
36 | public void lockWrite() { this.lock.writeLock().lock(); }
37 |
38 | public void unLockWrite() { this.lock.writeLock().unlock(); }
39 |
40 |
41 | public RandomInsertBStarTree(String dbName, IndexMgr indexMgr, TransMgr transMgr) {
42 | super();
43 | this.dbName = dbName;
44 | this.size = BALANCE_SIZE;
45 | this.indexMgr = indexMgr;
46 | this.transMgr = transMgr;
47 | }
48 |
49 | public RandomInsertBStarTree(String dbName, IndexMgr indexMgr, TransMgr transMgr, BTreeNode root) {
50 | super();
51 | this.dbName = dbName;
52 | this.size = BALANCE_SIZE;
53 | this.indexMgr = indexMgr;
54 | this.transMgr = transMgr;
55 | this.root = root;
56 | }
57 |
58 | public BTreeNode getRoot() { return this.root; }
59 |
60 | public static IBTree buildBTree(String dbName, IndexMgr indexMgr, TransMgr tansMgr, List buffList, List pageList){
61 | IBTree tree = null;
62 | ////type + pageid + parentid + priorid + nextid + size + (key + offset) * BALANCE_SIZE
63 | if(null != buffList && buffList.size() > 0){
64 | Map map = new HashMap();
65 | List nodeList = new ArrayList();
66 | BTreeNode rootNode = null;
67 | for(int i = 0; i < buffList.size(); ++i){
68 | ByteBuffer buffer = buffList.get(i);
69 | // System.out.println("buildBTree.1 " + i + " " + buffer.limit());
70 | if(buffer.limit() == IndexPage.PAGE_SIZE){
71 |
72 | buffer.position(0);
73 | byte type = buffer.get(0);
74 | int pageID = buffer.getInt(1);
75 | int parentID = buffer.getInt(5);
76 | int priorID = buffer.getInt(9);
77 | int nextID = buffer.getInt(13);
78 | int size = buffer.getInt(17);
79 |
80 | int[] keys = new int[size];
81 | IdxBlock[] values = new IdxBlock[size + 2];
82 | BTreeNode[] children = null;
83 |
84 | boolean isLeaf = false;
85 | if(BTreeNode.NODE_LEAF == type || (BTreeNode.NODE_ROOT == type && 1 == buffList.size())){
86 | values = new IdxBlock[size];
87 | for(int t = 0; t < size; ++t){
88 | int key = buffer.getInt(IndexPage.PAGE_HEAD_SIZE + IndexPage.PAGE_BLOCK_SIZE * t);
89 | int pid = buffer.getInt(IndexPage.PAGE_HEAD_SIZE + IndexPage.PAGE_BLOCK_SIZE * t + 4);
90 | int offset = buffer.getInt(IndexPage.PAGE_HEAD_SIZE + IndexPage.PAGE_BLOCK_SIZE * t + 8);
91 | int time = buffer.getInt(IndexPage.PAGE_HEAD_SIZE + IndexPage.PAGE_BLOCK_SIZE * t + 12);
92 | byte tag = buffer.get (IndexPage.PAGE_HEAD_SIZE + IndexPage.PAGE_BLOCK_SIZE * t + 16);
93 |
94 | keys[t] = key;
95 | values[t] = new IdxBlock(key);
96 | values[t].key = key;
97 | values[t].pageID = pid;
98 | values[t].offset = offset;
99 | values[t].time = time;
100 | values[t].tag = tag;
101 | }
102 | isLeaf = true;
103 | }else if(BTreeNode.NODE_BRANCH== type || (BTreeNode.NODE_ROOT == type && 1 < buffList.size())){
104 | for(int t = 0; t < size + 2; ++t){
105 | int key = buffer.getInt(IndexPage.PAGE_HEAD_SIZE + IndexPage.PAGE_BLOCK_SIZE * t);
106 | int pid = buffer.getInt(IndexPage.PAGE_HEAD_SIZE + IndexPage.PAGE_BLOCK_SIZE * t + 4);
107 | byte tag = buffer.get (IndexPage.PAGE_HEAD_SIZE + IndexPage.PAGE_BLOCK_SIZE * t + 16);
108 |
109 | if(t < size)
110 | keys[t] = key;
111 | values[t] = new IdxBlock(key);
112 | values[t].key = key;
113 | values[t].pageID = pid;
114 | values[t].offset = 0;
115 | values[t].time = 0;
116 | values[t].tag = tag;
117 | }
118 | isLeaf = false;;
119 | }
120 |
121 | //(boolean isLeaf, int num, int[] keys, Object[] values, BTreeNode[] children, BTreeNode parent, BTreeNode next, BTreeNode prior)
122 | BTreeNode node = new BTreeNode(dbName, isLeaf, size, keys, values, children, null, null, null);
123 | node.pageID = pageID;
124 | node.parentID = parentID;
125 | node.priorID = priorID;
126 | node.nextID = nextID;
127 |
128 | IndexPage page = indexMgr.addIndexPage(node, buffer);
129 | long pos = IndexPage.PAGE_SIZE * i + IndexPage.INDEX_HEAD_SIZE;
130 | page.setPos(pos);
131 | node.setRefPage(page);
132 | pageList.add(page);
133 |
134 | if(!isLeaf)
135 | node.values = values;
136 |
137 | nodeList.add(node);
138 | map.put(pageID, node);
139 |
140 | if(BTreeNode.NODE_ROOT == type){
141 |
142 | rootNode = node;
143 | }
144 | }
145 | }
146 |
147 | for(int i = 0; i < nodeList.size(); ++i){
148 | BTreeNode node = nodeList.get(i);
149 |
150 | node.parent = map.get(node.parentID);
151 | node.prior = map.get(node.priorID);
152 | node.next = map.get(node.nextID);
153 |
154 | if(!node.isLeaf){
155 |
156 | for(int t = 0; t < node.numKeys + 2; ++t){
157 | node.children[t] = map.get(node.values[t].pageID);
158 | }
159 | node.values = null;
160 | }
161 | }
162 |
163 | tree = new RandomInsertBStarTree(dbName, indexMgr, tansMgr, rootNode);
164 | }
165 |
166 | return tree;
167 | }
168 |
169 | public void print(List strList){
170 |
171 | try{
172 | this.lockRead();
173 | if( root != null ){
174 | root.toString(strList);
175 | }
176 | }catch(Exception e){}
177 | finally{
178 | this.unLockRead();
179 | }
180 | }
181 |
182 | public String toString(){
183 | String str = null;
184 |
185 | try{
186 | this.lockRead();
187 | if( root != null ){
188 | str = root.toString();
189 | }
190 |
191 | }catch(Exception e){}
192 | finally{
193 | this.unLockRead();
194 | }
195 |
196 | return str;
197 | }
198 |
199 | @Override
200 | public void printTreePrior(){
201 |
202 | try{
203 | this.lockRead();
204 |
205 | if(null != root){
206 | BTreeNode currentNode = root;
207 | while(null != currentNode && !currentNode.isLeaf){
208 | currentNode = currentNode.children[currentNode.numKeys];
209 | }
210 |
211 | if(null != currentNode){
212 | int index = 0;
213 | String str = "";
214 | while(null != currentNode){
215 |
216 | str = "";
217 | index++;
218 | for(int i = currentNode.numKeys - 1; i >= 0 ; --i){
219 | if(null != currentNode.values[i]){
220 | str += currentNode.keys[i] + "_" + currentNode.values[i].pageID + ":" + currentNode.values[i].offset + ",";
221 | }else{
222 | str += currentNode.keys[i] + "_null,";
223 | }
224 | }
225 | System.out.println(index + ":" + str);
226 |
227 | currentNode = currentNode.prior;
228 | }
229 | }
230 | }
231 | }catch(Exception e){}
232 | finally{
233 | this.unLockRead();
234 | }
235 | }
236 |
237 | @Override
238 | public void printNext() {
239 |
240 | try{
241 | this.lockRead();
242 |
243 | if(null != root){
244 | BTreeNode currentNode = root;
245 | while(null != currentNode && !currentNode.isLeaf){
246 | currentNode = currentNode.children[0];
247 | }
248 |
249 | if(null != currentNode){
250 | int index = 0;
251 | String str = "";
252 |
253 | while(null != currentNode){
254 | str = "PageID = " + currentNode.getPageID() + ", ";
255 | index++;
256 | for(int i = 0; i < currentNode.numKeys; ++i){
257 | if(null != currentNode.values[i]){
258 | str += currentNode.keys[i] + "_" + currentNode.values[i].pageID + ":" + currentNode.values[i].offset + ",";
259 | }else{
260 | str += currentNode.keys[i] + "_null,";
261 | }
262 | }
263 | System.out.println(index + ":" + str);
264 |
265 | currentNode = currentNode.next;
266 | }
267 | }
268 | }
269 | }catch(Exception e){}
270 | finally{
271 | this.unLockRead();
272 | }
273 | }
274 |
275 | protected boolean addChild(BTreeNode parentNode, int key, BTreeNode newNode){
276 | boolean b = false;
277 |
278 | b = parentNode.addChild(key, newNode);
279 |
280 | if(true == b){
281 | this.indexMgr.appendNewIndexPage(null, parentNode);
282 | }
283 |
284 | return b;
285 | }
286 |
287 | @Override
288 | public IdxBlock insert(int key, IdxBlock value, Trans tid, CellLogMgr logMgr) throws AbortTransException {
289 | IdxBlock oldVal = null;
290 | try{
291 | this.lockRead();
292 |
293 | if(null!= root){
294 | BTreeNode currentNode = root;
295 | while(null != currentNode && !currentNode.isLeaf){
296 | currentNode = currentNode.getChild(key);
297 | }
298 |
299 | if(null != currentNode){
300 | BTreeNode leaf = currentNode;
301 |
302 | InsertVar insert = leaf.addValue(key, value, this.transMgr, tid, logMgr);
303 |
304 | if(false == insert.conflict){
305 | if(!insert.inserted){
306 |
307 | this.unLockRead(); // read lock up to write lock
308 | this.lockWrite();
309 |
310 | SplitLeafVar slVar = leaf.splitLeaf(key, value, this.transMgr, tid, logMgr);
311 |
312 | BTreeNode newRight = slVar.newRight;
313 |
314 | this.indexMgr.appendNewIndexPage(newRight, null);
315 |
316 | oldVal = slVar.oldVar.oldValue;
317 |
318 | BTreeNode parent = newRight.parent;
319 | int addToParent = newRight.lowerBound();
320 |
321 | while(null != parent && ! this.addChild(parent,addToParent, newRight)){
322 |
323 | BTreeNode parentRight = parent.splitBranch(addToParent, newRight);
324 |
325 | this.indexMgr.appendNewIndexPage(parentRight, parent);
326 |
327 | addToParent = parent.getMiddle();
328 | parent = parent.parent;
329 | newRight = parentRight;
330 | }
331 |
332 | if(null == parent){
333 |
334 | BTreeNode newRoot = new BTreeNode(this.dbName, root, newRight, addToParent);
335 | this.indexMgr.appendNewIndexPage(newRoot, root);
336 |
337 | root.parent = newRoot;
338 | newRight.parent = newRoot;
339 | root = newRoot;
340 | }
341 |
342 | this.lockRead(); // write lock down to read lock
343 | this.unLockWrite();
344 |
345 | }else{
346 | oldVal = insert.oldValue;
347 | this.indexMgr.appendNewIndexPage(null, leaf);
348 | }
349 | }else{
350 | transMgr.setTransState(tid, Trans.ROLLBACK);
351 | tid.setState(Trans.ROLLBACK);
352 | throw new AbortTransException("insert: key = " + key);
353 | }
354 | }
355 | }else{
356 | this.unLockRead();
357 | this.lockWrite();
358 |
359 | this.root = new BTreeNode(this.dbName, key, value, this.transMgr, tid);
360 | this.indexMgr.appendNewIndexPage(root, null);
361 |
362 | this.lockRead();
363 | this.unLockWrite();
364 | }
365 |
366 | }catch(AbortTransException ae){
367 | System.out.println(ae);
368 | throw ae;
369 | }
370 | catch(Exception e){
371 | System.out.println(e);
372 | }
373 | finally{
374 | this.unLockRead();
375 | }
376 |
377 | return oldVal;
378 | }
379 |
380 | @Override
381 | public IdxBlock update(int key, IdxBlock rowData, Trans tid, CellLogMgr logMgr) throws AbortTransException {
382 | IdxBlock oldObj = null;
383 |
384 | try{
385 | this.lockRead();
386 |
387 | BTreeNode currentNode = this.root;
388 | while(null != currentNode && !currentNode.isLeaf){
389 | currentNode = currentNode.getChild(key);
390 | }
391 |
392 | if(null != currentNode){
393 | oldObj = currentNode.setValue(key, rowData, this.transMgr, tid, logMgr);
394 | }
395 |
396 | // this.indexMgr.flushNewPages();
397 | }catch(AbortTransException ae){
398 | System.out.println(ae);
399 | throw ae;
400 | }catch(Exception e){}
401 | finally{
402 | this.unLockRead();
403 | }
404 |
405 | return oldObj;
406 | }
407 |
408 | @Override
409 | public IdxBlock delete(int key, Trans tid, CellLogMgr logMgr) {
410 | IdxBlock oldObj = null;
411 |
412 | try{
413 | this.lockWrite();
414 |
415 | BTreeNode currentNode = root;
416 | while(null != currentNode && !currentNode.isLeaf){
417 | currentNode = currentNode.getChild(key);
418 | }
419 |
420 | if(null != currentNode){
421 | oldObj = currentNode.delValue(key, this.transMgr, tid, logMgr);
422 | if(null != oldObj){
423 | this.indexMgr.appendNewIndexPage(null, currentNode);
424 | }
425 | }
426 |
427 | // this.indexMgr.flushNewPages();
428 | }catch(Exception e){}
429 | finally{
430 | this.unLockWrite();
431 | }
432 |
433 | return oldObj;
434 | }
435 |
436 | @Override
437 | public BTreeNode seekNode(int key) {
438 | BTreeNode currentNode = null;
439 |
440 | try{
441 | this.lockRead();
442 |
443 | currentNode = this.root;
444 |
445 | while(null != currentNode && !currentNode.isLeaf){
446 | currentNode = currentNode.getChild(key);
447 | }
448 | }catch(Exception e){}
449 | finally{
450 | this.unLockRead();
451 | }
452 | return currentNode;
453 | }
454 |
455 | public boolean rollback(int key, Trans tid, CellLogMgr logMgr){
456 | boolean b = false;
457 |
458 | try{
459 | this.lockRead();
460 |
461 | BTreeNode currentNode = this.root;
462 | while(null != currentNode && !currentNode.isLeaf){
463 | currentNode = currentNode.getChild(key);
464 | }
465 |
466 | if(null != currentNode && currentNode.isLeaf){
467 | IdxBlock blk = currentNode.rollback(key, this.transMgr, tid);
468 | if(null != blk){
469 | // blk.idxPageID = currentNode.pageID;
470 | // b = this.indexMgr.flushBlock(blk);
471 | b = true;
472 | }
473 | }
474 | }catch(Exception e){}
475 | finally{
476 | this.unLockRead();
477 | }
478 | return b;
479 | }
480 |
481 | public boolean commit(int key, Trans tid, CellLogMgr logMgr){
482 | boolean b = false;
483 |
484 | try{
485 | this.lockRead();
486 |
487 | BTreeNode currentNode = root;
488 | while(null != currentNode && !currentNode.isLeaf){
489 | currentNode = currentNode.getChild(key);
490 | }
491 |
492 | if(null != currentNode && currentNode.isLeaf){
493 | IdxBlock blk = currentNode.commit(key, this.transMgr, tid);
494 | if(null != blk){
495 | blk.idxPageID = currentNode.pageID;
496 | b = this.indexMgr.flushBlock(blk);
497 | }
498 | }
499 | }catch(Exception e){}
500 | finally{
501 | this.unLockRead();
502 | }
503 |
504 | return b;
505 | }
506 |
507 | @Override
508 | public IdxBlock search(int key, Trans tid) {
509 | IdxBlock value = null;
510 |
511 | try{
512 | this.lockRead();
513 |
514 | BTreeNode currentNode = this.root;
515 | while(null != currentNode && !currentNode.isLeaf){
516 | currentNode = currentNode.getChild(key);
517 | }
518 |
519 | if(null != currentNode && currentNode.isLeaf){
520 | value = currentNode.getValue(key, this.transMgr, tid);
521 | }
522 | }catch(Exception e){}
523 | finally{
524 | this.unLockRead();
525 | }
526 |
527 | return value;
528 | }
529 |
530 | @Override
531 | public List range(int fromKey, int toKey, boolean isInc) {
532 | List list = new ArrayList();
533 |
534 | try{
535 | this.lockRead();
536 | if(fromKey <= toKey){
537 |
538 | if(isInc){
539 | BTreeNode node = this.seekNode(fromKey);
540 | boolean next = true;
541 | while(null != node){
542 | int i = 0;
543 | for(; i < node.numKeys; ++i){
544 | if(node.keys[i] >= fromKey && node.keys[i] <= toKey){
545 | if(IdxBlock.VALID == node.values[i].tag){
546 | IdxBlock iblk = new IdxBlock(node.keys[i]);
547 | iblk.pageID = node.values[i].pageID;
548 | iblk.offset = node.values[i].offset;
549 |
550 | list.add(iblk);
551 | }
552 | }else if(node.keys[i] > toKey){
553 | next = false;
554 | break;
555 | }
556 | }
557 | if(next)
558 | node = node.next;
559 | else
560 | node = null;
561 | }
562 | }else{
563 |
564 | BTreeNode node = this.seekNode(toKey);
565 | boolean next = true;
566 | while(null != node){
567 | int i = node.numKeys - 1;
568 | for(; i >= 0; --i){
569 | if(node.keys[i] >= fromKey && node.keys[i] <= toKey){
570 | if(IdxBlock.VALID == node.values[i].tag){
571 | IdxBlock iblk = new IdxBlock(node.keys[i]);
572 | iblk.pageID = node.values[i].pageID;
573 | iblk.offset = node.values[i].offset;
574 |
575 | list.add(iblk);
576 | }
577 | }else if(node.keys[i] < fromKey){
578 | next = false;
579 | break;
580 | }
581 | }
582 | if(next)
583 | node = node.prior;
584 | else
585 | node = null;
586 | }
587 | }
588 | }
589 | }catch(Exception e){}
590 | finally{
591 | this.unLockRead();
592 | }
593 |
594 | return list;
595 | }
596 |
597 | @Override
598 | public void toByteBuffer(List list) {
599 |
600 | if(null != this.root && null != list){
601 |
602 | try{
603 | this.lockRead();
604 | this.root.toByteBuffer(list, this.root);
605 | }catch(Exception e){
606 | System.out.println(e);
607 | }
608 | finally{
609 | this.unLockRead();;
610 | }
611 | }
612 | }
613 |
614 | @Override
615 | public int count(int fromKey, int toKey) {
616 | int count = 0;
617 |
618 | try{
619 | this.lockRead();
620 | if(fromKey <= toKey){
621 |
622 | BTreeNode node = this.seekNode(fromKey);
623 | boolean next = true;
624 | while(null != node){
625 | int i = 0;
626 | for(; i < node.numKeys; ++i){
627 | if(node.keys[i] >= fromKey && node.keys[i] <= toKey){
628 | if(IdxBlock.VALID == node.values[i].tag){
629 | ++count;
630 | }
631 | }else if(node.keys[i] > toKey){
632 | next = false;
633 | break;
634 | }
635 | }
636 | if(next)
637 | node = node.next;
638 | else
639 | node = null;
640 | }
641 | }
642 | }catch(Exception e){}
643 | finally{
644 | this.unLockRead();
645 | }
646 |
647 | return count;
648 | }
649 |
650 | }
651 |
--------------------------------------------------------------------------------
/src/tenndb/bstar/SplitLeafVar.java:
--------------------------------------------------------------------------------
1 | package tenndb.bstar;
2 |
3 | public class SplitLeafVar {
4 |
5 | protected BTreeNode newRight = null;
6 |
7 | protected InsertVar oldVar = null;
8 | }
9 |
--------------------------------------------------------------------------------
/src/tenndb/common/ByteUtil.java:
--------------------------------------------------------------------------------
1 | package tenndb.common;
2 |
3 | public final class ByteUtil {
4 |
5 | public static final int INT_SIZE = Integer.SIZE / Byte.SIZE;
6 | public static final int SHORT_SIZE = Short.SIZE / Byte.SIZE;
7 | public static final int BYTE_SIZE = Byte.SIZE / Byte.SIZE;
8 |
9 | public final static short BYTE_MAX_VALUE = 256;
10 | public final static int SHORT_MAX_VALUE = 65535;
11 | public final static long INT_MAX_VALUE = 4294967296L;
12 |
13 | public final static int byte2ToShort_big(byte[] buf, int offset)
14 | {
15 | int n = 0;
16 | if(null != buf)
17 | {
18 | for(int i = 0 ;i < 2; i++)
19 | {
20 | n <<= 8;
21 | n |= (buf[offset + i] & 0x000000FF);
22 | }
23 | }
24 | return n;
25 | }
26 |
27 | public static byte[] shortToByte2_big(int n)
28 | {
29 | byte[] buf = new byte[2];
30 |
31 | for(int i = 1; i >= 0; i--){
32 | buf[i] = (byte) (n & 0xFF);
33 | n >>= 8;
34 | }
35 |
36 | return buf;
37 | }
38 |
39 |
40 | public final static int byte4ToInt_big(byte[] buf, int offset)
41 | {
42 | int n = 0;
43 | if(null != buf)
44 | {
45 | for(int i = 0 ;i < 4; i++)
46 | {
47 | n <<= 8;
48 | n |= (buf[offset + i] & 0x000000FF);
49 | }
50 | }
51 | return n;
52 | }
53 |
54 | public static byte[] intToByte4_big(int n)
55 | {
56 | byte[] buf = new byte[4];
57 |
58 | for(int i = 3; i >= 0; i--){
59 | buf[i] = (byte) (n & 0xFF);
60 | n >>= 8;
61 | }
62 |
63 | return buf;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/tenndb/common/DateFormatUtil.java:
--------------------------------------------------------------------------------
1 | package tenndb.common;
2 |
3 | import java.text.SimpleDateFormat;
4 | import java.util.Locale;
5 | import java.util.TimeZone;
6 |
7 | public class DateFormatUtil {
8 |
9 | private static final String GMT_TIME_ZONE = "GMT+08:00".intern();
10 |
11 | public static ThreadLocal threadLocalDateFormat(final String pattern)
12 | {
13 | ThreadLocal tl = new ThreadLocal() {
14 | protected SimpleDateFormat initialValue() {
15 | SimpleDateFormat df = new SimpleDateFormat(pattern, Locale.ENGLISH);
16 | df.setTimeZone(TimeZone.getTimeZone(DateFormatUtil.GMT_TIME_ZONE));
17 | return df;
18 | }
19 | };
20 | return tl;
21 | }
22 |
23 | public static ThreadLocal threadLocalDateFormat
24 | (final String pattern, final TimeZone time_zone)
25 | {
26 | ThreadLocal tl = new ThreadLocal()
27 | {
28 | protected SimpleDateFormat initialValue() {
29 | SimpleDateFormat df = new SimpleDateFormat(pattern, Locale.ENGLISH);
30 | df.setTimeZone(time_zone);
31 | return df;
32 | }
33 | };
34 | return tl;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/tenndb/common/FileDeco.java:
--------------------------------------------------------------------------------
1 | package tenndb.common;
2 |
3 |
4 | import java.nio.channels.FileChannel;
5 |
6 | public class FileDeco {
7 |
8 | protected String fileName;
9 | protected int ref = 0;
10 | protected int state;
11 | protected int size;
12 | protected FileChannel fc;
13 |
14 | // protected MappedByteBuffer out;
15 |
16 | protected final Object lock = new Object();
17 |
18 | public static final int STATE_INIT = 0;
19 | public static final int STATE_OPEN = 1;
20 | public static final int STATE_CLOSING = 2;
21 | public static final int STATE_CLOSED = 3;
22 |
23 | public FileChannel getFileChannel(){
24 | return this.fc;
25 | }
26 |
27 | public int incRef(){
28 | int n = -1;
29 | synchronized(lock){
30 | ref++;
31 | n = ref;
32 | }
33 | return n;
34 | }
35 |
36 | public int decRef(){
37 | int n = -1;
38 | synchronized(lock){
39 | ref--;
40 | n = ref;
41 | }
42 | return n;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/tenndb/common/FileMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.common;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.RandomAccessFile;
6 | import java.nio.ByteBuffer;
7 |
8 | import java.util.concurrent.ConcurrentHashMap;
9 | import java.util.concurrent.ConcurrentMap;
10 |
11 |
12 | public class FileMgr {
13 |
14 | protected ConcurrentMap fileMap = null;
15 |
16 | protected File dir;
17 |
18 | // static int LEN = 0x800000; // 128 Mb
19 |
20 | public FileMgr(String instName){
21 | if(null != instName && instName.length() > 0){
22 | dir = new File(instName);
23 | }else{
24 | String homedir = System.getProperty("user.home");
25 | dir = new File(homedir, instName);
26 | }
27 |
28 | if(!dir.exists()){
29 |
30 | FileUtil.mkDir(dir);
31 |
32 | if(!dir.exists()){
33 | throw new RuntimeException("cannot create " + instName);
34 | }
35 | }
36 |
37 | this.fileMap = new ConcurrentHashMap();
38 | }
39 |
40 | public String[] listFiles(){
41 | return dir.list();
42 | }
43 |
44 | public boolean delete(String fileName){
45 | boolean b = false;
46 | this.closeFileChannel(fileName);
47 |
48 | File file = new File(this.dir, fileName);
49 | if(file.exists()){
50 | b = file.delete();
51 | }
52 |
53 | if(b){
54 | System.out.println("delete.ok " + fileName);
55 | }else{
56 | System.out.println("delete.failed " + fileName);
57 | }
58 |
59 | return b;
60 | }
61 |
62 | public boolean copy(String oldFileName, String newFileName){
63 | boolean b = false;
64 |
65 | try {
66 | long size = this.size(oldFileName);
67 | if(size > 0){
68 | this.delete(newFileName);
69 | FileDeco dest = pinFileChannel(newFileName);
70 | FileDeco src = pinFileChannel(oldFileName);
71 | if(null != src && null != dest){
72 | src.fc.position(0);
73 | dest.fc.position(0);
74 | ByteBuffer buffer = ByteBuffer.allocate(1000);
75 | while(src.fc.position() < src.fc.size() && src.fc.size() > 0){
76 |
77 | src.fc.read(buffer);
78 | buffer.flip();
79 | while(buffer.hasRemaining()){
80 | dest.fc.write(buffer);
81 | }
82 | // System.out.println(src.fc.position() + "," + src.fc.size() + "," + buffer.limit());
83 | buffer.rewind();
84 | }
85 | b = true;
86 | }
87 | }
88 | } catch (IOException e) {
89 | e.printStackTrace();
90 | }
91 |
92 |
93 | return b;
94 | }
95 |
96 | public long append(String fileName, ByteBuffer buffer){
97 | long pos = 0;
98 | try {
99 | FileDeco dest = pinFileChannel(fileName);
100 | if(null != dest){
101 | pos = dest.fc.size();
102 | dest.fc.position(dest.fc.size());
103 |
104 | buffer.position(0);
105 |
106 | while(buffer.hasRemaining()){
107 | dest.fc.write(buffer);
108 | }
109 | }
110 | } catch (IOException e) {
111 | e.printStackTrace();
112 | }
113 | return pos;
114 | }
115 |
116 | public boolean rename(String oldFileName, String newFileName){
117 | boolean b = false;
118 | this.closeFileChannel(oldFileName);
119 | this.closeFileChannel(newFileName);
120 |
121 | File srcFile = new File(this.dir, oldFileName);
122 | File destFile = new File(this.dir, newFileName);
123 |
124 | b = srcFile.renameTo(destFile);
125 | if(b){
126 | System.out.println("rename.ok " + oldFileName + " is renamed to " + newFileName);
127 | }else{
128 | System.out.println("rename.failed " + oldFileName + " is renamed to " + newFileName);
129 | }
130 | return b;
131 | }
132 |
133 |
134 | public void readBuffer(String fileName, byte[] buffer, long pos) throws IOException{
135 | File file = new File(this.dir, fileName);
136 | RandomAccessFile f = new RandomAccessFile(file, "rws");
137 |
138 | f.seek(pos);
139 | f.read(buffer);
140 | f.close();
141 |
142 | // f.close();
143 | /* FileDeco fd = pinFileChannel(fileName);
144 | if(null != fd){
145 | if(pos + len <= fd.fc.size()){
146 | fd.fc.position(pos);
147 | fd.fc.read(buffer);
148 | }
149 | } */
150 | }
151 |
152 | public void writeBuffer(String fileName, byte[] buffer, long pos) throws IOException{
153 |
154 | File file = new File(this.dir, fileName);
155 | RandomAccessFile f = new RandomAccessFile(file, "rws");
156 |
157 | f.seek(pos);
158 | f.write(buffer);
159 | f.close();
160 |
161 | /* FileDeco fd = pinFileChannel(fileName);
162 | if(null != fd){
163 | if(pos + len <= fd.fc.size()){
164 | fd.fc.position(pos);
165 | while(buffer.hasRemaining()){
166 | fd.fc.write(buffer);
167 | }
168 | }
169 | }*/
170 | }
171 |
172 | public void removeFileChannel(String fileName) throws IOException{
173 |
174 | FileDeco fd = null;
175 | fd = this.fileMap.remove(fileName);
176 |
177 | if(null != fd){
178 | this.closeFileChannel(fd);
179 | }
180 | }
181 |
182 | public void closeFileChannel(FileDeco fd){
183 | if(null != fd){
184 | if(null != fd.fc){
185 | try {
186 |
187 | fd.fc.close();
188 | } catch (IOException e) {
189 | e.printStackTrace();
190 | }
191 | }
192 |
193 | try {
194 | this.removeFileChannel(fd.fileName);
195 | } catch (IOException e) {
196 | e.printStackTrace();
197 | }
198 | }
199 | }
200 |
201 | public void closeFileChannel(String fileName){
202 | FileDeco fd = null;
203 |
204 | fd = this.fileMap.get(fileName);
205 |
206 | if(null != fd){
207 | if(null != fd.fc){
208 | try {
209 |
210 | fd.fc.close();
211 | } catch (IOException e) {
212 | e.printStackTrace();
213 | }
214 | }
215 |
216 | try {
217 | this.removeFileChannel(fd.fileName);
218 | } catch (IOException e) {
219 | e.printStackTrace();
220 | }
221 | }
222 | }
223 |
224 |
225 | public FileDeco pinFileChannel(String fileName) throws IOException{
226 | FileDeco fd = null;
227 |
228 | fd = this.fileMap.get(fileName);
229 |
230 | if(null == fd){
231 | File file = new File(this.dir, fileName);
232 | RandomAccessFile f = new RandomAccessFile(file, "rws");
233 | fd = new FileDeco();
234 | fd.fileName = fileName;
235 |
236 | fd.fc = f.getChannel();
237 |
238 | // fd.out = fd.fc.map(FileChannel.MapMode.READ_WRITE, 0, LEN);
239 |
240 | this.fileMap.put(fileName, fd);
241 | }
242 |
243 | return fd;
244 | }
245 |
246 | public synchronized long size(String filename) {
247 | long size = 0;
248 | try {
249 | FileDeco fd = pinFileChannel(filename);
250 | if(null != fd){
251 | size = fd.fc.size();
252 | }
253 | } catch (IOException e) {
254 | throw new RuntimeException("cannot access " + filename);
255 | }
256 | return size;
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/src/tenndb/common/FileUtil.java:
--------------------------------------------------------------------------------
1 | package tenndb.common;
2 |
3 | import java.io.BufferedWriter;
4 | import java.io.File;
5 | import java.io.FileWriter;
6 | import java.io.IOException;
7 | import java.util.List;
8 |
9 | public class FileUtil
10 | {
11 | public final static void mkDir(File file)
12 | {
13 | if (file.getParentFile().exists()) {
14 | file.mkdir();
15 | } else {
16 | mkDir(file.getParentFile());
17 | file.mkdir();
18 | }
19 | }
20 |
21 | public final static boolean createFile(File file)
22 | {
23 | boolean isCreated = false;
24 | if (file == null)
25 | {
26 | throw new RuntimeException(" can not create null file.");
27 | }
28 |
29 | if (file.exists())
30 | isCreated = true;
31 | else
32 | {
33 | File parentDir = file.getParentFile();
34 |
35 | if (parentDir != null && !parentDir.exists())
36 | {
37 | if (!parentDir.mkdirs())
38 | {
39 | isCreated = false;
40 | }
41 | }
42 | try
43 | {
44 | isCreated = file.createNewFile();
45 | } catch (IOException e)
46 | {
47 | throw new RuntimeException(e);
48 | }
49 | }
50 | return isCreated;
51 | }
52 |
53 | public static boolean deleteDirectory(File path)
54 | {
55 | if (path.exists())
56 | {
57 | File[] files = path.listFiles();
58 | for (int i = 0; i < files.length; i++)
59 | {
60 | if (files[i].isDirectory())
61 | {
62 | deleteDirectory(files[i]);
63 | } else
64 | {
65 | files[i].delete();
66 | }
67 | }
68 | }
69 | return (path.delete());
70 | }
71 |
72 | public final static boolean deleteFile(String filePath)
73 | {
74 | boolean ret = false;
75 |
76 | if(null != filePath && filePath.length() > 0)
77 | {
78 | File file = new File(filePath);
79 |
80 | if(file.exists())
81 | {
82 | ret = file.delete();
83 | }
84 | }
85 | return ret;
86 | }
87 |
88 | public static final void writeFile(String fullFilePath, List list)
89 | {
90 | if(null != fullFilePath && fullFilePath.length() > 0 && null != list && list.size() > 0)
91 | {
92 | File file = null;
93 | FileWriter fw = null;
94 | BufferedWriter out = null;
95 | try
96 | {
97 | file = new File(fullFilePath);
98 |
99 |
100 | fw = new FileWriter(file, true);
101 | out = new BufferedWriter(fw);
102 | for (String str : list)
103 | {
104 | if(null != str && str.length() > 0)
105 | {
106 | out.append(str);
107 | out.newLine();
108 | }
109 | }
110 | out.flush();
111 | }
112 | catch (Exception e)
113 | {
114 | System.out.println("fullFilePath = " + fullFilePath);
115 | e.printStackTrace();
116 | }
117 | finally
118 | {
119 | if(null != fw){
120 | try {
121 | fw.close();
122 | } catch (IOException e) {
123 | }
124 | }
125 |
126 | if(null != out){
127 | try {
128 | out.close();
129 | } catch (IOException e) {
130 | }
131 | }
132 | }
133 | }
134 | }
135 |
136 | /* public final static boolean append(String path, String content)
137 | {
138 | boolean b = false;
139 |
140 | if(null != path && path.length() > 0
141 | && null != content && content.length() > 0 )
142 | {
143 | File file = new File(path);
144 |
145 | if(createFile(file))
146 | {
147 | RandomAccessFile accesser = null;
148 | try
149 | {
150 | accesser = new RandomAccessFile(file, "rw");
151 |
152 | accesser.seek(accesser.length());
153 |
154 | accesser.writeUTF(content);
155 | b = true;
156 | } catch (Exception e)
157 | {
158 | throw new RuntimeException(e);
159 | }
160 | finally
161 | {
162 | if(null != accesser)
163 | try
164 | {
165 | accesser.close();
166 | } catch (IOException e)
167 | {
168 | }
169 | }
170 | }
171 | }
172 |
173 | return b;
174 | }
175 |
176 | public final static boolean append(String path, byte[] buf, int offset, int len)
177 | {
178 | boolean isAppended = false;
179 |
180 | if(null != path && path.length() > 0 && null != buf && buf.length > 0 && len > 0)
181 | {
182 | File file = new File(path);
183 |
184 | // System.out.println(path);
185 |
186 | if(createFile(file))
187 | {
188 | RandomAccessFile accesser = null;
189 | try
190 | {
191 | accesser = new RandomAccessFile(file, "rw");
192 | accesser.seek(accesser.length());
193 | accesser.write(buf, offset, len);
194 | isAppended = true;
195 | } catch (Exception e)
196 | {
197 | throw new RuntimeException(e);
198 | }
199 | finally
200 | {
201 | if(null != accesser)
202 | try
203 | {
204 | accesser.close();
205 | } catch (IOException e)
206 | {
207 | }
208 | }
209 | }
210 | }
211 | return isAppended;
212 | }*/
213 | }
214 |
--------------------------------------------------------------------------------
/src/tenndb/common/GraphFindCycle.java:
--------------------------------------------------------------------------------
1 | package tenndb.common;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 |
7 |
8 | public class GraphFindCycle {
9 | public List servList;
10 |
11 | public void setServList(List servList){
12 | this.servList = servList;
13 | }
14 |
15 | class ServRel{
16 | public String useServId;
17 | public String providerServId;
18 | public double amount;
19 | }
20 |
21 | class Serv{
22 | public String servId;
23 | public List refServ = new ArrayList();
24 | }
25 |
26 | public List findRefServ(String servId,List servRelList){
27 | List refServList = new ArrayList();
28 | for(int i = 0; i < servRelList.size(); i++){
29 | ServRel rel = (ServRel)servRelList.get(i);
30 | if(servId.equals(rel.useServId)){
31 | refServList.add(rel.providerServId);
32 | }
33 | }
34 | return refServList;
35 | }
36 |
37 | class CycleServ{
38 | public List cycleServList;
39 | }
40 |
41 | public void findCycleServ(String servId,String cyclePath, List servRelList){
42 | String id = servId;
43 | List refServList = findRefServ(servId, servRelList);
44 | if(!(refServList.size()>0)){
45 | return;
46 | }
47 | else if(cyclePath.indexOf(servId)>0){
48 | System.out.println(cyclePath + "," + id);
49 | return;
50 | }
51 | else{
52 | cyclePath = cyclePath+","+id;
53 | for(int j = 0; j < refServList.size(); j++){
54 | String childServId = (String)refServList.get(j);
55 | findCycleServ(childServId,cyclePath,servRelList);
56 | }
57 | }
58 | }
59 |
60 |
61 | public static void main(String[] args) {
62 | GraphFindCycle gfc = new GraphFindCycle();
63 | List servList = new ArrayList();
64 | servList.add("A");
65 | servList.add("B");
66 | servList.add("C");
67 | servList.add("D");
68 | servList.add("E");
69 | servList.add("F");
70 |
71 | List servRelList = new ArrayList();
72 | ServRel sr = gfc.new ServRel();
73 | sr.useServId = "A";
74 | sr.providerServId = "B";
75 | servRelList.add(sr);
76 | ServRel sr1 = gfc.new ServRel();
77 | sr1.useServId = "B";
78 | sr1.providerServId = "A";
79 | servRelList.add(sr1);
80 | ServRel sr2 = gfc.new ServRel();
81 | sr2.useServId = "A";
82 | sr2.providerServId = "C";
83 | servRelList.add(sr2);
84 | ServRel sr3 = gfc.new ServRel();
85 | sr3.useServId = "B";
86 | sr3.providerServId = "D";
87 | servRelList.add(sr3);
88 | ServRel sr4 = gfc.new ServRel();
89 | sr4.useServId = "E";
90 | sr4.providerServId = "A";
91 | servRelList.add(sr4);
92 | ServRel sr5 = gfc.new ServRel();
93 | sr5.useServId = "F";
94 | sr5.providerServId = "B";
95 | servRelList.add(sr5);
96 |
97 | //System.out.println(servRelList.size());
98 | for(int i=0;i 10*1000L){
43 | synchronized(_lock){
44 | if((lastTick - this.baseTick) > 10*1000L){
45 | // System.out.println("+++++++++++++++++++++++++++++++++++++++getCurrentTime");
46 | this.baseTime = new Date().getTime();
47 | this.baseTick = System.currentTimeMillis();
48 | lastTick = this.baseTick;
49 | }
50 | }
51 | }
52 |
53 | currentTime = this.baseTime + (lastTick - this.baseTick);
54 |
55 | return currentTime;
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/tenndb/common/test/TestSystemTime.java:
--------------------------------------------------------------------------------
1 | package tenndb.common.test;
2 |
3 | import java.util.Date;
4 |
5 | import tenndb.common.SystemTime;
6 |
7 | public class TestSystemTime {
8 |
9 | /**
10 | * @param args
11 | */
12 | public static void main(String[] args) {
13 |
14 | for(int i = 0; i < 100; ++i){
15 | SystemTime sys = SystemTime.getSystemTime();
16 | System.out.println(new Date().toString() + " " + sys.currentTimeMillis());
17 | try {
18 | Thread.sleep(1000);
19 | } catch (InterruptedException e) {
20 | // TODO Auto-generated catch block
21 | e.printStackTrace();
22 | }
23 | }
24 |
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/tenndb/data/ByteBufferMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.data;
2 |
3 | import java.nio.ByteBuffer;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import java.util.Queue;
7 | import java.util.concurrent.LinkedBlockingQueue;
8 |
9 | public class ByteBufferMgr {
10 |
11 | protected List list = null;
12 |
13 | protected Queue queue = null;
14 |
15 | protected int size;
16 |
17 | protected final Object lock = new Object();
18 |
19 | public ByteBufferMgr(int size) {
20 | super();
21 | this.size = size;
22 | this.queue = new LinkedBlockingQueue();
23 | this.list = new ArrayList();
24 | }
25 |
26 | public ByteBuffer pinBuffer(){
27 | ByteBuffer buffer = null;
28 |
29 | buffer = this.queue.poll();
30 |
31 | if(null == buffer){
32 | buffer = ByteBuffer.allocate(this.size);
33 | this.list.add(buffer);
34 | }
35 |
36 | return buffer;
37 | }
38 |
39 | public void unpinBuffer(ByteBuffer buffer){
40 |
41 | if(null != buffer){
42 | this.queue.add(buffer);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/tenndb/data/Colunm.java:
--------------------------------------------------------------------------------
1 | package tenndb.data;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import tenndb.common.ByteUtil;
7 |
8 | public class Colunm {
9 |
10 | protected String key;
11 |
12 | protected int hashCode;
13 | protected int len;
14 | protected int version;
15 | protected List fileds;
16 |
17 | protected int time;
18 |
19 | public Colunm(String key, int version) {
20 | super();
21 | this.key = key;
22 | this.hashCode = hashCode(key);
23 | this.version = version;
24 | this.fileds = new ArrayList();
25 | this.len = 0;
26 |
27 | this.addFiled(new Filed("key", key));
28 | }
29 |
30 | public static final int hashCode(String value){
31 | int hashCode = 0;
32 | if(null != value && value.length() > 0){
33 | hashCode = value.hashCode();
34 | }
35 | return hashCode;
36 | }
37 |
38 | public int getTime() {
39 | return time;
40 | }
41 |
42 | public void setTime(int time) {
43 | this.time = time;
44 | }
45 |
46 | public int getLen(){
47 | return len;
48 | }
49 |
50 | public int getVersion() {
51 | return version;
52 | }
53 |
54 | public int getHashCode(){
55 | return this.hashCode;
56 | }
57 |
58 | public String getKey() {
59 | if(null == this.key && this.fileds.size() > 0){
60 | this.key = this.fileds.get(0).getValue();
61 | }
62 | return key;
63 | }
64 |
65 | public void addFiled(Filed filed){
66 | if(null != filed){
67 | this.len += ByteUtil.SHORT_SIZE;
68 | String value = filed.getValue();
69 | if(null != value && value.length() > 0){
70 | this.len += value.length();
71 | }
72 | fileds.add(filed);
73 | }
74 | }
75 |
76 | public final List getFileds() {
77 | return fileds;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/tenndb/data/DBBlock.java:
--------------------------------------------------------------------------------
1 | package tenndb.data;
2 |
3 | import java.util.List;
4 |
5 | import tenndb.common.ByteUtil;
6 |
7 |
8 | public class DBBlock {
9 |
10 | //head
11 | protected int pageID;
12 |
13 | protected int offset;
14 |
15 | //body
16 | protected PageBuffer page = null;
17 |
18 | public static final int HEAD_SIZE = ByteUtil.INT_SIZE + ByteUtil.SHORT_SIZE + ByteUtil.SHORT_SIZE;
19 |
20 | public DBBlock(PageBuffer page){
21 | this.page = page;
22 | }
23 |
24 | public int getTableID(){
25 | int tableID = 0;
26 | if(null != this.page){
27 | tableID = this.page.getTableID();
28 | }
29 | return tableID;
30 | }
31 |
32 | public String getTableName(){
33 | String tableName = null;
34 |
35 | if(null != this.page){
36 | tableName = this.page.getTableName();
37 | }
38 |
39 | return tableName;
40 | }
41 |
42 | public Colunm getColunm(){
43 | Colunm colunm = null;
44 | int version = 0;
45 | int length = 0;
46 | int key = 0;
47 |
48 | synchronized(this.page){
49 | // this.page.buffer.rewind();
50 | this.page.buffer.position(DBPage.HEAD_SIZE + this.offset);
51 |
52 | key = this.page.buffer.getInt();
53 |
54 | version = this.page.buffer.getShort();
55 | if(version < 0){
56 | version += ByteUtil.SHORT_MAX_VALUE;
57 | }
58 |
59 | length = this.page.buffer.getShort();
60 | if(length < 0){
61 | length += ByteUtil.SHORT_MAX_VALUE;
62 | }
63 |
64 | int total = length;
65 | int index = 0;
66 |
67 |
68 | while(total > 0){
69 | int len = this.page.buffer.getShort();
70 | if(len < 0){
71 | len += ByteUtil.SHORT_MAX_VALUE;
72 | }
73 |
74 | if(len > 0){
75 | byte[] buff = new byte[len];
76 | this.page.buffer.get(buff);
77 | String value = new String(buff);
78 |
79 | if(0 == index){
80 | colunm = new Colunm(value, version);
81 | }else{
82 | Filed filed = new Filed("filed_" + index, value);
83 | colunm.fileds.add(filed);
84 | }
85 | }
86 |
87 | total -= (ByteUtil.SHORT_SIZE + len);
88 | index++;
89 | }
90 | }
91 |
92 | colunm.len = length;
93 | return colunm;
94 | }
95 |
96 | public void setColunm(Colunm colunm){
97 | if(null != colunm ){
98 | this.setVar(colunm.hashCode, colunm.version, colunm.len, colunm.fileds);
99 | }
100 | }
101 |
102 | public void setVar(int hashCode, int version, byte[] buff, int offset, int len){
103 |
104 | if(null != buff && buff.length > 0 && len > 0 && offset >= 0 && (offset + len) <= buff.length){
105 |
106 | synchronized(this.page){
107 | // this.page.buffer.rewind();
108 | this.page.buffer.limit(DBPage.HEAD_SIZE + this.offset + DBBlock.HEAD_SIZE + len);
109 | this.page.buffer.position(DBPage.HEAD_SIZE + this.offset);
110 | //dword key
111 | //word version
112 | //word len
113 | //byte[] buff
114 | this.page.buffer.putInt(hashCode);
115 | byte[] vers = ByteUtil.shortToByte2_big(version);
116 | this.page.buffer.put(vers);
117 |
118 | byte[] lens = ByteUtil.shortToByte2_big(len);
119 | this.page.buffer.put(lens);
120 |
121 | this.page.buffer.put(buff, offset, len);
122 | }
123 | }
124 | }
125 |
126 | public void setVar(int hashCode, int version, int len, List fileds){
127 |
128 | if(null != fileds && version >= 0){
129 |
130 | synchronized(this.page){
131 | // this.page.buffer.rewind();
132 | this.page.buffer.limit(DBPage.HEAD_SIZE + this.offset + DBBlock.HEAD_SIZE + len);
133 | this.page.buffer.position(DBPage.HEAD_SIZE + this.offset);
134 | //dword key
135 | //word version
136 | //word len
137 | //word filed1_len
138 | //word filed1_buff
139 | //word filed2_len
140 | //word filed2_buff
141 | this.page.buffer.putInt(hashCode);
142 |
143 | byte[] vers = ByteUtil.shortToByte2_big(version);
144 | this.page.buffer.put(vers);
145 |
146 | byte[] lens = ByteUtil.shortToByte2_big(len);
147 | this.page.buffer.put(lens);
148 |
149 | int total = 0;
150 | for(int i = 0; i < fileds.size(); ++i){
151 | Filed filed = fileds.get(i);
152 | if(null != filed.value){
153 | byte[] buff = filed.value.getBytes();
154 | if(null != buff && buff.length > 0){
155 | total += (ByteUtil.SHORT_SIZE + buff.length);
156 | if(total <= ByteUtil.SHORT_MAX_VALUE){
157 |
158 | byte[] itemsize = ByteUtil.shortToByte2_big(buff.length);
159 |
160 | this.page.buffer.put(itemsize, 0, itemsize.length);
161 | this.page.buffer.put(buff, 0, buff.length);
162 | }else{
163 | total -= (ByteUtil.SHORT_SIZE + buff.length);
164 | break;
165 | }
166 | }
167 | }
168 | }
169 | }
170 | }
171 | }
172 |
173 | public PageBuffer getPage() {
174 | return page;
175 | }
176 |
177 | public int getPageID() {
178 | return pageID;
179 | }
180 |
181 | public void setPageID(int pageID) {
182 | this.pageID = pageID;
183 | }
184 |
185 | public int getOffset() {
186 | return offset;
187 | }
188 |
189 | public void setOffset(int offset) {
190 | this.offset = offset;
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/src/tenndb/data/DBPage.java:
--------------------------------------------------------------------------------
1 | package tenndb.data;
2 |
3 | import tenndb.common.ByteUtil;
4 |
5 |
6 | public class DBPage {
7 |
8 | // public static final int MAX_BLOCK_SIZE = 10;
9 |
10 |
11 |
12 | //len
13 | // public static final int BLOCK_HEAD_SIZE = INT_SIZE;
14 | //data
15 | // public static final int BLOCK_BODY_SIZE = INT_SIZE * 24;
16 |
17 | // public static final int BLOCK_SIZE = BLOCK_HEAD_SIZE + BLOCK_BODY_SIZE;
18 |
19 | //(num,key,data) x86: (1 + 4 + 40)*20=900
20 |
21 | //pageid + size
22 | public static final int HEAD_SIZE = 0;//INT_SIZE + INT_SIZE ;
23 | // public static final int BLOCK_SIZE = ByteUtil.INT_SIZE;
24 |
25 | public static final int PAGE_SIZE = 1024 * 40;
26 | //HEAD_SIZE +
27 | //(key + offset)*BALANCE_SIZE 48
28 | // BLOCK_SIZE * MAX_BLOCK_SIZE;
29 |
30 |
31 | public static final int MAX_BLOCK_SIZE = ByteUtil.SHORT_MAX_VALUE;
32 |
33 | protected static final int NEW_PAGES_SIZE = 10;
34 |
35 | protected static final int PAGE_INDEX_SIZE = ByteUtil.INT_SIZE + ByteUtil.INT_SIZE;
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/tenndb/data/DBPageMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.data;
2 |
3 | import tenndb.common.FileMgr;
4 |
5 | public class DBPageMgr {
6 |
7 | protected PageBufferMgr pageMgr = null;
8 |
9 | protected String dbName;
10 |
11 | protected FileMgr fileMgr = null;
12 |
13 | protected final Object lock = new Object();
14 |
15 | public DBPageMgr(String dbName, FileMgr fileMgr){
16 | this.dbName = dbName;
17 | this.fileMgr = fileMgr;
18 |
19 | this.pageMgr = new PageBufferMgr(this.dbName, fileMgr);
20 | }
21 |
22 | public void load(){
23 | this.pageMgr.load();
24 | }
25 |
26 | public void flush(){
27 | this.pageMgr.flushPage();
28 | this.pageMgr.flushData();
29 | }
30 |
31 | public PageBuffer getPageBuffer(int pageID){
32 | PageBuffer buffer = null;
33 |
34 | buffer = this.pageMgr.getPageBuffer(pageID);
35 |
36 | return buffer;
37 | }
38 |
39 | public synchronized DBBlock getDBBlock(int pageID, int offset){
40 | DBBlock blk = null;
41 | // System.out.println("getDBBlock.1");
42 | PageBuffer buffer = this.getPageBuffer(pageID);
43 | if(null != buffer){
44 | // System.out.println("getDBBlock.2");
45 | blk = buffer.getBlock(offset);
46 | }else{
47 | // System.out.println("getDBBlock.3");
48 | }
49 |
50 | return blk;
51 | }
52 |
53 | public DBBlock nextDBBlock(int hashCode, int version, byte[] buff, int offset, int len){
54 | DBBlock blk = null;
55 |
56 | if(null != buff && buff.length > 0 && offset >= 0 && len > 0 && (offset + len) <= buff.length){
57 | blk = this.pageMgr.nextBlock(hashCode, version, buff, offset, len);
58 | }
59 |
60 | return blk;
61 | }
62 |
63 | public DBBlock nextDBBlock(Colunm colunm){
64 |
65 | return this.pageMgr.nextBlock(colunm);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/tenndb/data/Filed.java:
--------------------------------------------------------------------------------
1 | package tenndb.data;
2 |
3 | public class Filed {
4 |
5 | public static final byte BYTE = 1;
6 | public static final byte WORD = 2;
7 | public static final byte DWORD = 4;
8 | public static final byte LWORD = 8;
9 |
10 | protected byte type;
11 | protected String name;
12 | protected String value;
13 |
14 | public Filed(String name, String value) {
15 | super();
16 | this.name = name;
17 | this.value = value;
18 | }
19 | public String getName() {
20 | return name;
21 | }
22 | public String getValue() {
23 | return value;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/tenndb/data/PageBuffer.java:
--------------------------------------------------------------------------------
1 | package tenndb.data;
2 |
3 | import java.nio.ByteBuffer;
4 |
5 | import tenndb.common.SystemTime;
6 |
7 |
8 | public class PageBuffer {
9 |
10 | protected int pageID;
11 |
12 | protected int offset;
13 |
14 | protected int size;
15 |
16 | protected ByteBuffer buffer = null;
17 |
18 | protected int tableID;
19 |
20 | protected String tableName;
21 |
22 | protected int tick;
23 |
24 | public PageBuffer(String tableName){
25 | this.pageID = 0;
26 | this.offset = 0;
27 | this.tableName = tableName;
28 | this.size = DBPage.PAGE_SIZE;
29 | this.tableID = 0;
30 | this.tick = SystemTime.getSystemTime().currentTime();
31 | }
32 |
33 | public String getTableName(){
34 | return this.tableName;
35 | }
36 |
37 | public int getTableID(){
38 | return this.tableID;
39 | }
40 |
41 | public int getPageID() {
42 | return this.pageID;
43 | }
44 |
45 | public void setPageID(int pageID) {
46 | this.pageID = pageID;
47 | }
48 |
49 | public int getOffset() {
50 | return this.offset;
51 | }
52 |
53 | public int getSize() {
54 | return size;
55 | }
56 |
57 | public boolean isfull(int len){
58 | return (this.offset + DBBlock.HEAD_SIZE + len) > this.size;
59 | }
60 |
61 | public DBBlock nextBlock(int hashCode, int version, byte[] buff, int offset, int len){
62 | DBBlock blk = null;
63 | if(null != buff && buff.length > 0 && (this.offset + DBBlock.HEAD_SIZE + len) <= this.size){
64 | synchronized(this){
65 | try{
66 | blk = this.getBlock(this.offset);
67 | blk.setVar(hashCode, version, buff, offset, len);
68 | this.offset += (DBBlock.HEAD_SIZE + len);
69 | }catch(Exception e){
70 | System.out.println("nextBlock.1 " + e + " " + this.buffer.capacity() + " " + this.buffer.limit() + " " + this.buffer.position() + " " + this.size + ", " + this.offset + ", " + len);
71 | }
72 | }
73 | }
74 |
75 | return blk;
76 | }
77 |
78 | public DBBlock nextBlock(Colunm colunm){
79 | DBBlock blk = null;
80 | if((this.offset + DBBlock.HEAD_SIZE + colunm.len) <= this.size){
81 | try{
82 | blk = this.getBlock(this.offset);
83 | blk.setColunm(colunm);
84 | this.offset += (DBBlock.HEAD_SIZE + colunm.len);
85 | }catch(Exception e){
86 | System.out.println("nextBlock.2 " + e + " " + this.buffer.capacity() + " " + this.buffer.limit() + " " + this.buffer.position() + " " + this.size + ", " + this.offset + ", " + colunm.len);
87 | }
88 | }
89 | return blk;
90 | }
91 |
92 | public void setBlock(Colunm colunm, int offset){
93 | DBBlock block = this.getBlock(offset);
94 |
95 | if(null != block){
96 | block.setColunm(colunm);
97 | }
98 | }
99 |
100 | public Colunm getColunm(int offset){
101 | Colunm colunm = null;;
102 | DBBlock blk = this.getBlock(offset);
103 | if(null != blk){
104 | colunm = blk.getColunm();
105 | }
106 | return colunm;
107 | }
108 |
109 | public DBBlock getBlock(int offset){
110 | DBBlock blk = null;
111 | // System.out.println("getBlock " + offset + ", " + this.size + ", " + this.pageID);
112 | if(offset < this.size){
113 | blk = new DBBlock(this);
114 | blk.setOffset(offset);
115 | blk.setPageID(this.pageID);
116 | this.tick = SystemTime.getSystemTime().currentTime();
117 | }
118 |
119 | return blk;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/tenndb/data/PageBufferMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.data;
2 |
3 |
4 | import java.io.IOException;
5 | import java.nio.ByteBuffer;
6 | import java.util.ArrayList;
7 | import java.util.HashMap;
8 | import java.util.List;
9 | import java.util.Map;
10 | import java.util.Queue;
11 | import java.util.concurrent.ConcurrentHashMap;
12 | import java.util.concurrent.ConcurrentMap;
13 | import java.util.concurrent.LinkedBlockingDeque;
14 | import java.util.concurrent.locks.ReadWriteLock;
15 | import java.util.concurrent.locks.ReentrantReadWriteLock;
16 |
17 | import tenndb.common.FileDeco;
18 | import tenndb.common.FileMgr;
19 |
20 | public class PageBufferMgr {
21 |
22 | protected String dbName = null;
23 |
24 | protected Map unusedMap = null;
25 |
26 | protected Queue unusedQueue = null;
27 |
28 | protected List usedList = null;
29 |
30 | protected ConcurrentMap pageMap = null;
31 |
32 | protected FileMgr fileMgr = null;
33 |
34 | protected ByteBufferMgr bufMgr = null;
35 |
36 | // protected final Object lock = new Object();
37 |
38 | protected static final String PREFIX_UNUSED_PAGE = "unused_page_";
39 |
40 | protected static final String PREFIX_DATA = "data_";
41 |
42 |
43 | protected ReadWriteLock lock = new ReentrantReadWriteLock(false);
44 |
45 | public void RLock() { this.lock.readLock().lock(); }
46 |
47 | public void URLock() { this.lock.readLock().unlock(); }
48 |
49 | public void WLock() { this.lock.writeLock().lock(); }
50 |
51 | public void UWLock() { this.lock.writeLock().unlock(); }
52 |
53 |
54 | public PageBufferMgr(String dbName, FileMgr fileMgr){
55 | this.dbName = dbName;
56 | this.fileMgr = fileMgr;
57 |
58 | this.unusedQueue = new LinkedBlockingDeque();
59 | this.usedList = new ArrayList();
60 | this.pageMap = new ConcurrentHashMap();
61 | this.unusedMap = new HashMap();
62 | this.bufMgr = new ByteBufferMgr(DBPage.PAGE_SIZE);
63 | }
64 |
65 | protected DBBlock getBlock(int hashCode, int version, byte[] buff, int offset, int len){
66 | DBBlock blk = null;
67 |
68 | this.RLock();
69 |
70 | PageBuffer page = this.unusedQueue.peek();
71 |
72 | if(null != page){
73 |
74 | if(page.isfull(len)){
75 |
76 | this.URLock();
77 | this.WLock();
78 |
79 | PageBuffer full = this.unusedQueue.poll();
80 | this.usedList.add(full);
81 | this.unusedMap.remove(page.pageID);
82 | page = this.unusedQueue.peek();
83 |
84 | this.UWLock();
85 | this.RLock();
86 | }
87 |
88 | if(null != page){
89 | blk = page.nextBlock(hashCode, version, buff, offset, len);
90 | }
91 | }
92 |
93 | this.URLock();
94 | return blk;
95 | }
96 |
97 | protected DBBlock getBlock(Colunm colunm){
98 | DBBlock blk = null;
99 |
100 | this.RLock();
101 |
102 | PageBuffer page = this.unusedQueue.peek();
103 |
104 | if(null != page){
105 |
106 | if(page.isfull(colunm.len)){
107 |
108 | this.URLock();
109 | this.WLock();
110 |
111 | PageBuffer full = this.unusedQueue.poll();
112 | this.usedList.add(full);
113 | this.unusedMap.remove(page.pageID);
114 | page = this.unusedQueue.peek();
115 |
116 | this.UWLock();
117 | this.RLock();
118 | }
119 |
120 | if(null != page){
121 | blk = page.nextBlock(colunm);
122 | }
123 | }
124 |
125 | this.URLock();
126 | return blk;
127 | }
128 |
129 | public DBBlock nextBlock(int hashCode, int version, byte[] buff, int offset, int len){
130 | DBBlock blk = null;
131 | if(null != buff && buff.length > 0 && (len + DBBlock.HEAD_SIZE) <= DBPage.MAX_BLOCK_SIZE){
132 | blk = this.getBlock(hashCode, version, buff, offset, len);
133 |
134 | if(null == blk){
135 | this.apppend();
136 | blk = this.getBlock(hashCode, version, buff, offset, len);
137 | }
138 | }
139 |
140 | return blk;
141 | }
142 |
143 | public DBBlock nextBlock(Colunm colunm){
144 | DBBlock blk = null;
145 | if(colunm.len > 0 && (colunm.len + DBBlock.HEAD_SIZE) <= DBPage.MAX_BLOCK_SIZE){
146 | blk = this.getBlock(colunm);
147 |
148 | if(null == blk){
149 | this.apppend();
150 | blk = this.getBlock(colunm);
151 | }
152 | }
153 |
154 | return blk;
155 | }
156 |
157 | public void flushData(){
158 | this.RLock();
159 |
160 | PageBuffer page = this.unusedQueue.peek();
161 | if(null != page){
162 | this.setPageBuffer(page);
163 | }
164 |
165 | if(usedList.size() > 0){
166 | for(int i = 0; i < usedList.size(); ++i){
167 | PageBuffer buffer = usedList.get(i);
168 | this.setPageBuffer(buffer);
169 |
170 | this.pageMap.remove(buffer.pageID);
171 | }
172 |
173 | usedList.clear();
174 | }
175 |
176 | this.URLock();
177 | }
178 |
179 | public void flushPage(){
180 | this.RLock();
181 |
182 | List unusedList = new ArrayList();
183 | if(this.unusedMap.size() > 0){
184 |
185 | for(Integer pageID : this.unusedMap.keySet()){
186 |
187 | PageBuffer buffer = this.unusedMap.get(pageID);
188 |
189 | PageUnusedIndex index = new PageUnusedIndex();
190 | index.pageID = buffer.pageID;
191 | index.offset = buffer.offset;
192 | unusedList.add(index);
193 | }
194 | }
195 |
196 | if(null != unusedList && unusedList.size() > 0){
197 | FileDeco fd = null;
198 | try {
199 | fd = this.fileMgr.pinFileChannel(PREFIX_UNUSED_PAGE + this.dbName);
200 | if(null != fd){
201 | fd.getFileChannel().position(0);
202 |
203 | ByteBuffer buffer = ByteBuffer.allocate(DBPage.PAGE_INDEX_SIZE * unusedList.size());
204 | buffer.rewind();
205 | for(int i = 0; i < unusedList.size(); ++i){
206 | PageUnusedIndex index = unusedList.get(i);
207 | buffer.putInt(index.pageID);
208 | buffer.putInt(index.offset);
209 | }
210 |
211 | buffer.flip();
212 | fd.getFileChannel().position(0);
213 |
214 | while(buffer.hasRemaining()) {
215 | fd.getFileChannel().write(buffer);
216 | }
217 | }
218 | } catch (IOException e) {
219 | e.printStackTrace();
220 | } finally{
221 | if(null != fd){
222 | this.fileMgr.closeFileChannel(fd);
223 | }
224 | }
225 | }
226 |
227 | this.URLock();
228 | }
229 |
230 | public void load(){
231 |
232 | List unusedList = new ArrayList();
233 |
234 | FileDeco fd = null;
235 | try {
236 | fd = this.fileMgr.pinFileChannel(PREFIX_UNUSED_PAGE + this.dbName);
237 | if(null != fd){
238 | int len = (int) fd.getFileChannel().size();
239 | ByteBuffer buffer = ByteBuffer.allocate(len);
240 | int size = fd.getFileChannel().read(buffer);
241 | int limit = size / DBPage.PAGE_INDEX_SIZE;
242 | for(int i = 0; i < limit; ++i){
243 | int pageID = buffer.getInt(i * DBPage.PAGE_INDEX_SIZE);
244 | int offset = buffer.getInt(i * DBPage.PAGE_INDEX_SIZE + 4);
245 |
246 | PageUnusedIndex blk = new PageUnusedIndex();
247 | blk.pageID = pageID;
248 | blk.offset = offset;
249 |
250 | if(!this.unusedMap.containsKey(blk.pageID)){
251 | unusedList.add(blk);
252 | }
253 | }
254 | }
255 | } catch (IOException e) {
256 | e.printStackTrace();
257 | } finally{
258 | if(null != fd){
259 | this.fileMgr.closeFileChannel(fd);
260 | }
261 | }
262 |
263 | if(null != unusedList && unusedList.size() > 0){
264 | for(int i = 0; i < unusedList.size(); ++i){
265 | PageUnusedIndex index = unusedList.get(i);
266 | PageBuffer buff = this.getPageBuffer(index.pageID);
267 | if(null != buff){
268 | buff.offset = index.offset;
269 | this.unusedQueue.add(buff);
270 | this.unusedMap.put(buff.pageID, buff);
271 | }
272 | }
273 | }
274 | }
275 |
276 | public void setPageBuffer(PageBuffer buffer){
277 | if(null != buffer){
278 | FileDeco fd = null;
279 | try {
280 | fd = this.fileMgr.pinFileChannel(PREFIX_DATA + this.dbName);
281 |
282 | if (null != fd && null != fd.getFileChannel() && fd.getFileChannel().isOpen()) {
283 | int limit = (int) (fd.getFileChannel().size()/DBPage.PAGE_SIZE);
284 |
285 | if (buffer.pageID < limit) {
286 | buffer.buffer.flip();
287 | int read = fd.getFileChannel().write(buffer.buffer, buffer.pageID * DBPage.PAGE_SIZE);
288 | if (DBPage.PAGE_SIZE == read) {
289 |
290 | }
291 | }
292 | }
293 | } catch (IOException e) {
294 | System.out.println(e);
295 | if (null != fd) {
296 | this.fileMgr.closeFileChannel(fd);
297 | }
298 | }
299 | }
300 | }
301 |
302 | public PageBuffer getPageBuffer(int pageID) {
303 | PageBuffer buffer = null;
304 |
305 | buffer = this.pin(pageID);
306 |
307 | if (null == buffer) {
308 |
309 | FileDeco fd = null;
310 | try {
311 | fd = this.fileMgr.pinFileChannel(PREFIX_DATA + this.dbName);
312 |
313 | if (null != fd && null != fd.getFileChannel() && fd.getFileChannel().isOpen()) {
314 | int limit = (int) (fd.getFileChannel().size()/DBPage.PAGE_SIZE);
315 |
316 | if (pageID <= limit) {
317 | PageBuffer pageBuffer = new PageBuffer(this.dbName);
318 | pageBuffer.pageID = pageID;
319 | pageBuffer.buffer = this.bufMgr.pinBuffer();
320 |
321 | int read = fd.getFileChannel().read(pageBuffer.buffer, pageID * DBPage.PAGE_SIZE);
322 | if (DBPage.PAGE_SIZE == read) {
323 | this.put(pageBuffer);
324 | buffer = pageBuffer;
325 | }
326 | }
327 | }
328 | } catch (IOException e) {
329 | System.out.println(e);
330 | if (null != fd) {
331 | this.fileMgr.closeFileChannel(fd);
332 | }
333 | }
334 | }
335 |
336 | return buffer;
337 | }
338 |
339 | public void apppend(){
340 |
341 | FileDeco fd = null;
342 | try {
343 | fd = this.fileMgr.pinFileChannel(PREFIX_DATA + this.dbName);
344 |
345 | if(null != fd){
346 | // long size0 = fd.getFileChannel().size();
347 | int pos = (int)(fd.getFileChannel().size()/DBPage.PAGE_SIZE) ;
348 |
349 | // System.out.println(size0 + ", " + size0/DBPage.PAGE_SIZE + ", " + size0 % DBPage.PAGE_SIZE );
350 |
351 | // System.out.println(key + ", append.1, size = " + fd.getFileChannel().size() + ", pos = " + pos);
352 | ByteBuffer[] array = new ByteBuffer[DBPage.NEW_PAGES_SIZE];
353 | List newBuffList = new ArrayList();
354 | for(int i = 0; i < DBPage.NEW_PAGES_SIZE; ++i){
355 | PageBuffer pageBuffer = new PageBuffer(this.dbName);
356 | pageBuffer.pageID = pos + i;
357 | pageBuffer.buffer = this.bufMgr.pinBuffer();
358 |
359 | pageBuffer.buffer.rewind();
360 | // pageBuffer.buffer.putInt(0, pageBuffer.pageID);
361 | // pageBuffer.buffer.putInt(4, 0);
362 |
363 | array[i] = pageBuffer.buffer;
364 | newBuffList.add(pageBuffer);
365 | }
366 |
367 | fd.getFileChannel().position(fd.getFileChannel().size());
368 |
369 | long size = fd.getFileChannel().write(array, 0, DBPage.NEW_PAGES_SIZE);
370 | // System.out.println(key + ", append.2, size = " + size);
371 | if(size == DBPage.NEW_PAGES_SIZE * DBPage.PAGE_SIZE){
372 |
373 | // System.out.println(key + ", append.3, size = " + this.unusedQueue.size());
374 |
375 | for(int i = 0; i < newBuffList.size(); ++i){
376 | PageBuffer page = newBuffList.get(i);
377 | this.put(page);
378 | this.unusedMap.put(page.pageID, page);
379 | this.unusedQueue.add(page);
380 | }
381 | }
382 | }
383 | } catch (IOException e) {
384 | System.out.println(e);
385 | if(null != fd){
386 | this.fileMgr.closeFileChannel(fd);
387 | }
388 | }
389 | }
390 |
391 | public void put(PageBuffer buffer){
392 | this.pageMap.put(buffer.pageID, buffer);
393 | }
394 |
395 | public PageBuffer pin(int pageID){
396 | return this.pageMap.get(pageID);
397 | }
398 |
399 | public PageBuffer unpin(int pageID){
400 | return this.pageMap.remove(pageID);
401 | }
402 | }
403 |
--------------------------------------------------------------------------------
/src/tenndb/data/PageUnusedIndex.java:
--------------------------------------------------------------------------------
1 | package tenndb.data;
2 |
3 | public class PageUnusedIndex {
4 |
5 | protected int pageID;
6 | protected int offset;
7 |
8 | public PageUnusedIndex(){
9 | this.pageID = 0;
10 | this.offset = 0;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/tenndb/dist/DistMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.dist;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Queue;
6 | import java.util.concurrent.LinkedBlockingDeque;
7 | import java.util.concurrent.atomic.AtomicInteger;
8 | import java.util.concurrent.locks.ReadWriteLock;
9 | import java.util.concurrent.locks.ReentrantReadWriteLock;
10 | import java.nio.ByteBuffer;
11 |
12 | import tenndb.common.ByteUtil;
13 | import tenndb.common.FileMgr;
14 | import tenndb.thread.DistThread;
15 |
16 | public class DistMgr {
17 |
18 | protected FileMgr fileMgr = null;
19 |
20 | protected Queue unusedQueue = null;
21 |
22 | protected List usedList = null;
23 |
24 | protected AtomicInteger counter = null;
25 |
26 | protected static final int MAX_PAGE_NUM = 3;
27 |
28 | protected static final int MAX_QUEUE_SIZE = ByteUtil.SHORT_MAX_VALUE - ByteUtil.BYTE_MAX_VALUE;
29 |
30 | public static final String DIST_PATH = System.getProperty("file.separator") + "dist_data";
31 |
32 | public static final String PREFIX_TEMP = "temp_";
33 |
34 | public static final String PREFIX_DELETE = "delete_";
35 |
36 | public static final String PREFIX_QUEUE = "queue_";
37 |
38 | public static final byte TAG_DATA = 1;
39 | public static final byte TAG_NULL = 0;
40 |
41 | protected DistThread distThread = null;
42 |
43 | protected final ReadWriteLock lock = new ReentrantReadWriteLock(false);
44 |
45 | protected volatile boolean initialized = false;
46 |
47 |
48 | public DistMgr(String root){
49 |
50 | this.fileMgr = new FileMgr(root + DIST_PATH);
51 | this.unusedQueue = new LinkedBlockingDeque();
52 | this.usedList = new ArrayList();
53 |
54 | this.counter = new AtomicInteger(1);
55 | }
56 |
57 | public void init(){
58 | if(false == this.initialized){
59 | try{
60 | this.lockWrite();
61 | if(false == this.initialized){
62 | this.distThread = new DistThread(this);
63 | this.distThread.start();
64 | this.initialized = true;
65 | }
66 | }catch(Exception e){
67 | System.out.println(e);
68 | }finally{
69 | this.unLockWrite();
70 | }
71 | }
72 | }
73 |
74 | public void flush(DistPage page, String fileName){
75 | if(null != page && null != page.buffer && page.buffer.limit() > 0){
76 | page.buffer.rewind();
77 | String tempFileName = PREFIX_TEMP + PREFIX_QUEUE + fileName;
78 | String newfileName = PREFIX_QUEUE + fileName;
79 |
80 | this.fileMgr.append(tempFileName, page.buffer);
81 | this.fileMgr.rename(tempFileName, newfileName);
82 | this.fileMgr.closeFileChannel(newfileName);
83 | page.clear();
84 |
85 | synchronized(this.lock){
86 | if(this.unusedQueue.size() < MAX_PAGE_NUM){
87 | this.unusedQueue.add(page);
88 | }
89 | }
90 | }
91 | }
92 |
93 | public String newFileName(){
94 | String fileName = null;
95 | int index = this.counter.getAndIncrement();
96 | if(index > MAX_QUEUE_SIZE){
97 | index = this.counter.getAndSet(1);
98 | }
99 | fileName = String.format("%04X", index);
100 | return fileName;
101 | }
102 |
103 |
104 | public List getAndClearUsedList(){
105 | List list = null;
106 | synchronized(this.lock){
107 | if(this.usedList.size() > 0){
108 | list = this.usedList;
109 | this.usedList = new ArrayList();
110 | }
111 | }
112 | return list;
113 | }
114 |
115 | protected DistPage pinDistPage(){
116 | DistPage page = this.unusedQueue.peek();
117 |
118 | if(null == page){
119 | ByteBuffer buff = ByteBuffer.allocate(DistPage.PAGE_SIZE);
120 | page = new DistPage(buff);
121 | this.unusedQueue.add(page);
122 | }
123 |
124 | return page;
125 | }
126 |
127 | public void write(List list){
128 | if(null != list && list.size() > 0){
129 | synchronized(this.lock){
130 | for(byte[] array : list){
131 |
132 | DistPage page = this.pinDistPage();
133 | boolean b = page.write(array);
134 | if(false == b){
135 | this.usedList.add(page);
136 | this.unusedQueue.poll();
137 | page = this.pinDistPage();
138 | b = page.write(array);
139 | }
140 | }
141 | }
142 | }
143 | }
144 |
145 | protected void lockRead() { this.lock.readLock().lock(); }
146 |
147 | protected void unLockRead() { this.lock.readLock().unlock(); }
148 |
149 | protected void lockWrite() { this.lock.writeLock().lock(); }
150 |
151 | protected void unLockWrite() { this.lock.writeLock().unlock(); }
152 | }
153 |
--------------------------------------------------------------------------------
/src/tenndb/dist/DistPage.java:
--------------------------------------------------------------------------------
1 | package tenndb.dist;
2 |
3 |
4 | import java.nio.ByteBuffer;
5 |
6 |
7 | public class DistPage {
8 | //
9 | // public static final int PAGE_SIZE = 1024 * 1000 * 10;
10 |
11 | public static final int PAGE_SIZE = 1024 * 400;
12 |
13 | protected ByteBuffer buffer;
14 |
15 | protected int limit;
16 |
17 | protected int offset;
18 |
19 | protected final Object lock = new Object();
20 |
21 | public DistPage(ByteBuffer buffer) {
22 | super();
23 | this.buffer = buffer;
24 | this.limit = PAGE_SIZE;
25 | this.offset = 0;
26 | }
27 |
28 | public ByteBuffer getBuffer() {
29 | return buffer;
30 | }
31 |
32 | public void clear(){
33 | this.offset = 0;
34 | this.buffer.clear();
35 | }
36 |
37 | public boolean write(byte[] buff){
38 | boolean b = false;
39 |
40 | if(null != buff && buff.length > 0){
41 | synchronized(this.lock){
42 | if(this.offset + buff.length < this.limit){
43 | this.buffer.position(this.offset);
44 | this.buffer.put(buff);
45 | this.offset += buff.length;
46 | b = true;
47 | }
48 | }
49 | }
50 |
51 | return b;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/tenndb/disttest/DemoThread.java:
--------------------------------------------------------------------------------
1 | package tenndb.disttest;
2 |
3 | import java.nio.ByteBuffer;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import tenndb.common.SystemTime;
8 | import tenndb.dist.DistMgr;
9 |
10 | public class DemoThread extends Thread {
11 |
12 | protected int devID;
13 | protected DistMgr distMgr;
14 |
15 | public DemoThread(int devID, DistMgr distMgr) {
16 | super();
17 | this.devID = devID;
18 | this.distMgr = distMgr;
19 | }
20 | protected static int SIZE = 100;
21 |
22 | public void run(){
23 | int time = SystemTime.getSystemTime().currentTime();
24 | List list = new ArrayList();
25 | ByteBuffer buffer = ByteBuffer.allocate(25);
26 |
27 | for(int i = 0; i < SIZE; ++i){
28 | byte[] array = new byte[25];
29 | list.add(array);
30 | }
31 |
32 | while(true){
33 | try{
34 | int lng = 1200000000;
35 | int lat = 300000000;
36 |
37 | for(int i = 0; i < SIZE; ++i){
38 | time++;
39 | String strDevID = String.valueOf(this.devID);
40 | byte[] devIDArray = new byte[10];
41 | byte[] temp = strDevID.getBytes();
42 | System.arraycopy(temp, 0, devIDArray, 0, 10);
43 |
44 | buffer.clear();
45 | buffer.rewind();
46 | buffer.put(DistMgr.TAG_DATA);
47 | buffer.put(devIDArray); //10
48 | buffer.putInt(time); //4
49 | buffer.putShort((short) 8); //2
50 | buffer.putInt(lng + i); //4
51 | buffer.putInt(lat + i); //4
52 |
53 | byte[] array = list.get(i);
54 | System.arraycopy(buffer.array(), 0, array, 0, array.length);
55 | }
56 |
57 | this.distMgr.write(list);
58 |
59 | }catch(Exception e){
60 | System.out.println(e);
61 | }finally{
62 | try {
63 | Thread.sleep(100);
64 | } catch (InterruptedException e) {
65 | e.printStackTrace();
66 | }
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/tenndb/disttest/Test.java:
--------------------------------------------------------------------------------
1 | package tenndb.disttest;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import tenndb.dist.DistMgr;
7 | import tenndb.route.RouteMgr;
8 |
9 | public class Test {
10 |
11 | /**
12 | * @param args
13 | */
14 | public static void main(String[] args) {
15 |
16 | DistMgr distMgr = new DistMgr("J:\\tennbase");
17 | distMgr.init();
18 |
19 | RouteMgr routeMgr = new RouteMgr("J:\\tennbase");
20 | routeMgr.init();
21 |
22 | int devID = 1607140000;
23 | List list = new ArrayList();
24 |
25 | for(int i = 0; i < 20; ++i){
26 | DemoThread thread = new DemoThread(devID + i, distMgr);
27 | list.add(thread);
28 | }
29 |
30 | for(DemoThread thread : list){
31 | thread.start();
32 | }
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/tenndb/disttest/TestDist.java:
--------------------------------------------------------------------------------
1 | package tenndb.disttest;
2 |
3 | import tenndb.dist.DistMgr;
4 |
5 | public class TestDist {
6 |
7 | /**
8 | * @param args
9 | */
10 | public static void main(String[] args) {
11 |
12 | DistMgr distMgr = new DistMgr("J:\\tennbase");
13 | distMgr.init();
14 |
15 |
16 |
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/tenndb/disttest/TestFileName.java:
--------------------------------------------------------------------------------
1 | package tenndb.disttest;
2 |
3 | import java.io.File;
4 | import java.util.Date;
5 |
6 | public class TestFileName {
7 |
8 | /**
9 | * @param args
10 | */
11 | public static void main(String[] args) {
12 |
13 | String str = "1607140000";
14 | System.out.println(str.getBytes().length);
15 |
16 | /* for(int i = 0; i < 100; ++i){
17 | long time = new Date().getTime();
18 | time %= 1000;
19 | System.out.println(time + "," + String.format("%04X", time));
20 |
21 | }*/
22 |
23 | File dir = new File("J:\\tennbase\\dist_data");
24 |
25 | String[] files = dir.list();
26 |
27 | if(null != files){
28 | for(String file : files){
29 | System.out.println(file);
30 | }
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/tenndb/disttest/TestRoute.java:
--------------------------------------------------------------------------------
1 | package tenndb.disttest;
2 |
3 | import tenndb.dist.DistMgr;
4 | import tenndb.route.RouteMgr;
5 |
6 | public class TestRoute {
7 |
8 | /**
9 | * @param args
10 | */
11 | public static void main(String[] args) {
12 |
13 | RouteMgr routeMgr = new RouteMgr("J:\\tennbase");
14 | routeMgr.init();
15 |
16 | // DistMgr distMgr = new DistMgr("J:\\tennbase");
17 | // distMgr.init();
18 |
19 |
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/tenndb/index/IBTree.java:
--------------------------------------------------------------------------------
1 | package tenndb.index;
2 |
3 | import java.nio.ByteBuffer;
4 | import java.util.List;
5 |
6 | import tenndb.bstar.BTreeNode;
7 | import tenndb.bstar.IdxBlock;
8 | import tenndb.log.CellLogMgr;
9 | import tenndb.tx.AbortTransException;
10 | import tenndb.tx.Trans;
11 |
12 |
13 | public interface IBTree {
14 |
15 | public BTreeNode getRoot();
16 |
17 | public void print(List strList);
18 |
19 | public String toString();
20 |
21 | public void printNext();
22 |
23 | public void printTreePrior();
24 |
25 | public IdxBlock insert(int key, IdxBlock var, Trans tid, CellLogMgr logMgr) throws AbortTransException ;
26 |
27 | public IdxBlock update(int key, IdxBlock var, Trans tid, CellLogMgr logMgr) throws AbortTransException ;
28 |
29 | public IdxBlock delete(int key, Trans tid, CellLogMgr logMgr) throws AbortTransException ;
30 |
31 | public IdxBlock search(int key, Trans tid);
32 |
33 | public boolean rollback(int key, Trans tid, CellLogMgr logMgr);
34 |
35 | public boolean commit(int key, Trans tid, CellLogMgr logMgr);
36 |
37 | public BTreeNode seekNode(int key);
38 |
39 | public int count(int fromKey, int toKey);
40 |
41 | public List range(int fromKey, int toKey, boolean isInc);
42 |
43 | public void toByteBuffer(List list);
44 |
45 | }
--------------------------------------------------------------------------------
/src/tenndb/index/IndexMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.index;
2 |
3 | import java.io.IOException;
4 | import java.nio.ByteBuffer;
5 | import java.util.ArrayList;
6 | import java.util.HashSet;
7 | import java.util.Hashtable;
8 | import java.util.List;
9 | import java.util.Map;
10 | import java.util.Set;
11 | import java.util.concurrent.atomic.AtomicInteger;
12 |
13 | import tenndb.bstar.RandomInsertBStarTree;
14 | import tenndb.bstar.BTreeNode;
15 | import tenndb.bstar.IdxBlock;
16 | import tenndb.common.ByteUtil;
17 | import tenndb.common.FileDeco;
18 | import tenndb.common.FileMgr;
19 | import tenndb.data.ByteBufferMgr;
20 | import tenndb.tx.TransMgr;
21 |
22 | public class IndexMgr {
23 |
24 | protected IBTree tree = null;
25 |
26 | protected String dbName = null;
27 |
28 | protected FileMgr fileMgr = null;
29 |
30 | protected ByteBufferMgr bufferMgr = null;
31 |
32 | protected static final String PREFIX_TEMP_INDEX = "temp_index_";
33 |
34 | protected static final String PREFIX_SNAPSHOT_INDEX = "snapshot_index_";
35 |
36 | protected static final String PREFIX_INDEX = "index_";
37 |
38 | protected static final String PREFIX_BAK_INDEX = "bak_index_";
39 |
40 | protected int lastNodeID = -1;
41 |
42 | protected AtomicInteger counter = new AtomicInteger(1);
43 |
44 | protected Map pageMap = null;
45 |
46 | protected List blockList = null;
47 |
48 | protected Set newPageList = null;
49 |
50 | protected Set dirtyPageList = null;
51 |
52 | protected TransMgr transMgr = null;
53 |
54 |
55 |
56 |
57 | public IndexMgr(String dbName, FileMgr fileMgr, TransMgr transMgr) {
58 | super();
59 | this.dbName = dbName;
60 | this.tree = null;
61 | this.fileMgr = fileMgr;
62 | this.transMgr = transMgr;
63 | this.bufferMgr = new ByteBufferMgr(IndexPage.PAGE_SIZE);
64 | this.pageMap = new Hashtable();
65 | this.newPageList = new HashSet();
66 | this.dirtyPageList = new HashSet();
67 | this.blockList = new ArrayList();
68 | }
69 |
70 | public boolean flushBlock(IdxBlock blk){
71 | boolean b = false;
72 |
73 | if(null != blk){
74 | IndexPage page = this.pageMap.get(blk.getIdxPageID());
75 | if(null != page){
76 | long pos = page.pos + IndexPage.PAGE_HEAD_SIZE + IndexPage.PAGE_BLOCK_SIZE * blk.getIdxOffset();
77 | ByteBuffer buff = ByteBuffer.allocate(IndexPage.PAGE_BLOCK_SIZE);
78 | byte[] array = buff.array();
79 | // System.out.println("flushBlock " + pos);
80 | try {
81 | this.fileMgr.writeBuffer(PREFIX_SNAPSHOT_INDEX + this.dbName, array, pos);
82 | b = true;
83 | } catch (IOException e) {
84 | e.printStackTrace();
85 | }
86 | }
87 | }
88 | return b;
89 | }
90 |
91 | public IndexPage addIndexPage(BTreeNode node, ByteBuffer buffer){
92 | IndexPage page = null;
93 | if(null != node && null != buffer){
94 | page = new IndexPage(node, buffer);
95 | // System.out.println("pinIndexPage " + page.pageID());
96 | this.pageMap.put(page.pageID(), page);
97 | }
98 | return page;
99 | }
100 |
101 | public IndexPage appendNewIndexPage(BTreeNode newNode, BTreeNode oldNode){
102 | IndexPage newPage = null;
103 | if(null != newNode){
104 | int nodeID = this.nextNodeID();
105 | // System.out.println("appendNewIndexPage " + nodeID);
106 | newNode.setPageID(nodeID);
107 | ByteBuffer buffer = this.bufferMgr.pinBuffer();
108 | newPage = new IndexPage(newNode, buffer);
109 | newNode.setRefPage(newPage);
110 | this.pageMap.put(newPage.pageID(), newPage);
111 | this.newPageList.add(newPage.pageID());
112 | }
113 |
114 | if(null != oldNode){
115 | IndexPage oldPage = oldNode.getRefPage();
116 | // System.out.println("dirtyPageList.1 " + oldNode.getPageID());
117 | if(null != oldPage){
118 | // System.out.println("dirtyPageList.2 " + oldPage.pos + ", " + oldPage.pageID());
119 |
120 | this.dirtyPageList.add(oldPage.pageID());
121 | }
122 | }
123 | return newPage;
124 | }
125 |
126 | public boolean flushNewPages(){
127 | boolean b = false;
128 | if(this.newPageList.size() > 0){
129 | byte[] array = ByteUtil.intToByte4_big(this.counter.get());
130 | try {
131 | this.fileMgr.writeBuffer(PREFIX_SNAPSHOT_INDEX + this.dbName, array, 0);
132 | } catch (IOException e) {
133 | e.printStackTrace();
134 | }
135 |
136 | for(Integer pid : this.newPageList){
137 | IndexPage page = this.pageMap.get(pid);
138 | if(null != page){
139 | page.flush(this.tree.getRoot());
140 | long pos = this.fileMgr.append(PREFIX_SNAPSHOT_INDEX + this.dbName, page.buffer);
141 | page.setPos(pos);
142 | }
143 |
144 | // System.out.println("new " + page.pageID() + ", " + page.pos + ", " + page.node.isLeaf());
145 | }
146 |
147 | // this.tree.printTreeNext();
148 | // System.out.println("+++++++++++++++++++++++++++++++++++++++++++");
149 | this.newPageList.clear();
150 | b = true;
151 | }
152 |
153 | if(this.dirtyPageList.size() > 0){
154 | for(Integer pid : this.dirtyPageList){
155 |
156 | IndexPage page = this.pageMap.get(pid);
157 | if(null != page){
158 | page.flush(this.tree.getRoot());
159 | byte[] array = page.buffer.array();
160 | try {
161 | this.fileMgr.writeBuffer(PREFIX_SNAPSHOT_INDEX + this.dbName, array, page.pos);
162 | // System.out.println("old " + page.pageID() + ", " + page.pos + ", " + page.node.isLeaf());
163 | } catch (IOException e) {
164 | e.printStackTrace();
165 | }
166 | }
167 | }
168 |
169 | this.dirtyPageList.clear();
170 |
171 | b = true;
172 | }
173 |
174 | return b;
175 | }
176 |
177 | public IndexPage getPage(int pageID){
178 | return this.pageMap.get(pageID);
179 | }
180 |
181 | public int nextNodeID(){
182 | return this.counter.getAndIncrement();
183 | }
184 |
185 | public IBTree getBTree(){
186 | return this.tree;
187 | }
188 |
189 | public void load(){
190 |
191 | try {
192 | List bufferList = new ArrayList();
193 |
194 | FileDeco fd = this.fileMgr.pinFileChannel(PREFIX_INDEX + this.dbName);
195 | long len = fd.getFileChannel().size();
196 | // System.out.println(PREFIX_INDEX + this.dbName + " len = " + len);
197 | if(len >= ByteUtil.INT_SIZE){
198 | fd.getFileChannel().position(0);
199 | ByteBuffer buff = ByteBuffer.allocate(ByteUtil.INT_SIZE);
200 | fd.getFileChannel().read(buff);
201 | buff.rewind();
202 | this.counter.set(buff.getInt());
203 |
204 | // System.out.println("load counter = " + this.counter.get());
205 | }
206 | if(len >= IndexPage.PAGE_SIZE + ByteUtil.INT_SIZE){
207 | int size = (int) ((len - ByteUtil.INT_SIZE) / IndexPage.PAGE_SIZE);
208 |
209 | // System.out.println("load size = " + size + ", len = " + len);
210 |
211 | if(size * IndexPage.PAGE_SIZE < len){
212 | ByteBuffer[] array = new ByteBuffer[size];
213 | for(int i = 0; i < size; ++i){
214 | ByteBuffer buffer = this.bufferMgr.pinBuffer();
215 | array[i] = buffer;
216 | array[i].position(0);
217 | bufferList.add(buffer);
218 | }
219 |
220 | fd.getFileChannel().position(ByteUtil.INT_SIZE);
221 | fd.getFileChannel().read(array);
222 | }
223 | }
224 |
225 | List pageList = new ArrayList();
226 | if(null != bufferList && bufferList.size() > 0){
227 |
228 | this.tree = RandomInsertBStarTree.buildBTree(this.dbName, this, this.transMgr, bufferList, pageList);
229 |
230 | }else{
231 |
232 | this.tree = new RandomInsertBStarTree(this.dbName, this, this.transMgr);
233 | /* IndexPage page = this.appendNewIndexPage(this.tree.getRoot());
234 | pageList.add(page);*/
235 | }
236 |
237 | if(pageList.size() > 0){
238 | for(IndexPage page : pageList){
239 | // System.out.println("load " + page.pageID() + ", " + page.pos);
240 | this.pageMap.put(page.pageID(), page);
241 | }
242 | }
243 |
244 | this.fileMgr.copy(PREFIX_INDEX + this.dbName, PREFIX_SNAPSHOT_INDEX + this.dbName);
245 | } catch (Exception e) {
246 | System.out.println(e);
247 | e.printStackTrace();
248 | }
249 |
250 |
251 | }
252 |
253 | public void flush(){
254 |
255 | if(null != this.tree){
256 | try {
257 | List bufferList = new ArrayList();
258 |
259 | this.tree.toByteBuffer(bufferList);
260 |
261 | if(null != bufferList && bufferList.size() > 0){
262 |
263 | FileDeco fd = this.fileMgr.pinFileChannel(PREFIX_TEMP_INDEX + this.dbName);
264 | // ByteBuffer[] array = new ByteBuffer[bufferList.size()];
265 | fd.getFileChannel().truncate(0);
266 | fd.getFileChannel().position(0);
267 |
268 | ByteBuffer buff = ByteBuffer.allocate(ByteUtil.INT_SIZE);
269 | buff.putInt(this.counter.get());
270 | buff.position(0);
271 | // System.out.println("flush counter = " + this.counter.get());
272 | fd.getFileChannel().write(buff);
273 |
274 | for(int i = 0; i < bufferList.size(); ++i){
275 | ByteBuffer array = bufferList.get(i);
276 | // System.out.println(i + " limit = " + array[i].limit() + ", size = " + array[i].getInt(17));
277 | array.position(0);
278 |
279 | while(array.hasRemaining()) {
280 | fd.getFileChannel().write(array);
281 | }
282 |
283 |
284 | BTreeNode.buffMgr.unpinBuffer(array);
285 | }
286 |
287 | this.fileMgr.closeFileChannel(fd);
288 | this.fileMgr.delete(PREFIX_BAK_INDEX + this.dbName);
289 |
290 | this.fileMgr.rename(PREFIX_INDEX + this.dbName, PREFIX_BAK_INDEX + this.dbName);
291 | this.fileMgr.rename(PREFIX_TEMP_INDEX + this.dbName, PREFIX_INDEX + this.dbName);
292 | }
293 | } catch (IOException e) {
294 | System.out.println(e);
295 | e.printStackTrace();
296 | }
297 | }
298 | }
299 | }
300 |
--------------------------------------------------------------------------------
/src/tenndb/index/IndexPage.java:
--------------------------------------------------------------------------------
1 | package tenndb.index;
2 |
3 |
4 | import java.nio.ByteBuffer;
5 |
6 | import tenndb.bstar.RandomInsertBStarTree;
7 | import tenndb.bstar.BTreeNode;
8 | import tenndb.bstar.IdxBlock;
9 | import tenndb.common.ByteUtil;
10 |
11 |
12 | public class IndexPage {
13 |
14 |
15 | public static final int INDEX_HEAD_SIZE = ByteUtil.INT_SIZE;
16 |
17 | public static final int PAGE_HEAD_SIZE = ByteUtil.BYTE_SIZE + ByteUtil.INT_SIZE + ByteUtil.INT_SIZE + ByteUtil.INT_SIZE + ByteUtil.INT_SIZE + ByteUtil.INT_SIZE ;
18 | public static final int PAGE_BLOCK_SIZE = ByteUtil.INT_SIZE + ByteUtil.INT_SIZE + ByteUtil.INT_SIZE + ByteUtil.INT_SIZE + ByteUtil.BYTE_SIZE ;
19 | public static final int PAGE_BODY_SIZE = PAGE_BLOCK_SIZE * (RandomInsertBStarTree.BALANCE_SIZE + 2);
20 | //(num,key,data) x86: (1 + 4 + 40)*20=900
21 | //type + pageid + parentid + priorid + nextid + size
22 | public static final int PAGE_SIZE = PAGE_HEAD_SIZE + PAGE_BODY_SIZE;
23 | //(key + pageid + blockid + tag)*BALANCE_SIZE 48
24 |
25 |
26 | protected long pos = 0;
27 | protected BTreeNode node = null;
28 | protected ByteBuffer buffer = null;
29 |
30 | public IndexPage(BTreeNode node, ByteBuffer buffer) {
31 | super();
32 | this.node = node;
33 | this.buffer = buffer;
34 | }
35 |
36 | public ByteBuffer getBuffer() {
37 | return buffer;
38 | }
39 |
40 | public IdxBlock getBlock(int index){
41 | return this.node.getBlock(index);
42 | }
43 |
44 | public int size(){
45 | return this.node.size();
46 | }
47 |
48 | public long getPos() {
49 | return pos;
50 | }
51 |
52 | public void setPos(long pos) {
53 | this.pos = pos;
54 | }
55 |
56 | public void flush(BTreeNode rootNode){
57 | this.node.toByteBuffer(this.buffer, rootNode);
58 | }
59 |
60 | public int pageID(){
61 | return this.node.getPageID();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/tenndb/log/CellLogMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.log;
2 |
3 | import tenndb.bstar.IdxBlock;
4 | import tenndb.tx.Trans;
5 |
6 | public class CellLogMgr {
7 |
8 | protected final int tabID;
9 |
10 | protected final LogMgr logMgr;
11 |
12 | public CellLogMgr(int tabID, LogMgr logMgr) {
13 | super();
14 | this.tabID = tabID;
15 | this.logMgr = logMgr;
16 | }
17 |
18 | public boolean logBegin(Trans tid){
19 | return this.logMgr.logBegin(tid);
20 | }
21 |
22 | public boolean logRollback(Trans tid){
23 | return this.logMgr.logRollback(tid);
24 | }
25 |
26 | public boolean logCommit(Trans tid){
27 | return this.logMgr.logCommit(tid);
28 | }
29 |
30 | public boolean logTerminated(Trans tid){
31 | return this.logMgr.logTerminated(tid);
32 | }
33 |
34 | public boolean logInsert(Trans tid, int key, IdxBlock newblk){
35 | return this.logMgr.logInsert(tid, key, this.tabID, newblk);
36 | }
37 |
38 | public boolean logDelete(Trans tid, int key){
39 | return this.logMgr.logDelete(tid, key, this.tabID);
40 | }
41 |
42 | public boolean logUpdate(Trans tid, int key, IdxBlock newblk, IdxBlock oldblk){
43 | return this.logMgr.logUpdate(tid, key, this.tabID, newblk, oldblk);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/tenndb/log/LogMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.log;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.IOException;
6 | import java.io.RandomAccessFile;
7 | import java.nio.ByteBuffer;
8 | import java.util.ArrayList;
9 | import java.util.HashMap;
10 | import java.util.HashSet;
11 | import java.util.Hashtable;
12 | import java.util.List;
13 | import java.util.Map;
14 | import java.util.Set;
15 | import java.util.concurrent.locks.ReadWriteLock;
16 | import java.util.concurrent.locks.ReentrantReadWriteLock;
17 |
18 | import tenndb.base.Catalog;
19 | import tenndb.base.Cell;
20 | import tenndb.bstar.IdxBlock;
21 | import tenndb.common.FileUtil;
22 | import tenndb.tx.Trans;
23 |
24 | public class LogMgr {
25 |
26 | static final byte START_RECORD = 1;
27 |
28 | static final byte INSERT_RECORD = 2;
29 | static final byte UPDATE_RECORD = 3;
30 | static final byte DELETE_RECORD = 4;
31 |
32 | static final byte ROLLBACK_RECORD = 5;
33 | static final byte COMMIT_RECORD = 6;
34 | static final byte TERMINATED_RECORD = 7;
35 |
36 | static final byte CHECKPOINT_RECORD = 8;
37 | static final byte NO_CHECKPOINT_ID = 0;
38 |
39 |
40 | public static final int INT_SIZE = Integer.SIZE / Byte.SIZE;
41 | public static final int SHORT_SIZE = Short.SIZE / Byte.SIZE;
42 | public static final int BYTE_SIZE = Byte.SIZE / Byte.SIZE;
43 |
44 | //tid 4
45 | //type 1
46 | //state 1
47 | //new.key 4
48 | //tabId 4
49 | //new.pageid 4
50 | //new.offset 2
51 | //new.tag 1
52 | //old.pageid 4
53 | //old.offset 2
54 | //old.tag 1
55 | //prelog.pos 4
56 |
57 | public static final int LOG_BLOCK_SIZE = INT_SIZE + BYTE_SIZE + BYTE_SIZE + INT_SIZE + INT_SIZE
58 | + INT_SIZE + SHORT_SIZE + BYTE_SIZE
59 | + INT_SIZE + SHORT_SIZE + BYTE_SIZE
60 | + INT_SIZE;
61 |
62 | protected boolean logging = true;
63 | protected final File logFile;
64 | protected RandomAccessFile raf = null;
65 | private Map tidToTailLogRecord = null;
66 |
67 | protected final ReadWriteLock lock = new ReentrantReadWriteLock(false);
68 |
69 | protected static final String PREFIX_LOG = "log_";
70 |
71 |
72 | public void recover(Catalog catalog){
73 | List logRecordList = this.loadLogRecord();
74 | if(null != logRecordList){
75 | Map> undoSetMap = new HashMap>();
76 | Map> redoSetMap = new HashMap>();
77 |
78 | this.recoverLogRecord(logRecordList, undoSetMap, redoSetMap);
79 |
80 | System.out.println("undo.size = " + undoSetMap.size());
81 | System.out.println("redo.size = " + redoSetMap.size());
82 |
83 | this.redo(catalog, redoSetMap);
84 | this.undo(catalog, undoSetMap);
85 | }
86 |
87 | this.truncate();
88 | }
89 |
90 | public void undo(Catalog catalog, Map> undoSetMap){
91 |
92 | }
93 |
94 | public void redo(Catalog catalog, Map> redoSetMap){
95 | Set tidSet = redoSetMap.keySet();
96 | for(Integer tid : tidSet){
97 | List list = redoSetMap.get(tid);
98 | if(null != list && list.size() > 0){
99 | for(int i = list.size() - 1; i >= 0; --i){
100 | LogRecord record = list.get(i);
101 |
102 | int tabID = record.tabId;
103 | Cell cell = catalog.getCell(tabID);
104 | if(null != cell){
105 | if(INSERT_RECORD == record.type){
106 | cell.recoverInsert(record.key, record.getNewPid(), record.getNewOffset());
107 | }else if(UPDATE_RECORD == record.type){
108 | cell.recoverUpdate(record.key, record.getNewPid(), record.getNewOffset());
109 | }else if(DELETE_RECORD == record.type){
110 | cell.recoverDelete(record.key);
111 | }
112 | }
113 | }
114 | }
115 | }
116 | }
117 |
118 | public void truncate(){
119 | System.out.println("truncate.1");
120 | if(this.logFile.exists()){
121 | try {
122 | this.raf.close();
123 | System.out.println("truncate.2");
124 | this.logFile.delete();
125 | this.raf = new RandomAccessFile(this.logFile, "rw");
126 | } catch (IOException e) {
127 | // TODO Auto-generated catch block
128 | e.printStackTrace();
129 | }
130 | }
131 | System.out.println("truncate.3");
132 | }
133 |
134 | public void recoverLogRecord(List logRecordList, Map> undoSetMap, Map> redoSetMap){
135 |
136 | Map recordMap = new HashMap();
137 | Set undoSet = new HashSet();
138 | Set redoSet = new HashSet();
139 |
140 | for(int i = logRecordList.size() - 1; i >= 0 ; --i){
141 | LogRecord record = logRecordList.get(i);
142 | if(!recordMap.containsKey(record.tid)){
143 | if(Trans.COMMIT == record.type){
144 | redoSet.add(record.tid);
145 | }else if(Trans.ROLLBACK == record.type){
146 | undoSet.add(record.tid);
147 | }else if(Trans.ACTIVE == record.type){
148 | undoSet.add(record.tid);
149 | }
150 |
151 | recordMap.put(record.tid, record.type);
152 | }else{
153 | if(Trans.START == record.type){
154 | undoSet.remove(record.tid);
155 | redoSet.remove(record.tid);
156 | }
157 | }
158 |
159 | if(redoSet.contains(record.tid)){
160 | List list = redoSetMap.get(record.tid);
161 | if(null == list){
162 | list = new ArrayList();
163 | redoSetMap.put(record.tid, list);
164 | }
165 | list.add(record);
166 | }
167 |
168 | if(undoSet.contains(record.tid)){
169 | List list = undoSetMap.get(record.tid);
170 | if(null == list){
171 | list = new ArrayList();
172 | undoSetMap.put(record.tid, list);
173 | }
174 | list.add(record);
175 | }
176 | }
177 | }
178 |
179 | public LogMgr(String cataName, String root){
180 | File dir = new File(root);
181 |
182 | if(!dir.exists()){
183 | FileUtil.mkDir(dir);
184 | }
185 |
186 | File file = new File(root, PREFIX_LOG + cataName);
187 | this.logFile = file;
188 | this.logging = true;
189 | this.tidToTailLogRecord = new Hashtable();
190 | try {
191 | this.raf = new RandomAccessFile(this.logFile, "rw");
192 | } catch (FileNotFoundException e) {
193 | e.printStackTrace();
194 | }
195 | }
196 |
197 | public List loadLogRecord(){
198 | List list = new ArrayList();
199 |
200 | try{
201 | byte[] array = new byte[LOG_BLOCK_SIZE];
202 | ByteBuffer buff = ByteBuffer.allocate(LOG_BLOCK_SIZE);
203 | this.lockWrite();
204 |
205 | this.raf.seek(0);
206 |
207 | while(this.raf.getFilePointer() < this.raf.length()){
208 | this.raf.read(array);
209 | buff.flip();
210 | buff.clear();
211 | buff.put(array);
212 | //tid 4
213 | //type 1
214 | //state 1
215 | //new.key 4
216 | //tabId 4
217 | //new.pageid 4
218 | //new.offset 2
219 | //new.tag 1
220 | //old.pageid 4
221 | //old.offset 2
222 | //old.tag 1
223 | //prelog.pos 4
224 | buff.flip();
225 |
226 | int tid = buff.getInt();
227 | byte type = buff.get();
228 | byte state = buff.get();
229 | int key = buff.getInt();
230 | int tabId = buff.getInt();
231 | int newPid = buff.getInt();
232 | short newOffset = buff.getShort();
233 | byte newTag = buff.get();
234 | int oldPid = buff.getInt();
235 | short oldOffset = buff.getShort();
236 | byte oldTag = buff.get();
237 | int pos = buff.getInt();
238 |
239 | LogRecord record = new LogRecord(tid, state, type, key, tabId,
240 | newPid, newOffset, newTag,
241 | oldPid, oldOffset, oldTag);
242 | record.prePos = pos;
243 | record.state = state;
244 | list.add(record);
245 | }
246 | }catch(Exception e){}
247 | finally{
248 | this.unLockWrite();
249 | }
250 |
251 | return list;
252 | }
253 |
254 | public boolean writeLog(LogRecord record){
255 | boolean b = false;
256 |
257 | // this.logCache.push(record);
258 |
259 | if(null != record && record.tid > 0 && true == this.logging){
260 | try{
261 | this.lockWrite();
262 | int start = (int) this.raf.length();
263 |
264 | this.raf.seek(start);
265 | this.raf.writeInt (record.tid);
266 | this.raf.writeByte (record.type);
267 | this.raf.writeByte (record.state);
268 | this.raf.writeInt (record.key);
269 | this.raf.writeInt (record.tabId);
270 |
271 | this.raf.writeInt (record.newPid);
272 | this.raf.writeShort(record.newOffset);
273 | this.raf.writeByte (record.newTag);
274 |
275 | this.raf.writeInt (record.oldPid);
276 | this.raf.writeShort(record.oldOffset);
277 | this.raf.writeByte (record.oldTag);
278 |
279 | if(START_RECORD != record.type){
280 | Integer pos = this.tidToTailLogRecord.get(record.tid);
281 |
282 | this.raf.writeInt(pos);
283 |
284 | }else{
285 | this.raf.writeInt(0);
286 | }
287 |
288 | this.tidToTailLogRecord.put(record.tid, start);
289 |
290 | b = true;
291 | }catch(Exception e){}
292 | finally{
293 | this.unLockWrite();
294 | }
295 | }
296 |
297 | return b;
298 | }
299 |
300 | public boolean logBegin(Trans tid){
301 | boolean b = false;
302 |
303 | if(null != tid && tid.getTransID() > 0){
304 | LogRecord record = new LogRecord(tid.getTransID(), Trans.START, START_RECORD, 0, 0,
305 | 0, (short)0, (byte)0, 0, (short)0, (byte)0);
306 | b = this.writeLog(record);
307 | }
308 | return b;
309 | }
310 |
311 | public boolean logTerminated(Trans tid){
312 | boolean b = false;
313 |
314 | if(null != tid && tid.getTransID() > 0){
315 | LogRecord record = new LogRecord(tid.getTransID(), Trans.TERMINATED, TERMINATED_RECORD, 0, 0,
316 | 0, (short)0, (byte)0, 0, (short)0, (byte)0);
317 | b = this.writeLog(record);
318 | }
319 | return b;
320 | }
321 |
322 | public boolean logRollback(Trans tid){
323 | boolean b = false;
324 |
325 | if(null != tid && tid.getTransID() > 0){
326 | LogRecord record = new LogRecord(tid.getTransID(), Trans.ROLLBACK, ROLLBACK_RECORD, 0, 0,
327 | 0, (short)0, (byte)0, 0, (short)0, (byte)0);
328 | b = this.writeLog(record);
329 | }
330 | return b;
331 | }
332 |
333 | public boolean logCommit(Trans tid){
334 | boolean b = false;
335 |
336 | if(null != tid && tid.getTransID() > 0){
337 | LogRecord record = new LogRecord(tid.getTransID(), Trans.COMMIT, COMMIT_RECORD, 0, 0,
338 | 0, (short)0, (byte)0, 0, (short)0, (byte)0);
339 | b = this.writeLog(record);
340 | }
341 | return b;
342 | }
343 |
344 | public boolean logInsert(Trans tid, int key, int tabId, IdxBlock newblk){
345 | boolean b = false;
346 |
347 | if(null != tid && tid.getTransID() > 0 && null != newblk){
348 | LogRecord record = new LogRecord(tid.getTransID(), Trans.ACTIVE, INSERT_RECORD, key, tabId,
349 | newblk.getPageID(), (short)newblk.getOffset(), (byte)newblk.getTag(),
350 | (int)0, (short)0, (byte)0);
351 | b = this.writeLog(record);
352 | }
353 | return b;
354 | }
355 |
356 | public boolean logDelete(Trans tid, int key, int tabId){
357 | boolean b = false;
358 |
359 | if(null != tid && tid.getTransID() > 0){
360 | LogRecord record = new LogRecord(tid.getTransID(), Trans.ACTIVE, DELETE_RECORD, key, tabId,
361 | 0, (short)0, (byte)IdxBlock.INVALID,
362 | 0, (short)0, (byte)IdxBlock.VALID);
363 | b = this.writeLog(record);
364 | }
365 |
366 | return b;
367 | }
368 |
369 | public boolean logUpdate(Trans tid, int key, int tabId, IdxBlock newblk, IdxBlock oldblk){
370 | boolean b = false;
371 |
372 | if(null != tid && tid.getTransID() > 0 && null != newblk && null != oldblk){
373 | LogRecord record = new LogRecord(tid.getTransID(), Trans.ACTIVE, UPDATE_RECORD, key, tabId,
374 | newblk.getPageID(), (short)newblk.getOffset(), (byte)newblk.getTag(),
375 | oldblk.getPageID(), (short)oldblk.getOffset(), (byte)oldblk.getTag());
376 | b = this.writeLog(record);
377 | }
378 |
379 | return b;
380 | }
381 |
382 |
383 | protected void lockRead() { this.lock.readLock().lock(); }
384 |
385 | protected void unLockRead() { this.lock.readLock().unlock(); }
386 |
387 | protected void lockWrite() { this.lock.writeLock().lock(); }
388 |
389 | protected void unLockWrite() { this.lock.writeLock().unlock(); }
390 | }
391 |
--------------------------------------------------------------------------------
/src/tenndb/log/LogRecord.java:
--------------------------------------------------------------------------------
1 | package tenndb.log;
2 |
3 | public class LogRecord {
4 |
5 | //tid 4
6 | //type 1
7 | //state 1
8 | //new.key 4
9 | //tabId 4
10 | //new.pageid 4
11 | //new.offset 2
12 | //new.tag 1
13 | //old.pageid 4
14 | //old.offset 2
15 | //old.tag 1
16 | //prelog.pos 4
17 |
18 | protected int tid;
19 | protected byte type;
20 | protected byte state;
21 | protected int key;
22 | protected int tabId;
23 | protected int newPid;
24 | protected short newOffset;
25 | protected byte newTag;
26 | protected int oldPid;
27 | protected short oldOffset;
28 | protected byte oldTag;
29 | protected int prePos;
30 |
31 | public LogRecord(int tid, byte state, byte type, int key, int tabId,
32 | int newPid, short newOffset, byte newTag,
33 | int oldPid, short oldOffset, byte oldTag) {
34 | super();
35 | this.tid = tid;
36 | this.type = type;
37 | this.state = state;
38 | this.key = key;
39 | this.tabId = tabId;
40 | this.newPid = newPid;
41 | this.newOffset = newOffset;
42 | this.newTag = newTag;
43 | this.oldPid = oldPid;
44 | this.oldOffset = oldOffset;
45 | this.oldTag = oldTag;
46 | }
47 |
48 | public int getTid() {
49 | return tid;
50 | }
51 |
52 | public byte getType() {
53 | return type;
54 | }
55 |
56 | public byte getState() {
57 | return state;
58 | }
59 |
60 | public int getKey() {
61 | return key;
62 | }
63 |
64 | public int getTabId() {
65 | return tabId;
66 | }
67 |
68 | public int getNewPid() {
69 | return newPid;
70 | }
71 |
72 | public short getNewOffset() {
73 | return newOffset;
74 | }
75 |
76 | public byte getNewTag() {
77 | return newTag;
78 | }
79 |
80 | public int getOldPid() {
81 | return oldPid;
82 | }
83 |
84 | public short getOldOffset() {
85 | return oldOffset;
86 | }
87 |
88 | public byte getOldTag() {
89 | return oldTag;
90 | }
91 |
92 | public int getPrePos() {
93 | return prePos;
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/src/tenndb/route/RouteMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.route;
2 |
3 | import java.util.Hashtable;
4 | import java.util.Map;
5 | import java.util.concurrent.locks.ReadWriteLock;
6 | import java.util.concurrent.locks.ReentrantReadWriteLock;
7 |
8 | import tenndb.base.Cell;
9 | import tenndb.common.FileMgr;
10 | import tenndb.data.ByteBufferMgr;
11 | import tenndb.data.Colunm;
12 | import tenndb.data.DBPage;
13 | import tenndb.dist.DistMgr;
14 | import tenndb.log.LogMgr;
15 | import tenndb.thread.ImportThread;
16 | import tenndb.tx.TransMgr;
17 |
18 |
19 | public class RouteMgr {
20 |
21 | protected Cell level0 = null;
22 |
23 | protected Map level1 = null;
24 | protected Map level2 = null;
25 |
26 | protected final String root;
27 | protected final String cataName;
28 | protected final FileMgr rootMgr;
29 | protected final LogMgr logMgr;
30 | protected final TransMgr transMgr;
31 | protected final ByteBufferMgr bufMgr;
32 |
33 | protected ImportThread importThread = null;
34 |
35 | protected final ReadWriteLock lock = new ReentrantReadWriteLock(false);
36 |
37 | protected volatile boolean initialized = false;
38 |
39 | public static final String LOGS_PATH = System.getProperty("file.separator") + "logs_data";
40 |
41 | public static final String ROUTE_PATH = System.getProperty("file.separator") + "route_data";
42 |
43 | public static final String DATA_PATH = System.getProperty("file.separator") + "raw_data";
44 |
45 |
46 | public RouteMgr(String root){
47 | this.cataName = "date_route";
48 | this.root = root;
49 | this.rootMgr = new FileMgr(this.root);
50 |
51 | this.logMgr = new LogMgr(this.cataName, this.root + LOGS_PATH);
52 | this.bufMgr = new ByteBufferMgr(DBPage.PAGE_SIZE);
53 | this.transMgr = new TransMgr();
54 |
55 | this.level0 = new Cell(this.cataName, 0, new FileMgr(this.root + ROUTE_PATH), this.transMgr, this.logMgr);
56 | this.level1 = new Hashtable();
57 | this.level2 = new Hashtable();
58 | }
59 |
60 | public void init(){
61 | if(false == this.initialized){
62 | try{
63 | this.lockWrite();
64 | if(false == this.initialized){
65 | this.level0.init();
66 | this.importThread = new ImportThread(new FileMgr(this.root + DistMgr.DIST_PATH), this);
67 | this.importThread.start();
68 | this.initialized = true;
69 | }
70 | }catch(Exception e){
71 | System.out.println(e);
72 | }finally{
73 | this.unLockWrite();
74 | }
75 | }
76 | }
77 |
78 | public final Cell getLevel0(){
79 | return this.level0;
80 | }
81 |
82 | public static final String data2path(String date){
83 | String path = null;
84 | //20160701
85 | if(null != date && date.length() == 8){
86 | path = System.getProperty("file.separator") + date.substring(0, 4)
87 | + System.getProperty("file.separator") + date.substring(4, 6)
88 | + System.getProperty("file.separator") + date.substring(6, 8) ;
89 | }
90 |
91 | return path;
92 | }
93 |
94 | public static final String dev2path(String dev){
95 | String path = null;
96 |
97 | if(null != dev && dev.length() == 10){
98 | path = System.getProperty("file.separator") + dev.substring(8, 10)
99 | + System.getProperty("file.separator") + dev.substring(0, 8);
100 | }
101 |
102 | return path;
103 | }
104 |
105 | public final Cell pinLevel2(String level1, String level2){
106 | Cell cell2 = null;
107 |
108 | try{
109 | if(null != level1 && level1.length() > 0 && null != level2 && level2.length() > 0){
110 | String key = level1 + "_" + level2;
111 |
112 | // this.lockRead();
113 | cell2 = this.level2.get(key);
114 | // this.unLockRead();
115 |
116 | if(null == cell2){
117 | Cell cell1 = this.pinLevel1(level1);
118 | if(null != cell1){
119 |
120 | Colunm colunm = cell1.search(Colunm.hashCode(level2));
121 | if(null == colunm){
122 | colunm = new Colunm(level2, 1);
123 | cell1.insert(colunm.getHashCode(), colunm);
124 | }
125 |
126 | if(null != colunm){
127 |
128 | String key2 = colunm.getKey();
129 | if(null != key2){
130 | String datepath = data2path(level1);
131 | String devpath = dev2path (level2);
132 | //dev2path
133 | cell2 = new Cell(key2, 0, new FileMgr(this.root + DATA_PATH + datepath + devpath), this.transMgr, this.logMgr);
134 | cell2.init();
135 |
136 | try{
137 | // this.unLockRead();
138 | this.lockWrite();
139 | this.level2.put(key, cell2);
140 | }catch(Exception e){
141 | System.out.println(e);
142 | }
143 | finally{
144 | this.unLockWrite();
145 | // this.lockRead();
146 | }
147 | }
148 | }
149 | }
150 | }
151 | }
152 | }catch(Exception e){
153 | System.out.println(e);
154 | }finally{
155 | // this.unLockRead();
156 | }
157 |
158 | return cell2;
159 | }
160 |
161 | //160101
162 | public final Cell pinLevel1(String level1){
163 |
164 | Cell cell = null;
165 |
166 | try{
167 | if(null != level1 && level1.length() > 0){
168 | // this.lockRead();
169 |
170 | cell = this.level1.get(level1);
171 | if(null == cell){
172 | Colunm colunm = this.level0.search(Colunm.hashCode(level1));
173 | if(null == colunm){
174 | colunm = new Colunm(level1, 1);
175 | this.level0.insert(colunm.getHashCode(), colunm);
176 | }
177 |
178 | if(null != colunm){
179 | String key = colunm.getKey();
180 | if(null != key){
181 | String path = data2path(key);
182 | cell = new Cell(key, 0, new FileMgr(this.root + DATA_PATH + path), this.transMgr, this.logMgr);
183 | cell.init();
184 | try{
185 | // this.unLockRead();
186 | this.lockWrite();
187 | this.level1.put(key, cell);
188 | }catch(Exception e){
189 | System.out.println(e);
190 | }
191 | finally{
192 | this.unLockWrite();
193 | // this.lockRead();
194 | }
195 | }
196 | }
197 | }
198 | }
199 | }catch(Exception e){
200 | System.out.println(e);
201 | }finally{
202 | // this.unLockRead();
203 | }
204 | return cell;
205 | }
206 |
207 | protected void lockRead() { this.lock.readLock().lock(); }
208 |
209 | protected void unLockRead() { this.lock.readLock().unlock(); }
210 |
211 | protected void lockWrite() { this.lock.writeLock().lock(); }
212 |
213 | protected void unLockWrite() { this.lock.writeLock().unlock(); }
214 |
215 | }
216 |
--------------------------------------------------------------------------------
/src/tenndb/routetest/TestRoute.java:
--------------------------------------------------------------------------------
1 | package tenndb.routetest;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Hashtable;
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | import tenndb.base.Cell;
9 | import tenndb.common.SystemTime;
10 | import tenndb.data.Colunm;
11 | import tenndb.data.Filed;
12 | import tenndb.route.RouteMgr;
13 |
14 | public class TestRoute {
15 |
16 | /**
17 | * @param args
18 | */
19 | public static void main(String[] args) {
20 |
21 | RouteMgr mgr = new RouteMgr("J:\\tennbase");
22 | mgr.init();
23 |
24 | String date = "160713";
25 | Map map = new Hashtable();
26 | List list = new ArrayList();
27 |
28 | for(int i = 0; i < 3; ++i)
29 | {
30 | long dev = 1607130000 + i;
31 | String level2 = String.valueOf(dev);
32 | Cell cell2 = mgr.pinLevel2(date, level2);
33 | if(null != cell2){
34 | map.put(cell2.getDbName(), cell2);
35 | list.add(cell2);
36 | }
37 | }
38 |
39 | int when = SystemTime.getSystemTime().currentTime();
40 | for(int i = 1; i < 100000; ++i){
41 | String key = String.valueOf(when + i);
42 | Colunm colunm = new Colunm(key, 1);
43 | colunm.addFiled(new Filed("var1", key + 1));
44 |
45 | for(int t = 0; t < list.size(); ++t){
46 | Cell cell = list.get(t);
47 | cell.insert(colunm.getHashCode(), colunm);
48 | }
49 | }
50 |
51 |
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/tenndb/test/TestAbortTransException.java:
--------------------------------------------------------------------------------
1 | package tenndb.test;
2 |
3 | import tenndb.tx.AbortTransException;
4 |
5 | public class TestAbortTransException {
6 |
7 | public static void test() throws AbortTransException{
8 | try{
9 | System.out.println("test.1");
10 | throw new AbortTransException("abort ");
11 |
12 | }catch(AbortTransException ae){
13 | System.out.println(ae);
14 | System.out.println("test.2");
15 | throw ae;
16 | }
17 | catch(Exception e){
18 | System.out.println(e);
19 | System.out.println("test.3");
20 | }
21 | finally{
22 | System.out.println("test.4");
23 | }
24 | }
25 |
26 |
27 | public static void main(String[] args) {
28 |
29 | try {
30 | test();
31 | } catch (AbortTransException e) {
32 | // TODO Auto-generated catch block
33 | e.printStackTrace();
34 | }
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/tenndb/test/TestByte.java:
--------------------------------------------------------------------------------
1 | package tenndb.test;
2 |
3 | import tenndb.common.ByteUtil;
4 |
5 | public class TestByte {
6 |
7 | /**
8 | * @param args
9 | */
10 | public static void main(String[] args) {
11 | byte[] array = ByteUtil.intToByte4_big(123456);
12 |
13 | int n = ByteUtil.byte4ToInt_big(array, 0);
14 | System.out.println("n = " + n);
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/tenndb/test/TestCell.java:
--------------------------------------------------------------------------------
1 | package tenndb.test;
2 |
3 | import java.util.List;
4 |
5 | import tenndb.base.Cell;
6 | import tenndb.common.FileMgr;
7 | import tenndb.data.Colunm;
8 | import tenndb.tx.Trans;
9 | import tenndb.tx.TransMgr;
10 |
11 | public class TestCell {
12 |
13 | /**
14 | * @param args
15 | */
16 | public static void main(String[] args) {
17 |
18 | TransMgr trasMgr = new TransMgr();
19 |
20 | FileMgr fileMgr = new FileMgr("J:\\tennbase\\");
21 | String dbName = "stu";
22 | int dbID = 123;
23 | Cell cell = new Cell(dbName, dbID, fileMgr, trasMgr, null);
24 |
25 | cell.init();
26 | /*
27 | for(int i = 1000; i < 2000; ++i){
28 | int key = i;
29 | String var = i + "_hellowrold";
30 | cell.insert(key, var);
31 | }
32 |
33 | for(int i = 2000; i < 3000; ++i){
34 | int key = i;
35 | String var = i + "_hellowrold";
36 | cell.insert(key, var);
37 | }
38 |
39 | for(int i = 3000; i < 4000; ++i){
40 | int key = i;
41 | String var = i + "_hellowrold";
42 | cell.insert(key, var);
43 | }
44 | */
45 | Trans tid = new Trans();
46 | /* for(int i = 0; i < 100; ++i){
47 | int key = i;
48 | String var = i + "_hellowrold";
49 | cell.insert(key, var, tid);
50 | cell.commit(key, tid);
51 | }
52 | */
53 |
54 | // cell.delete(51);
55 | // TransID tid = new TransID();
56 |
57 | for(int i = 1; i <= 100; i+=10){
58 | Colunm var = cell.search(i, tid);
59 | System.out.println("key = " + i + ", var = " + var.getKey());
60 | }
61 |
62 |
63 | int n1 = cell.count(33, 88);
64 | System.out.println("count = " + n1);
65 |
66 |
67 |
68 | System.out.println("++++++++++++++++++++++++++++");
69 |
70 | List list2 = cell.range(8888, 8988, false);
71 |
72 | for(int i = 0; i < list2.size(); ++i){
73 | System.out.println("range2 " + list2.get(i).getKey());
74 | }
75 |
76 | cell.printTreeNext();
77 |
78 | // reactor.print();
79 | /* try {
80 | Thread.sleep(1000*1000);
81 | } catch (InterruptedException e) {
82 | // TODO Auto-generated catch block
83 | e.printStackTrace();
84 | }*/
85 | cell.flush();
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/src/tenndb/test/TestDBPageMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.test;
2 |
3 | import tenndb.bstar.IdxBlock;
4 | import tenndb.common.FileMgr;
5 | import tenndb.data.DBBlock;
6 | import tenndb.data.DBPageMgr;
7 | import tenndb.index.IBTree;
8 | import tenndb.index.IndexMgr;
9 | import tenndb.tx.AbortTransException;
10 | import tenndb.tx.Trans;
11 | import tenndb.tx.TransMgr;
12 |
13 |
14 | public class TestDBPageMgr {
15 |
16 | /**
17 | * @param args
18 | */
19 | public static void main(String[] args) {
20 |
21 | FileMgr fileMgr = new FileMgr("J:\\tennbase\\");
22 |
23 | String dbName = "stu";
24 |
25 | TransMgr trasMgr = new TransMgr();
26 | IndexMgr indexMgr = new IndexMgr(dbName, fileMgr, trasMgr);
27 | DBPageMgr dbPageMgr = new DBPageMgr(dbName, fileMgr);
28 | dbPageMgr.load();
29 | indexMgr.load();
30 |
31 | IBTree tree = indexMgr.getBTree();
32 | System.out.println(tree.toString());
33 | tree.printNext();
34 | // Trans tid = new Trans();
35 | for(int i = 0; i < 100; ++i){
36 | int key = i;
37 | String str = i + "_hellowrold";
38 | byte[] var = str.getBytes();
39 |
40 | /* DBBlock dbblk = dbPageMgr.nextDBBlock(var);
41 | if(null != dbblk){
42 |
43 |
44 |
45 | dbblk.setVar(var);
46 | System.out.println("pageID = " + dbblk.getPageID() + ", offset = " + dbblk.getOffset());
47 | IdxBlock idxblk = new IdxBlock(key);
48 | idxblk.setPageID(dbblk.getPageID());
49 | idxblk.setOffset(dbblk.getOffset());
50 | try {
51 | tree.insert(key, idxblk, null, null);
52 | } catch (AbortTransException e) {
53 | // TODO Auto-generated catch block
54 | e.printStackTrace();
55 | }
56 | }*/
57 | }
58 |
59 | for(int i = 1; i < 100; i*=10){
60 | int key = i;
61 | IdxBlock idxblk = tree.search(key, null);
62 | System.out.println(idxblk.getPageID() + ", " + idxblk.getOffset());
63 | DBBlock dbblk = dbPageMgr.getDBBlock(idxblk.getPageID(), idxblk.getOffset());
64 | System.out.println(key + ", " + dbblk.getColunm().getKey());
65 | }
66 |
67 | indexMgr.flush();
68 | dbPageMgr.flush();
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/tenndb/test/TestFileMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.test;
2 |
3 |
4 | import java.io.IOException;
5 |
6 | import tenndb.common.FileMgr;
7 |
8 | public class TestFileMgr {
9 |
10 | /**
11 | * @param args
12 | */
13 | public static void main(String[] args) {
14 | // TODO Auto-generated method stub
15 | //snapshot_index_stu
16 | FileMgr mgr = new FileMgr("J:\\tennbase");
17 | byte[] buffer = new byte[4];
18 | for(int i = 0 ; i < 4; ++i)
19 | buffer[i] = (byte) i;
20 | try{
21 | mgr.writeBuffer("snapshot_index_stu", buffer, 0);
22 | } catch (IOException e) {
23 | e.printStackTrace();
24 | }
25 |
26 | try {
27 | for(int i = 0 ; i < 4; ++i)
28 | buffer[i] = (byte) 0;
29 | mgr.readBuffer("snapshot_index_stu", buffer, 0);
30 |
31 | for(int i = 0 ; i < 4; ++i)
32 | System.out.println("readBuffer " + i + ", " + buffer[i]);
33 |
34 |
35 | } catch (IOException e) {
36 | e.printStackTrace();
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/tenndb/test/TestIndexMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.test;
2 |
3 | import java.nio.ByteBuffer;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import tenndb.bstar.IdxBlock;
8 | import tenndb.common.FileMgr;
9 | import tenndb.index.IBTree;
10 | import tenndb.index.IndexMgr;
11 | import tenndb.tx.AbortTransException;
12 | import tenndb.tx.Trans;
13 | import tenndb.tx.TransMgr;
14 |
15 | public class TestIndexMgr {
16 |
17 | /**
18 | * @param args
19 | */
20 | public static void main(String[] args) {
21 |
22 | TransMgr trasMgr = new TransMgr();
23 | FileMgr fileMgr = new FileMgr("J:\\tennbase\\");
24 | IndexMgr indexMgr = new IndexMgr("stu", fileMgr, trasMgr);
25 | indexMgr.load();
26 | IBTree tree = indexMgr.getBTree();
27 | // Trans tid = new Trans();
28 | for(int i = 0; i < 100; ++i){
29 | int key = i;
30 | IdxBlock blk = new IdxBlock(key);
31 | blk.setPageID(i);
32 | blk.setOffset(1);
33 | /* try {
34 | tree.insert(key, blk, null, null);
35 | } catch (AbortTransException e) {
36 | // TODO Auto-generated catch block
37 | e.printStackTrace();
38 | }*/
39 | }
40 |
41 | List bufferList = new ArrayList();
42 | /*
43 | try{
44 | tree.toByteBuffer(bufferList);
45 | }catch(Exception e)
46 | {
47 | System.out.println(e);
48 | }*/
49 |
50 | System.out.println("toByteBuffer, bufferList.len = " + bufferList.size());
51 |
52 | tree.printNext();
53 |
54 | // indexMgr.flush();
55 |
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/tenndb/test/TestLogMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.test;
2 |
3 | import java.util.List;
4 |
5 | import tenndb.bstar.IdxBlock;
6 | import tenndb.log.LogMgr;
7 | import tenndb.log.LogRecord;
8 | import tenndb.tx.Trans;
9 |
10 | public class TestLogMgr {
11 |
12 | /**
13 | * @param args
14 | */
15 | public static void main(String[] args) {
16 |
17 | LogMgr logMgr = new LogMgr("tenn", "J:\\tennbase");
18 |
19 | Trans tid = new Trans();
20 |
21 | logMgr.logBegin(tid);
22 |
23 | for(int i = 1; i <= 10; ++i){
24 | IdxBlock newblk = new IdxBlock(i);
25 | newblk.setPageID(3);
26 | newblk.setOffset(i);
27 | newblk.setTag(IdxBlock.VALID);
28 | logMgr.logInsert(tid, i, 1, newblk);
29 | }
30 |
31 | for(int i = 1; i <= 10; ++i){
32 | IdxBlock newblk = new IdxBlock(i);
33 | newblk.setPageID(3);
34 | newblk.setOffset(i);
35 | newblk.setTag(IdxBlock.VALID);
36 |
37 | IdxBlock oldblk = new IdxBlock(i);
38 | oldblk.setPageID(4);
39 | oldblk.setOffset(i);
40 | oldblk.setTag(IdxBlock.VALID);
41 |
42 | logMgr.logUpdate(tid, i, 1, newblk, oldblk);
43 | }
44 |
45 | logMgr.logCommit(tid);
46 |
47 | List list = logMgr.loadLogRecord();
48 |
49 | if(null != list){
50 | for(int i = 0; i < list.size(); ++i){
51 | LogRecord record = list.get(i);
52 |
53 | System.out.println("tid = " + record.getTid() + ", type = " + record.getType() + ", key = " + record.getKey()
54 | + ", state = " + record.getState() + ", pos = " + record.getPrePos()
55 | + ", nPid = " + record.getNewPid() + ", nOffSet = " + record.getNewOffset() + ", nTag = " + record.getNewTag()
56 | + ", oPid = " + record.getOldPid() + ", oOffSet = " + record.getOldOffset() + ", oTag = " + record.getOldTag());
57 | }
58 | }
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/tenndb/test/TestRun.java:
--------------------------------------------------------------------------------
1 | package tenndb.test;
2 |
3 | public class TestRun {
4 |
5 | /**
6 | * @param args
7 | */
8 | public static void main(String[] args) {
9 |
10 | Runtime.getRuntime().addShutdownHook(new Thread() {
11 | public void run() { System.out.println("wwwwww"); }
12 | });
13 |
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/tenndb/test/TestTennBase.java:
--------------------------------------------------------------------------------
1 | package tenndb.test;
2 |
3 |
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 | import java.util.Random;
7 |
8 | import tenndb.base.Catalog;
9 | import tenndb.base.Cell;
10 | import tenndb.base.TennBase;
11 | import tenndb.common.DateFormatUtil;
12 | import tenndb.data.Colunm;
13 | import tenndb.data.Filed;
14 | import tenndb.tx.AbortTransException;
15 | import tenndb.tx.Trans;
16 |
17 | public class TestTennBase {
18 |
19 |
20 | private static final ThreadLocal LOG_DATE_FORMAT =
21 | DateFormatUtil.threadLocalDateFormat("yyyy-MM-dd HH:mm:ss");
22 |
23 | /**
24 | * @param args
25 | */
26 | public static void main(String[] args) {
27 | Catalog catalog = TennBase.getCatalog();
28 |
29 | SimpleDateFormat df = LOG_DATE_FORMAT.get();
30 |
31 | String dbStudent = "student";
32 | String dbDepartment = "department";
33 | int dbStudentID = 1;
34 | int dbDepartmentID = 2;
35 | if(null != catalog){
36 |
37 | // tid = null;
38 |
39 | catalog.addCell(dbStudent, dbStudentID);
40 | // catalog.addCell(dbDepartment);
41 | Cell cellStu = catalog.getCell(dbStudent);
42 |
43 | long t1 = System.currentTimeMillis();
44 |
45 | // cellStu.print();
46 | for(int i = 1; i <= 200000; ++i){
47 | // for(int i = 100000; i >= 1; --i){
48 | Random r = new Random();
49 |
50 | int p = r.nextInt(10000000);
51 | // String key = "helloworld_" + p;
52 | String key = "hello_" + i;
53 | Colunm colunm = new Colunm(key, 1);
54 | colunm.addFiled(new Filed("var1", key + 1));
55 | colunm.addFiled(new Filed("var2", key + 2));
56 | colunm.addFiled(new Filed("var3", key + 3));
57 | colunm.addFiled(new Filed("var4", key + 4));
58 | colunm.addFiled(new Filed("var5", key + 5));
59 | colunm.addFiled(new Filed("var6", key + 6));
60 |
61 | cellStu.insert(colunm.getHashCode(), colunm);
62 | }
63 |
64 | // cellStu.print();
65 |
66 | {
67 | int num = 0;
68 | //for(int i = 1; i <= 100000; i*=10){
69 | for(int i = 1; i <= 200000; ++i){
70 | String key = "hello_" + i;
71 |
72 | Colunm colunm = cellStu.search(key.hashCode());
73 | if(null != colunm)
74 | {
75 | /* System.out.println("search" + i + " : " + colunm.getKey() + ", " + df.format(new Date(colunm.getTime()*1000L)) + ", " + colunm.getVersion() + ", " + colunm.getLen());
76 | for(int t = 0; t < colunm.getFileds().size(); ++t){
77 | Filed filed = colunm.getFileds().get(t);
78 | System.out.println(" " + filed.getName() + ", " + filed.getValue());
79 | }*/
80 | }
81 | else{
82 | ++num;
83 | System.out.println("+++++++++++++++++++++++++++++++++ miss " + i);
84 | }
85 | }
86 | System.out.println(" miss " + num);
87 | }
88 |
89 | {
90 | Colunm str = cellStu.search(99477, null);
91 | System.out.println("search " + str);
92 | }
93 |
94 | /* Trans trans = catalog.beginTrans();
95 | for(int i = 1; i <= 10000; ++i){
96 |
97 | String str = i + "_helloworld";
98 | try {
99 | cellStu.insert(i, str, trans);
100 | } catch (AbortTransException e) {
101 | System.out.println(e);
102 | }
103 |
104 | }*/
105 | long t2 = System.currentTimeMillis();
106 |
107 | // catalog.commit(trans);
108 |
109 | int count = 0;
110 | /* for(int i = 100001; i <= 200000; ++i){
111 | String str = cellStu.search(i);
112 | if(null == str || str.length() == 0){
113 | count++;
114 | }
115 | }*/
116 |
117 | long t3 = System.currentTimeMillis();
118 |
119 | // Cell cellDep = catalog.getCell(dbDepartment);
120 |
121 | //0123456789
122 | //abcdefghij
123 | //kmnpqrstuv
124 | //wsyz_
125 | //35
126 |
127 | // cellStu.print();
128 |
129 | /* {
130 | TransID tid = catalog.getTransID();
131 | System.out.println("transID = " + tid.getTransID());
132 | // tid = null;
133 | for(int i = 1; i <= 100; ++i){
134 | boolean b = cellStu.insert(i, i +"_student_3", tid);
135 | System.out.println("insert.x " + b);
136 | TransID tid2 = catalog.getTransID();
137 | boolean b2 = cellStu.insert(i, i +"_student_4", tid2);
138 | System.out.println("insert.y " + b2);
139 | catalog.commit(tid2);
140 |
141 | }
142 |
143 | catalog.commit(tid);
144 | }*/
145 |
146 | /* for(int t = 0; t < 100; ++t)
147 | {
148 | TransID tid = catalog.beginTrans();
149 | System.out.println("transID = " + tid.getTransID());
150 | // tid = null;
151 | for(int i = 1; i <= 1000; ++i){
152 | boolean b = cellStu.insert(t*100 + i, (t*100 + i) +"_student_" + (t*100 + i), tid);
153 | }
154 |
155 | catalog.commit(tid);
156 | }*/
157 |
158 | /* {
159 | TransID tid = catalog.getTransID();
160 | System.out.println("transID = " + tid.getTransID());
161 | // tid = null;
162 | for(int i = 1; i <= 10; ++i){
163 | TransID tid2 = catalog.getTransID();
164 | cellStu.update(i, i +"_student_2", tid);
165 | cellStu.delete(i, tid2);
166 | catalog.commit(tid2);
167 | }
168 |
169 | catalog.commit(tid);
170 | }*/
171 |
172 | /* System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
173 |
174 | {
175 | Trans tid = catalog.beginTrans();
176 | System.out.println("transID = " + tid.getTransID());
177 | for(int i = 1; i <= 10; ++i){
178 | String str = cellStu.search(i, tid);
179 | System.out.println("search" + i + " : " + str);
180 | }
181 | catalog.commit(tid);
182 | }
183 |
184 | System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");*/
185 | /*
186 |
187 |
188 | {
189 | TransID tid = catalog.getTransID();
190 | System.out.println("transID = " + tid.getTransID());
191 | // tid = null;
192 | for(int i = 1; i <= 10; ++i){
193 | cellStu.insert(i, i +"_student_2", tid);
194 | }
195 |
196 | catalog.commit(tid);
197 | }
198 |
199 |
200 | {
201 | TransID tid = catalog.getTransID();
202 | System.out.println("transID = " + tid.getTransID());
203 | for(int i = 1; i <= 10; ++i){
204 | String str = cellStu.search(i, tid);
205 | System.out.println("search" + i + " : " + str);
206 | }
207 | catalog.commit(tid);
208 | }
209 | */
210 | // catalog.flush();
211 |
212 | // cellStu.print();
213 |
214 | // cellDep.print();
215 | }
216 |
217 | }
218 |
219 | }
220 |
--------------------------------------------------------------------------------
/src/tenndb/thread/DistThread.java:
--------------------------------------------------------------------------------
1 | package tenndb.thread;
2 |
3 | import java.util.List;
4 |
5 | import tenndb.dist.DistPage;
6 | import tenndb.dist.DistMgr;
7 |
8 | public class DistThread extends Thread {
9 |
10 | protected DistMgr pageMgr = null;
11 |
12 | public DistThread(DistMgr pageMgr) {
13 | super();
14 | this.pageMgr = pageMgr;
15 | }
16 |
17 | public void run(){
18 |
19 | while(true){
20 | try{
21 | if(null != this.pageMgr){
22 | List list = this.pageMgr.getAndClearUsedList();
23 | if(null != list && list.size() > 0){
24 | System.out.println(list.size());
25 | for(DistPage page : list){
26 | String fileName = this.pageMgr.newFileName();
27 | System.out.println("fileName = " + fileName) ;
28 | this.pageMgr.flush(page, fileName);
29 | }
30 | }
31 | }
32 | }catch(Exception e){}
33 | finally{
34 | try {
35 | Thread.sleep(3000);
36 | } catch (InterruptedException e) {
37 | e.printStackTrace();
38 | }
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/tenndb/thread/FlushHook.java:
--------------------------------------------------------------------------------
1 | package tenndb.thread;
2 |
3 | import java.util.Date;
4 |
5 | import tenndb.base.Cell;
6 | import tenndb.bstar.RandomInsertBStarTree;
7 | import tenndb.common.SystemTime;
8 |
9 | public class FlushHook extends Thread {
10 |
11 | protected Cell cell = null;
12 | protected int lastTime = 0;
13 | public FlushHook(Cell cell) {
14 | super();
15 | this.cell = cell;
16 | this.lastTime = SystemTime.getSystemTime().currentTime();
17 | }
18 |
19 | public void run(){
20 | while(true){
21 | try{
22 | if(null != this.cell){
23 | RandomInsertBStarTree tree = (RandomInsertBStarTree) this.cell.getIndex();
24 | boolean next = false;
25 | tree.lockWrite();
26 | next = this.cell.flushNewPages();
27 |
28 | int current = SystemTime.getSystemTime().currentTime();
29 |
30 | if(next || (current > (this.lastTime + 60))){
31 | long t1 = System.currentTimeMillis();
32 | this.cell.flush();
33 | long t2 = System.currentTimeMillis();
34 | System.out.println("flush, cost = " + (t2 - t1) + ", " + new Date());
35 | this.lastTime = current;
36 | }
37 |
38 | tree.unLockWrite();
39 | }
40 | }catch(Exception e){
41 | System.out.println(e);
42 | }
43 | finally{
44 | try {
45 | Thread.sleep(3000);
46 | } catch (InterruptedException e) {
47 | e.printStackTrace();
48 | }
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/tenndb/thread/ImportThread.java:
--------------------------------------------------------------------------------
1 | package tenndb.thread;
2 |
3 | import java.nio.ByteBuffer;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Date;
6 |
7 | import tenndb.base.Cell;
8 | import tenndb.common.ByteUtil;
9 | import tenndb.common.DateFormatUtil;
10 | import tenndb.common.FileMgr;
11 | import tenndb.dist.DistPage;
12 | import tenndb.dist.DistMgr;
13 | import tenndb.route.RouteMgr;
14 |
15 | public class ImportThread extends Thread {
16 |
17 | protected FileMgr fileMgr;
18 | protected RouteMgr routeMgr;
19 |
20 | protected final ByteBuffer buffer;
21 | protected final byte[] buff;
22 |
23 | private static final ThreadLocal LOG_DATE_FORMAT =
24 | DateFormatUtil.threadLocalDateFormat("yyyyMMdd");
25 |
26 | public ImportThread(FileMgr fileMgr, RouteMgr routeMgr) {
27 | super();
28 | this.fileMgr = fileMgr;
29 | this.routeMgr = routeMgr;
30 | this.buffer = ByteBuffer.allocate(DistPage.PAGE_SIZE);
31 | this.buff = new byte[DistPage.PAGE_SIZE];
32 | }
33 |
34 | public void run(){
35 | this.reflush(DistMgr.PREFIX_TEMP + DistMgr.PREFIX_QUEUE);
36 |
37 | while(true)
38 | {
39 | try{
40 | this.reflush(DistMgr.PREFIX_QUEUE);
41 | }catch(Exception e){
42 | System.out.println(e);
43 | }finally{
44 | try {
45 | Thread.sleep(3000);
46 | } catch (InterruptedException e) {
47 | e.printStackTrace();
48 | }
49 | }
50 | }
51 | }
52 |
53 | public void reflush(String prefix){
54 | if(null != prefix && prefix.length() > 0){
55 | String[] files = this.fileMgr.listFiles();
56 | if(null != files && files.length > 0){
57 |
58 | SimpleDateFormat df = LOG_DATE_FORMAT.get();
59 |
60 | for(String fileName : files){
61 |
62 | if(fileName.startsWith(prefix)){
63 | // System.out.println("fileName = " + fileName);
64 | try {
65 | this.buffer.clear();
66 | this.fileMgr.readBuffer(fileName, this.buffer.array(), 0);
67 |
68 | /*
69 | buffer.put(devIDArray); //10
70 | buffer.putInt(time); //4
71 | buffer.putShort((short) 8);//2
72 | buffer.putInt(lng + i); //4
73 | buffer.putInt(lat + i); //4
74 | */
75 | this.buffer.rewind();
76 | while(buffer.remaining() > 0){
77 | byte tag = this.buffer.get();
78 |
79 | if(DistMgr.TAG_NULL == tag){
80 | break;
81 | }
82 |
83 | byte[] devArray = new byte[10];
84 |
85 | this.buffer.get(devArray);
86 |
87 | String strDevID = new String(devArray);
88 |
89 | int time = this.buffer.getInt();
90 | int len = this.buffer.getShort();
91 | // System.out.println("len = " + len);
92 |
93 | if(len < 0){
94 | len += ByteUtil.SHORT_MAX_VALUE;
95 | }
96 | if(len > 0){
97 | this.buffer.get(buff, 0, len);
98 | }
99 |
100 | String strDate = df.format(new Date(time * 1000L));
101 | // System.out.println("pinLevel2: strDate = " + strDate + ", strDevID = " + strDevID);
102 |
103 | Cell cell = this.routeMgr.pinLevel2(strDate, strDevID);
104 | if(null != cell){
105 | // System.out.println("insert: time = " + time + ", len = " + len);
106 | cell.insert(time, this.buff, 0, len);
107 | }
108 | }
109 |
110 | } catch (Exception e) {
111 | System.out.println(e);
112 | }
113 |
114 | // String newFileName = DistMgr.PREFIX_DELETE + fileName;
115 |
116 | this.fileMgr.delete(fileName);
117 |
118 | // break;
119 | }
120 |
121 | try {
122 | Thread.sleep(10);
123 | } catch (InterruptedException e) {
124 | e.printStackTrace();
125 | }
126 |
127 | }
128 | }
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/tenndb/thread/ShutdownHook.java:
--------------------------------------------------------------------------------
1 | package tenndb.thread;
2 |
3 | import tenndb.base.Catalog;
4 |
5 | public class ShutdownHook extends Thread {
6 |
7 | protected Catalog catalog = null;
8 |
9 | public ShutdownHook(Catalog catalog) {
10 | super();
11 | this.catalog = catalog;
12 | }
13 |
14 | public void run(){
15 | System.out.println("+ShutdownHook");
16 | this.catalog.flush();
17 | System.out.println("-ShutdownHook");
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/tenndb/threadtest/InsertThread.java:
--------------------------------------------------------------------------------
1 | package tenndb.threadtest;
2 |
3 | import tenndb.base.Cell;
4 | import tenndb.data.Colunm;
5 | import tenndb.data.Filed;
6 |
7 | public class InsertThread extends Thread {
8 |
9 | protected Cell cell;
10 |
11 | public InsertThread(Cell cell) {
12 | super();
13 | this.cell = cell;
14 | }
15 |
16 | public void run(){
17 |
18 |
19 | // while(true)
20 | {
21 | for(int i = 1; i <= 1000; ++i){
22 |
23 | String key = i + "_helloworld_";
24 |
25 | Colunm colunm = new Colunm(key, 1);
26 | colunm.addFiled(new Filed("var1", key + 1));
27 | /* colunm.addFiled(new Filed("var2", key + 2));
28 | colunm.addFiled(new Filed("var3", key + 3));
29 | colunm.addFiled(new Filed("var4", key + 4));
30 | colunm.addFiled(new Filed("var5", key + 5));
31 | colunm.addFiled(new Filed("var6", key + 6));*/
32 | this.cell.insert(i, colunm);
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/tenndb/threadtest/TestTennBase.java:
--------------------------------------------------------------------------------
1 | package tenndb.threadtest;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import tenndb.base.Catalog;
7 | import tenndb.base.Cell;
8 | import tenndb.base.TennBase;
9 |
10 | public class TestTennBase {
11 |
12 | /**
13 | * @param args
14 | */
15 | public static void main(String[] args) {
16 |
17 | Catalog catalog = TennBase.getCatalog();
18 | String dbStudent = "student";
19 | int dbStudentID = 1;
20 | catalog.addCell(dbStudent, dbStudentID);
21 | Cell cellStu = catalog.getCell(dbStudent);
22 |
23 | List list = new ArrayList();
24 |
25 | for(int i = 0; i < 10; ++i){
26 | InsertThread thread = new InsertThread(cellStu);
27 | list.add(thread);
28 | }
29 |
30 | for(InsertThread thread : list){
31 | thread.start();
32 | }
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/tenndb/tx/AbortTransException.java:
--------------------------------------------------------------------------------
1 | package tenndb.tx;
2 |
3 | public class AbortTransException extends Exception {
4 |
5 | /**
6 | *
7 | */
8 | private static final long serialVersionUID = 4369948384114813894L;
9 |
10 | public AbortTransException(String message) {
11 | super(message);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/tenndb/tx/BlkID.java:
--------------------------------------------------------------------------------
1 | package tenndb.tx;
2 |
3 | import java.io.Serializable;
4 |
5 | import tenndb.index.IndexPage;
6 |
7 | public class BlkID implements Serializable {
8 |
9 | private static final long serialVersionUID = -2731980102685155241L;
10 |
11 | protected String dbName;
12 | protected int key;
13 |
14 | protected IndexPage page;
15 | protected Trans transactionID;
16 |
17 | public BlkID(String dbName, int key) {
18 | super();
19 | this.dbName = dbName;
20 | this.key = key;
21 | }
22 |
23 | public String getDbName() {
24 | return dbName;
25 | }
26 |
27 | public void setDbName(String dbName) {
28 | this.dbName = dbName;
29 | }
30 |
31 | public void setKey(int key) {
32 | this.key = key;
33 | }
34 |
35 | public IndexPage getPage() {
36 | return page;
37 | }
38 |
39 | public void setPage(IndexPage page) {
40 | this.page = page;
41 | }
42 |
43 | public Trans getTransactionID() {
44 | return transactionID;
45 | }
46 |
47 | public void setTransactionID(Trans transactionID) {
48 | this.transactionID = transactionID;
49 | }
50 |
51 | public int getKey(){
52 | return this.key;
53 | }
54 |
55 | public String getSeq(){
56 | return this.dbName + "_" + this.key;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/tenndb/tx/Trans.java:
--------------------------------------------------------------------------------
1 | package tenndb.tx;
2 |
3 | import java.io.Serializable;
4 | import java.util.concurrent.atomic.AtomicInteger;
5 |
6 | public class Trans implements Serializable {
7 |
8 | private static final long serialVersionUID = -3717435910507148488L;
9 |
10 | protected static AtomicInteger _counter = new AtomicInteger(1);
11 |
12 | protected int transID = 0;
13 |
14 | protected byte state;
15 |
16 | public static final byte INVALID = 0;
17 | public static final byte START = 1;
18 | public static final byte ACTIVE = 2;
19 | public static final byte TERMINATED = 3;
20 |
21 | public static final byte COMMIT = 4;
22 | public static final byte ROLLBACK = 5;
23 |
24 | public static final byte REDO = 6;
25 | public static final byte UNDO = 7;
26 |
27 | //normal
28 | // COMMITED
29 | // START -> ACTIVE -> -> TERMINATED
30 | // ROLLBACK
31 | //
32 |
33 | //crashdown
34 | //COMMITED -> REDO
35 | //ROLLBACK -> UNDO
36 |
37 | public Trans(){
38 | this.transID = _counter.getAndIncrement();
39 | this.state = ACTIVE;
40 | }
41 |
42 | public int getState() {
43 | return state;
44 | }
45 |
46 | public void setState(byte state) {
47 | this.state = state;
48 | }
49 |
50 | public int getTransID(){
51 | return this.transID;
52 | }
53 |
54 | public int hashCode(){
55 | return this.transID;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/tenndb/tx/TransMgr.java:
--------------------------------------------------------------------------------
1 | package tenndb.tx;
2 |
3 | import java.util.ArrayList;
4 | import java.util.concurrent.ConcurrentHashMap;
5 | import java.util.concurrent.locks.ReadWriteLock;
6 | import java.util.concurrent.locks.ReentrantReadWriteLock;
7 |
8 |
9 | public class TransMgr {
10 |
11 | protected ConcurrentHashMap blkTrans;
12 |
13 | protected ConcurrentHashMap> transBlks;
14 |
15 | protected ConcurrentHashMap transState;
16 |
17 | public TransMgr(){
18 |
19 | this.blkTrans = new ConcurrentHashMap();
20 | this.transBlks = new ConcurrentHashMap>();
21 | this.transState = new ConcurrentHashMap();
22 | }
23 |
24 | protected ReadWriteLock lock = new ReentrantReadWriteLock(false);
25 |
26 | protected void lockRead() { this.lock.readLock().lock(); }
27 |
28 | protected void unLockRead() { this.lock.readLock().unlock(); }
29 |
30 | protected void lockWrite() { this.lock.writeLock().lock(); }
31 |
32 | protected void unLockWrite() { this.lock.writeLock().unlock(); }
33 |
34 |
35 | public synchronized void delTransBlks(Trans tid){
36 | if(null != tid){
37 | ArrayList blkList = this.transBlks.get(tid);
38 |
39 | if(null != blkList){
40 | for(BlkID blk : blkList){
41 | this.blkTrans.remove(blk.getSeq());
42 | }
43 | }
44 |
45 | this.transBlks.remove(tid);
46 | this.transState.remove(tid);
47 | }
48 | }
49 |
50 | public synchronized void setTransState(Trans tid, byte state){
51 | if(null != tid){
52 | this.transState.put(tid, state);
53 | }
54 | }
55 |
56 | public synchronized byte getTransState(Trans tid){
57 | byte state = Trans.INVALID;
58 |
59 | if(null != tid){
60 | Byte var = this.transState.get(tid);
61 | if(null != var){
62 | state = var.byteValue();
63 | }
64 | }
65 | return state;
66 | }
67 |
68 | public synchronized ArrayList getTransBlks(Trans tid){
69 | ArrayList blkList = null;
70 |
71 | if(null != tid){
72 | blkList = this.transBlks.get(tid);
73 | }
74 | return blkList;
75 | }
76 |
77 | public synchronized boolean unlockBlk(Trans tid){
78 | boolean b = false;
79 |
80 | if(null != tid){
81 | this.transBlks.remove(tid);
82 | ArrayList blkList = this.transBlks.get(tid);
83 | if(null != blkList && blkList.size() > 0){
84 | for(BlkID blk : blkList){
85 | this.blkTrans.remove(blk.getSeq());
86 | }
87 | }
88 | b = true;
89 | }
90 |
91 | return b;
92 | }
93 |
94 | /* public synchronized boolean lockBlk(BlkID bid, Trans tid){
95 | boolean b = false;
96 |
97 | if(null != bid && null != tid){
98 | Trans trans = this.blkTrans.get(bid.getSeq());
99 | if(null == trans || trans.equals(tid)){
100 |
101 | if(null == trans){
102 | this.blkTrans.put(bid.getSeq(), tid);
103 | }
104 |
105 | ArrayList blkList = this.transBlks.get(tid);
106 |
107 | if(null == blkList){
108 | blkList = new ArrayList();
109 | this.transBlks.put(tid, blkList);
110 | }
111 | boolean had = false;
112 | for(BlkID tmp : blkList){
113 | if(tmp.getSeq().equals(bid.getSeq())){
114 | had = true;
115 | break;
116 | }
117 | }
118 |
119 | if(false == had){
120 | // System.out.println("lockBlk " + bid.getSeq());
121 | blkList.add(bid);
122 | }
123 |
124 | b = true;
125 | }
126 | }
127 |
128 | return b;
129 | }*/
130 |
131 | public synchronized boolean lockBlk(BlkID bid, Trans tid){
132 | boolean b = false;
133 |
134 | if(null != bid && null != tid){
135 | Trans trans = this.blkTrans.get(bid.getSeq());
136 | if(null == trans || trans.equals(tid)){
137 |
138 | if(null == trans){
139 | this.blkTrans.put(bid.getSeq(), tid);
140 | }
141 |
142 | ArrayList blkList = this.transBlks.get(tid);
143 |
144 | if(null == blkList){
145 | blkList = new ArrayList();
146 | this.transBlks.put(tid, blkList);
147 | }
148 | blkList.add(bid);
149 |
150 | b = true;
151 | }
152 | }
153 |
154 | return b;
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/tenndb/txtest/TestInsertTx.java:
--------------------------------------------------------------------------------
1 | package tenndb.txtest;
2 |
3 | import tenndb.base.Catalog;
4 | import tenndb.base.Cell;
5 | import tenndb.base.TennBase;
6 | import tenndb.data.Colunm;
7 | import tenndb.data.Filed;
8 | import tenndb.tx.AbortTransException;
9 | import tenndb.tx.Trans;
10 |
11 | public class TestInsertTx {
12 |
13 | /**
14 | * @param args
15 | */
16 | public static void main(String[] args) {
17 |
18 | Catalog catalog = TennBase.getCatalog();
19 | String dbStudent = "student";
20 | int dbStudentID = 1;
21 | catalog.addCell(dbStudent, dbStudentID);
22 | Cell cellStu = catalog.getCell(dbStudent);
23 |
24 | Trans trans1 = catalog.beginTrans();
25 | Trans trans2 = catalog.beginTrans();
26 | /*
27 | for(int i = 1; i < 100; i+=2){
28 | String str1 = i + "_helloworld1_";
29 | String str2 = i+1 + "_helloworld2_";
30 | try {
31 | cellStu.insert(i, str1, trans1);
32 | } catch (AbortTransException e) {
33 | System.out.println(e);
34 | e.printStackTrace();
35 | }
36 |
37 | try {
38 | cellStu.insert(i+1, str2, trans2);
39 | } catch (AbortTransException e) {
40 | System.out.println(e);
41 | e.printStackTrace();
42 | }
43 | }
44 |
45 | {
46 | String str = 99 + "_helloworld2_";
47 | try {
48 | cellStu.insert(99, str, trans2);
49 | } catch (AbortTransException e) {
50 | // TODO Auto-generated catch block
51 | e.printStackTrace();
52 | }
53 | }
54 |
55 | {
56 | String str = 98 + "_helloworld2_";
57 | try {
58 | cellStu.insert(98, str, trans1);
59 | } catch (AbortTransException e) {
60 | // TODO Auto-generated catch block
61 | e.printStackTrace();
62 | }
63 | }*/
64 |
65 |
66 |
67 | {
68 | int key = 1;
69 | String str = key + "_helloworld_1";
70 | try {
71 | Colunm colunm = new Colunm(str, 1);
72 | colunm.addFiled(new Filed("var1", str + 1));
73 |
74 | cellStu.insert(key, colunm, trans1);
75 | } catch (AbortTransException e) {
76 | // TODO Auto-generated catch block
77 | e.printStackTrace();
78 | catalog.rollback(trans1);
79 | }
80 | }
81 |
82 |
83 | {
84 | int key = 2;
85 | String str = key + "_helloworld_2";
86 | try {
87 | Colunm colunm = new Colunm(str, 1);
88 | colunm.addFiled(new Filed("var1", str + 1));
89 |
90 | cellStu.insert(key, colunm, trans2);
91 | } catch (AbortTransException e) {
92 | // TODO Auto-generated catch block
93 | e.printStackTrace();
94 | catalog.rollback(trans2);
95 | }
96 | }
97 |
98 |
99 | {
100 | int key = 1;
101 | String str = key + "_helloworld_2";
102 | try {
103 | Colunm colunm = new Colunm(str, 1);
104 | colunm.addFiled(new Filed("var1", str + 1));
105 |
106 | cellStu.insert(key, colunm, trans2);
107 | } catch (AbortTransException e) {
108 | // TODO Auto-generated catch block
109 | e.printStackTrace();
110 | catalog.rollback(trans2);
111 | }
112 | }
113 |
114 |
115 | {
116 | int key = 2;
117 | String str = key + "_helloworld_1";
118 | try {
119 | Colunm colunm = new Colunm(str, 1);
120 | colunm.addFiled(new Filed("var1", str + 1));
121 |
122 | cellStu.insert(key, colunm, trans1);
123 | } catch (AbortTransException e) {
124 | // TODO Auto-generated catch block
125 | e.printStackTrace();
126 | catalog.rollback(trans1);
127 | }
128 | }
129 |
130 |
131 |
132 |
133 | // catalog.rollback(trans);
134 | // catalog.commit(trans1);
135 | // catalog.commit(trans2);
136 |
137 | for(int i = 1; i <= 100000; ++i){
138 | Colunm colunm = cellStu.search(i, null);
139 | if(null != colunm){
140 | System.out.println("search" + i + " : " + colunm.getKey());
141 | }
142 | }
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/简易数据库存储系统的JAVA实现.ppt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tenn-cn/TennBase/bd67a825100b565d58f0153cbfc2f848cb298367/简易数据库存储系统的JAVA实现.ppt
--------------------------------------------------------------------------------
| |