# coding : utf-8 =begin ============================================================= Copyright (C) 2013 BizStation Corp All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. =================================================================== =end require 'date' require 'transactd' TYPE_SCHEMA_BDF = 0 USE_NORMAL = 0 USE_TRANS = 1 USE_BALKINS = 2 USE_SNAPSHOT = 4 FN_ID = 0 FN_NAME = 1 AUTO_CREATE_TABLE = true PARALLEL_TRN = 1000 LOCK_SINGLE_NOWAIT = 200 TRANS_BIAS = PARALLEL_TRN + LOCK_SINGLE_NOWAIT BULKBUFSIZE = 65535 - 1000 ## -------------------------------------------------------------------------------- def showTableError(tb, description) if (tb.stat() != 0) puts("#{description} error #{tb.tableDef().fileName()}:No.#{tb.stat().to_s}") end end ## -------------------------------------------------------------------------------- def showEnginError(db, tableName) if (db.stat() != 0) puts("#{tableName} error No.#{db.stat().to_s}") end end ## -------------------------------------------------------------------------------- def openTable(db, tableName, mode) tb = db.openTable(tableName, mode, AUTO_CREATE_TABLE) showEnginError(db, tableName) if (tb == nil) return tb end ## -------------------------------------------------------------------------------- def createDataBase(db, uri) db.create(uri) return (db.stat() == 0) end ## -------------------------------------------------------------------------------- def write(tb, start, endid) tb.setKeyNum(0) for i in start..(endid - 1) do tb.clearBuffer() tb.setFV(FN_ID, i) tb.setFV(FN_NAME, i) tb.insert() if (tb.stat() != 0) showTableError(tb, 'write') return false end end return true end ## -------------------------------------------------------------------------------- def deleteAll(db, tb, start, endid) db.beginTrn(TRANS_BIAS) tb.clearBuffer() for i in start..(endid - 1) do tb.setFV(FN_ID, i) tb.seek() if (tb.stat() == 0) tb.del() if (tb.stat() != 0) showTableError(tb, 'deleteAll') db.endTrn() return false end end end db.endTrn() return true end ## -------------------------------------------------------------------------------- def Inserts(db, tb, start, endid, mode, unit) ret = true total = endid - start count = total / unit st = start en = st while (en != endid) do en = st + unit db.beginTrn(TRANS_BIAS) if (mode == USE_TRANS) tb.beginBulkInsert(BULKBUFSIZE) if (mode == USE_BALKINS) ret = write(tb, st, en) tb.commitBulkInsert() if (mode == USE_BALKINS) db.endTrn() if (mode == USE_TRANS) break if (ret == false) st = en end return ret end ## -------------------------------------------------------------------------------- def Read(db, tb, start, endid, shapshot) ret = true tb.clearBuffer() db.beginSnapshot() if (shapshot == USE_SNAPSHOT) for i in start..(endid - 1) do tb.setFV(FN_ID, i) tb.seek() if ((tb.stat() != 0) || (tb.getFVlng(FN_ID) != i)) puts("GetEqual Error stat() = #{tb.stat().to_s} Value #{i.to_s} = #{tb.getFVlng(FN_ID).to_s}") ret = false break end end db.endSnapshot() if (shapshot == USE_SNAPSHOT) return ret end ## -------------------------------------------------------------------------------- def Reads(db, tb, start, endid, unit, shapshot) ret = true total = endid - start count = total / unit st = start en = st db.beginSnapshot() if (shapshot == USE_SNAPSHOT) tb.setKeyNum(0) tb.setFilter('*', 1, 20) tb.clearBuffer() tb.setFV(FN_ID, st) tb.find(Transactd::Table::FindForword) while (en != endid) en = st + unit for i in st..(en - 1) do if (tb.getFVlng(FN_ID) != i) puts("findNext Error stat() = #{tb.stat().to_s} Value #{i.to_s} = #{tb.getFVlng(FN_ID).to_s}") ret = false break end tb.findNext() end break if (ret == false) st = en end db.endSnapshot() if (shapshot == USE_SNAPSHOT) return ret end ## -------------------------------------------------------------------------------- def Updates(db, tb, start, endid, tran, unit) ret = true tb.setKeyNum(0) total = endid - start count = total / unit st = start en = st while (en != endid) en = st + unit db.beginTrn(TRANS_BIAS) if (tran == USE_TRANS) for i in st..(en - 1) do tb.setFV(FN_ID, i) tb.setFV(FN_NAME, "#{i + 1 + tran}") tb.update(Transactd::Table::ChangeInKey) if (tb.stat() != 0) ret = false break end end db.endTrn() if (tran == USE_TRANS) break if (ret == false) st = en end return ret end ## -------------------------------------------------------------------------------- def createTestDataBase(db, uri) db.create(uri) if (db.stat() != 0) puts("createTestDataBase erorr:No.#{db.stat().to_s} #{uri}") return false end if (db.open(uri, TYPE_SCHEMA_BDF, Transactd::TD_OPEN_NORMAL, '', '')) dbdef = db.dbDef() td = Transactd::Tabledef.new() td.setTableName('user') td.setFileName('user.dat') td.id = 1 # td.primaryKeyNum = -1 # td.parentKeyNum = -1 # td.replicaKeyNum = -1 td.pageSize = 2048 dbdef.insertTable(td) fd = dbdef.insertField(td.id, 0) fd.setName('id') fd.type = Transactd::Ft_integer fd.len = 4 dbdef.updateTableDef(1) fd = dbdef.insertField(td.id, 1) fd.setName('name') fd.type = Transactd::Ft_myvarchar fd.len = 100 dbdef.updateTableDef(td.id) kd = dbdef.insertKey(td.id, 0) kd.segment(0).fieldNum = 0 kd.segment(0).flags.bit8 = 1 # extend key type kd.segment(0).flags.bit1 = 1 # changeable kd.segmentCount = 1 td.primaryKeyNum = 0 dbdef.updateTableDef(td.id) return true else puts("open daatabse erorr No:#{db.stat().to_s}") end return false end ## -------------------------------------------------------------------------------- def printDateTime() puts(DateTime.now.strftime('%Y/%m/%d %H:%M:%S')) end ## -------------------------------------------------------------------------------- def printHeader(uri, count) puts("Start Bench mark Insert Items = #{count.to_s}") printDateTime() puts(uri) puts("----------------------------------------") end ## -------------------------------------------------------------------------------- def printTail() puts("----------------------------------------") end ## -------------------------------------------------------------------------------- def main(argv) if (argv.length < 4) puts("usage: ruby bench_tdclcpp.rb databaseUri processNumber functionNumber noDeleteFlag") puts("\t --- functionNumber list ---") puts("\t-1: all function") puts("\t 0: Insert") puts("\t 1: Insert in transaction. 20rec x 1000times") puts("\t 2: Insert by bulkmode. 20rec x 1000times") puts("\t 3: read each record") puts("\t 4: read each record with snapshot") puts("\t 5: read range. 20rec x 1000times") puts("\t 6: read range with snapshpot. 20rec x 1000times") puts("\t 7: update") puts("\t 8: update in transaction. 20rec x 1000times") puts("example : ruby bench_tdclcpp.rb \"tdap://localhost/test?dbfile=test.bdf\" 0 -1 1") return end uri = argv[1] # "tdap://localhost/test?dbfile=test.bdf" procID = Integer(argv[2]) # 0 count = 20000 start = procID * count + 1 endid = start + count exeType = Integer(argv[3]) # -1 insertBeforeNoDelete = ((argv.length > 4) && (Integer(argv[4]) != 0)) db = Transactd::Database.createObject() if (db.open(uri, TYPE_SCHEMA_BDF, Transactd::TD_OPEN_NORMAL, '', '') == false) if (!createTestDataBase(db, uri)) db.close() return end puts("CreateDataBase success.") end printHeader(uri, count) if (!db.open(uri, TYPE_SCHEMA_BDF, Transactd::TD_OPEN_NORMAL, '', '')) puts("open table erorr No:#{db.stat().to_s}") else tb = openTable(db, 'user', Transactd::TD_OPEN_NORMAL) if tb == nil puts "can not open table 'user'" db.close() return end if ((exeType == -1) || (exeType == 0)) if (insertBeforeNoDelete || deleteAll(db, tb, start, endid)) Transactd::Benchmark::start() succeed = Inserts(db, tb, start, endid, USE_NORMAL, 1) Transactd::Benchmark::showTimeSec(succeed, ': Insert') else puts("deleteAll erorr No:#{tb.stat().to_s}") end end if ((exeType == -1) || (exeType == 1)) if (insertBeforeNoDelete || deleteAll(db, tb, start, endid)) Transactd::Benchmark::start() succeed = Inserts(db, tb, start, endid, USE_TRANS, 20) Transactd::Benchmark::showTimeSec(succeed, ': Insert in transaction. 20rec x 1000times.') else puts("deleteAll erorr No:#{tb.stat().to_s}") end end if ((exeType == -1) || (exeType == 2)) if (insertBeforeNoDelete || deleteAll(db, tb, start, endid)) Transactd::Benchmark::start() succeed = Inserts(db, tb, start, endid, USE_BALKINS, 20) Transactd::Benchmark::showTimeSec(succeed, ': Insert by bulkmode. 20rec x 1000times.') else puts("deleteAll erorr No:#{tb.stat().to_s}") end end if ((exeType == -1) || (exeType == 3)) Transactd::Benchmark::start() succeed = Read(db, tb, start, endid, USE_NORMAL) Transactd::Benchmark::showTimeSec(succeed, 'read each record.') end if ((exeType == -1) || (exeType == 4)) Transactd::Benchmark::start() succeed = Read(db, tb, start, endid, USE_SNAPSHOT) Transactd::Benchmark::showTimeSec(succeed, ': read each record with snapshot.') end if ((exeType == -1) || (exeType == 5)) Transactd::Benchmark::start() succeed = Reads(db, tb, start, endid, 20, USE_NORMAL) Transactd::Benchmark::showTimeSec(succeed, ': read range. 20rec x 1000times.') end if ((exeType == -1) || (exeType == 6)) Transactd::Benchmark::start() succeed = Reads(db, tb, start, endid, 20, USE_SNAPSHOT) Transactd::Benchmark::showTimeSec(succeed, ': read range with snapshpot. 20rec x 1000times.') end if ((exeType == -1) || (exeType == 7)) Transactd::Benchmark::start() succeed = Updates(db, tb, start, endid, USE_NORMAL, 1) Transactd::Benchmark::showTimeSec(succeed, ': update.') end if ((exeType == -1) || (exeType == 8)) Transactd::Benchmark::start() succeed = Updates(db, tb, start, endid, USE_TRANS, 20) Transactd::Benchmark::showTimeSec(succeed, ': update in transaction. 20rec x 1000times.') end end tb.close() db.close() printTail() return end args = ARGV args.unshift(__FILE__) main(args)