From 90d17d538f82ebb50236ae138e147f4a10f4e365 Mon Sep 17 00:00:00 2001 From: prabatuty Date: Sat, 31 Jan 2009 08:41:30 +0000 Subject: [PATCH] performance fixes for JDBC wisc benchmark --- include/Allocator.h | 2 + include/DataType.h | 2 +- include/PredicateImpl.h | 2 + include/os.h | 2 + src/odbc/Makefile | 2 +- src/server/ChunkIterator.cxx | 10 +- src/storage/AggTableImpl.cxx | 4 +- src/storage/ChunkIterator.cxx | 6 - src/storage/DataType.cxx | 266 +++++++++++++++++++----------------------- src/storage/PredicateImpl.cxx | 57 ++++----- src/storage/os.cxx | 4 + 11 files changed, 161 insertions(+), 196 deletions(-) diff --git a/include/Allocator.h b/include/Allocator.h index 6f708dbc..783c7327 100644 --- a/include/Allocator.h +++ b/include/Allocator.h @@ -85,6 +85,8 @@ class ChunkIterator int noOfNodes_; public: + ChunkIterator() { allocSize_ =0; iterPage_ = NULL; nodeOffset_ =0; + chunkID_ = -1; noOfNodes_ =0; } void* nextElement(); friend class Chunk; }; diff --git a/include/DataType.h b/include/DataType.h index a394f6fb..1da43578 100644 --- a/include/DataType.h +++ b/include/DataType.h @@ -64,7 +64,7 @@ enum ComparisionOp { OpLessThanEquals, OpGreaterThan, OpGreaterThanEquals, - OpLike, // for Like operator + OpLike, // for Like operator OpInvalidComparisionOp }; static char CompOpNames[][20] = diff --git a/include/PredicateImpl.h b/include/PredicateImpl.h index b0f66950..48d27ae2 100644 --- a/include/PredicateImpl.h +++ b/include/PredicateImpl.h @@ -39,6 +39,7 @@ class PredicateImpl:public Predicate //Members set during execution void *tuple; //pointer to the tuple List *projList; + bool isPushedDown; //This will be set before calling evaluate TableImpl *table; @@ -54,6 +55,7 @@ class PredicateImpl:public Predicate offset1 = -1; offset2 =-1; type = typeUnknown; length = 0; + isPushedDown=false; } ~PredicateImpl(){} diff --git a/include/os.h b/include/os.h index 9a90f8cd..f220912e 100644 --- a/include/os.h +++ b/include/os.h @@ -35,6 +35,7 @@ #include #include #include +#include #if defined(solaris) #include #endif @@ -154,6 +155,7 @@ class os static size_t send(int fd, const void *buf, size_t len, int flags); static size_t recv(int fd, void *buf, size_t len, int flags); static int gethostname(char *hostname, size_t len); + static int strmatch(char *pattern, char *str); }; #endif diff --git a/src/odbc/Makefile b/src/odbc/Makefile index d51b5c30..87ce8acb 100644 --- a/src/odbc/Makefile +++ b/src/odbc/Makefile @@ -94,7 +94,7 @@ CPPFLAGS = CXX = g++ CXXCPP = g++ -E CXXDEPMODE = depmode=gcc3 -CXXFLAGS = -O2 -I/home/praba/csql/jdk1.6.0_06/include -I/home/praba/csql/jdk1.6.0_06/include/linux +CXXFLAGS = -g -I/home/praba/csql/jdk1.6.0_06/include -I/home/praba/csql/jdk1.6.0_06/include/linux CYGPATH_W = echo DEFS = -DHAVE_CONFIG_H DEPDIR = .deps diff --git a/src/server/ChunkIterator.cxx b/src/server/ChunkIterator.cxx index cfd7e08a..a3a63e87 100644 --- a/src/server/ChunkIterator.cxx +++ b/src/server/ChunkIterator.cxx @@ -23,6 +23,10 @@ ChunkIterator Chunk::getIterator() { ChunkIterator iter; + if (0 == allocSize_) { + printError(ErrNotExists,"Iterators are not for variable size allocators"); + return iter; + } iter.chunkID_ = chunkID_; iter.allocSize_ = allocSize_; iter.allocType_ = allocType_; @@ -39,12 +43,6 @@ void* ChunkIterator::nextElement() printError(ErrNotExists,"No iter page exists."); return NULL; } - //No iterators for variable size allocators - if(0 == allocSize_) - { - printError(ErrNotExists,"Iterators are not for variable size allocators"); - return NULL; - } PageInfo* pageInfo = (PageInfo*)iterPage_; if (0 == noOfNodes_) { diff --git a/src/storage/AggTableImpl.cxx b/src/storage/AggTableImpl.cxx index 69dd59e8..76d25d0e 100644 --- a/src/storage/AggTableImpl.cxx +++ b/src/storage/AggTableImpl.cxx @@ -348,12 +348,12 @@ DbRetVal HashMap::insert(void *element) newNode->next = NULL; int hashVal = (*(int*) element) % bucketSize; //printf("Hash val is %d\n", hashVal); - if (bucket[hashVal] == NULL) + HashMapNode *node = (HashMapNode*) bucket[hashVal]; + if (NULL == node) { bucket[hashVal] = newNode; return OK; } - HashMapNode *node = (HashMapNode*) bucket[hashVal]; while(node->next != NULL) ; node->next = newNode; return OK; diff --git a/src/storage/ChunkIterator.cxx b/src/storage/ChunkIterator.cxx index cfd7e08a..63230dc5 100644 --- a/src/storage/ChunkIterator.cxx +++ b/src/storage/ChunkIterator.cxx @@ -39,12 +39,6 @@ void* ChunkIterator::nextElement() printError(ErrNotExists,"No iter page exists."); return NULL; } - //No iterators for variable size allocators - if(0 == allocSize_) - { - printError(ErrNotExists,"Iterators are not for variable size allocators"); - return NULL; - } PageInfo* pageInfo = (PageInfo*)iterPage_; if (0 == noOfNodes_) { diff --git a/src/storage/DataType.cxx b/src/storage/DataType.cxx index 0449f0b4..1f43aca9 100644 --- a/src/storage/DataType.cxx +++ b/src/storage/DataType.cxx @@ -505,59 +505,36 @@ void AllDataType::copyVal(void* dest, void *src, DataType type, int length) return; }else if (typeString == type) { + //null is always put at the last byte by insert + //so using strcpy is safe + //strcpy((char*)dest, (char*)src); strncpy((char*)dest, (char*)src, length); char *d =(char*)dest; d[length-1] = '\0'; return; + }else if (typeShort == type) { + *(short*)dest = *(short*)src; + }else if (typeDouble == type) { + *(double*)dest = *(double*)src; + }else if (typeTimeStamp == type) { + *(TimeStamp*)dest = *(TimeStamp*)src; + }else if (typeDate == type) { + *(Date*)dest = *(Date*)src; + }else if (typeFloat == type) { + *(float*)dest = *(float*)src; + }else if (typeTime == type) { + *(Time*)dest = *(Time*)src; + }else if (typeLong == type) { + *(long*)dest = *(long*)src; + }else if (typeLongLong == type) { + *(long long*)dest = *(long long*)src; + }else if (typeByteInt == type) { + *(char*)dest = *(char*)src; + }else if (typeBinary == type) { + os::memcpy(dest, src, length); + }else if (typeComposite == type) { + os::memcpy(dest, src, length); } - - switch(type) - { - case typeInt: - *(int*)dest = *(int*)src; - break; - case typeLong: - *(long*)dest = *(long*)src; - break; - case typeLongLong: - *(long long*)dest = *(long long*)src; - break; - case typeShort: - *(short*)dest = *(short*)src; - break; - case typeByteInt: - *(char*)dest = *(char*)src; - break; - case typeDouble: - *(double*)dest = *(double*)src; - break; - case typeFloat: - *(float*)dest = *(float*)src; - break; - case typeDecimal: - //TODO::for porting - case typeDate: - *(Date*)dest = *(Date*)src; - break; - case typeTime: - *(Time*)dest = *(Time*)src; - break; - case typeTimeStamp: - *(TimeStamp*)dest = *(TimeStamp*)src; - break; - case typeString: - { - strncpy((char*)dest, (char*)src, length); - char *d =(char*)dest; - d[length-1] = '\0'; - break; - } - case typeBinary: - os::memcpy(dest, src, length); - break; - default: - break; - } return; } void AllDataType::addVal(void* dest, void *src, DataType type) @@ -796,91 +773,81 @@ void AllDataType::divVal(void* dest, int src, DataType type) bool AllDataType::compareVal(void *val1, void *val2, ComparisionOp op, DataType type, long length) { - //Performance optimization. putting likely case first - if (typeInt == type && OpEquals == op) + //Performance optimization. + //do not convert compareXXXVal to virtual functions. it takes more time + if (typeInt == type) { + //as int is the heavily used type, hardcoding the compare here itself + if (OpEquals == op) { if (*(int*)val1 == *(int*)val2) return true; else return false; + }else if (OpGreaterThanEquals == op) { + if (*(int*)val1 >= *(int*)val2) return true; + else return false; + }else if (OpLessThanEquals == op) { + if (*(int*)val1 <= *(int*)val2) return true; + else return false; + }else if (OpGreaterThan == op) { + if (*(int*)val1 > *(int*)val2) return true; + else return false; + }else if (OpLessThan == op) { + if (*(int*)val1 < *(int*)val2) return true; + else return false; + }else if (OpNotEquals == op) { + if (*(int*)val1 != *(int*)val2) return true; + else return false; + } + + }else if(typeString == type) { + return AllDataType::compareStringVal(val1, val2, op); + } else if (typeShort == type) { + return AllDataType::compareShortVal(val1, val2, op); + } else if (typeDouble == type) { + return AllDataType::compareDoubleVal(val1, val2, op); + } else if (typeFloat == type) { + return AllDataType::compareFloatVal(val1, val2, op); + } else if (typeLong == type) { + return AllDataType::compareLongVal(val1, val2, op); + } else if (typeLongLong == type) { + return AllDataType::compareLongLongVal(val1, val2, op); + } else if (typeByteInt == type) { + return AllDataType::compareByteIntVal(val1, val2, op); + } else if (typeTimeStamp == type) { + return AllDataType::compareTimeStampVal(val1, val2, op); + } else if (typeDate == type) { + return AllDataType::compareDateVal(val1, val2, op); + } else if (typeTime == type) { + return AllDataType::compareTimeVal(val1, val2, op); + } else if (typeBinary == type) { + return AllDataType::compareBinaryVal(val1, val2, op, length); + } else if (typeComposite == type) { + return AllDataType::compareBinaryVal(val1, val2, op, length); } - bool result = false; - switch(type) - { - case typeInt: - result = AllDataType::compareIntVal(val1, val2, op); - break; - case typeLong: - result = AllDataType::compareLongVal(val1, val2, op); - break; - case typeLongLong: - result = AllDataType::compareLongLongVal(val1, val2, op); - break; - case typeShort: - result = AllDataType::compareShortVal(val1, val2, op); - break; - case typeByteInt: - result = AllDataType::compareByteIntVal(val1, val2, op); - break; - case typeDouble: - result = AllDataType::compareDoubleVal(val1, val2, op); - break; - case typeFloat: - result = AllDataType::compareFloatVal(val1, val2, op); - break; - case typeDecimal: - //TODO::for porting - break; - case typeDate: - result = AllDataType::compareDateVal(val1, val2, op); - break; - case typeTime: - result = AllDataType::compareTimeVal(val1, val2, op); - break; - case typeTimeStamp: - result = AllDataType::compareTimeStampVal(val1, val2, op); - break; - case typeString: - result = AllDataType::compareStringVal(val1, val2, op); - break; - case typeComposite: - case typeBinary: - result = AllDataType::compareBinaryVal(val1, val2, op, length); - break; - } - return result; } bool AllDataType::compareIntVal(void* src1, void *src2, ComparisionOp op) { - if (OpEquals == op) - { - if (*(int*)src1 == *(int*)src2) return true; - else return false; + printf("This function should never be called by anyone"); + if (OpEquals == op) { + if (*(int*)src1 == *(int*)src2) return true; + else return false; + }else if (OpGreaterThan == op) { + if (*(int*)src1 > *(int*)src2) return true; + else return false; + }else if (OpLessThan == op) { + if (*(int*)src1 < *(int*)src2) return true; + else return false; + }else if (OpLessThanEquals == op) { + if (*(int*)src1 <= *(int*)src2) return true; + else return false; + }else if (OpGreaterThanEquals == op) { + if (*(int*)src1 >= *(int*)src2) return true; + else return false; + }else if (OpNotEquals == op) { + if (*(int*)src1 != *(int*)src2) return true; + else return false; } - bool result = false; - switch(op) - { - case OpLessThan: - if (*(int*)src1 < *(int*)src2) result = true; - else result = false; - break; - case OpGreaterThan: - if (*(int*)src1 > *(int*)src2) result = true; - else result = false; - break; - case OpLessThanEquals: - if (*(int*)src1 <= *(int*)src2) result = true; - else result = false; - break; - case OpGreaterThanEquals: - if (*(int*)src1 >= *(int*)src2) result = true; - else result = false; - break; - case OpNotEquals: - if (*(int*)src1 != *(int*)src2) result = true; - else result = false; - break; - } - return result; + return false; } bool AllDataType::compareLongVal(void* src1, void *src2, ComparisionOp op) @@ -1183,30 +1150,33 @@ bool AllDataType::compareTimeStampVal(void* src1, void *src2, ComparisionOp op) bool AllDataType::compareStringVal(void* src1, void *src2, ComparisionOp op) { - bool result = false; - int ret = strcmp((char*)src1, (char*)src2); - switch(op) - { - case OpEquals: - if (ret == 0 ) result= true; else result = false; - break; - case OpNotEquals: - if (ret != 0 ) result= true; else result = false; - break; - case OpLessThan: - if (ret < 0 ) result= true; else result = false; - break; - case OpLessThanEquals: - printf("Illegal Operator:Not Supported for String\n"); - break; - case OpGreaterThan: - if (ret > 0 ) result= true; else result = false; - break; - case OpGreaterThanEquals: - printf("Illegal Operator:Not Supported for String\n"); - break; - } - return result; + if (OpEquals == op) { + if (strcmp((char*)src1, (char*)src2) ==0) return true; + else return false; + }else if (OpGreaterThan == op) { + if (strcmp((char*)src1, (char*)src2) >0) return true; + else return false; + }else if (OpLessThan == op) { + if (strcmp((char*)src1, (char*)src2) <0 ) return true; + else return false; + }else if (OpLessThanEquals == op) { + printf("Illegal Operator:Not Supported for String\n"); + return false; + //if (strcmp((char*)src1, (char*)src2)<= 0) return true; + //else return false; + }else if (OpGreaterThanEquals == op) { + printf("Illegal Operator:Not Supported for String\n"); + return false; + //if (strcmp((char*)src1, (char*)src2) >=0) return true; + //else return false; + }else if (OpNotEquals == op) { + if (strcmp((char*)src1, (char*)src2) != 0) return true; + else return false; + }else if (OpLike == op) { + return !os::strmatch((char*)src2, (char*)src1); + } + printf("Illegeal Operator:Not supported for String\n"); + return false; } bool AllDataType::compareBinaryVal(void* src1, void *src2, diff --git a/src/storage/PredicateImpl.cxx b/src/storage/PredicateImpl.cxx index 928b6b90..9cb80dda 100644 --- a/src/storage/PredicateImpl.cxx +++ b/src/storage/PredicateImpl.cxx @@ -21,7 +21,6 @@ #include #include #include -#include #include #include void PredicateImpl::print(int space) @@ -132,6 +131,7 @@ void PredicateImpl::setTable(Table *tbl) void PredicateImpl::setTuple(void *tpl) { + //if (isPushedDown) return; if (NULL != lhs) lhs->setTuple(tpl); if (NULL != rhs) @@ -185,6 +185,7 @@ bool PredicateImpl::isNotOrInvolved() DbRetVal PredicateImpl::evaluate(bool &result) { + //if (isPushedDown) { result = true; return OK; } bool rhsResult = false, lhsResult=false; DbRetVal retCode =OK; result = false; @@ -201,23 +202,15 @@ DbRetVal PredicateImpl::evaluate(bool &result) if (NULL != lhs) { //Means it involves only Logical operator - switch(logicalOp) - { - case OpAnd: - if (lhsResult && rhsResult) result = true; - break; - case OpOr: - if (lhsResult || rhsResult) result = true; - break; - case OpNot: - if (lhsResult) result = false; else result = true; - break; - default: - return ErrInvalidExpr; - - } - printDebug(DM_Predicate, "result is %d", result); - return OK; + if (OpAnd == logicalOp) { + if (lhsResult && rhsResult) result = true; + }else if (OpOr == logicalOp) { + if (lhsResult || rhsResult) result = true; + }else if (OpNot == logicalOp){ + if (lhsResult) result = false; else result = true; + } + printDebug(DM_Predicate, "result is %d", result); + return OK; } //Means it is relational expression //first operand is always field identifier @@ -291,8 +284,9 @@ DbRetVal PredicateImpl::evaluate(bool &result) { val2 = *(char**)operandPtr; } - if (compOp == OpLike) result = ! fnmatch(val2, val1, 0); - else result = AllDataType::compareVal(val1, val2, compOp, type, + //if (compOp == OpLike) result = ! fnmatch(val2, val1, 0); + //else + result = AllDataType::compareVal(val1, val2, compOp, type, length); return OK; } @@ -301,27 +295,25 @@ DbRetVal PredicateImpl::evaluate(bool &result) //offset1 = table->getFieldOffset(fieldName1); //TODO::do not call getFieldXXX many times, instead get it using getFieldInfo - char *val1, *val2; + char *val2, *val1= ((char*) tuple) + offset1; //Assumes that fldName2 data type is also same for expr f1 getFieldType(fieldName1); - val1 = ((char*) tuple) + offset1; - if (operand == NULL && operandPtr == NULL) + //Note:Perf: Do not change the order below + if(operand == NULL && operandPtr != NULL) + { + val2 = *(char**)operandPtr; + result = AllDataType::compareVal(val1, val2, compOp, type,length); + } + else if (operand == NULL && operandPtr == NULL) { - // offset2 = table->getFieldOffset(fieldName2); if(offset2 != -1) val2 = ((char*)tuple) + offset2; + result = AllDataType::compareVal(val1, val2, compOp, type,length); } else if(operand != NULL && operandPtr == NULL) { val2 = (char*) operand; + result = AllDataType::compareVal(val1, val2, compOp, type,length); } - else if(operand == NULL && operandPtr != NULL) - { - val2 = *(char**)operandPtr; - } - int ret = 0; - if (compOp == OpLike) result = ! fnmatch(val2, val1, 0); - else result = AllDataType::compareVal(val1, val2, compOp, type,length); return OK; } void PredicateImpl::setOffsetAndType() @@ -501,6 +493,7 @@ void* PredicateImpl::valPtrForIndexField(const char *fname) { if(0 == strcmp(fieldName1, fname)) { + isPushedDown = true; if (operand) return operand; else return *(void**)operandPtr; } } diff --git a/src/storage/os.cxx b/src/storage/os.cxx index 9442abd2..77000447 100644 --- a/src/storage/os.cxx +++ b/src/storage/os.cxx @@ -258,3 +258,7 @@ int os::gethostname(char *hostname, size_t len) { return ::gethostname(hostname, len); } +int os::strmatch(char *pattern, char *str) +{ + return ::fnmatch(pattern, str, 0); +} -- 2.11.4.GIT