Fennel: /home/pub/open/dev/fennel/hashexe/LhxHashGenerator.cpp Source File (original) (raw)

00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 #include "fennel/common/CommonPreamble.h" 00024 #include "fennel/common/FennelExcn.h" 00025 #include "fennel/hashexe/LhxHashGenerator.h" 00026 #include 00027 00028 using namespace std; 00029 00030 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/hashexe/LhxHashGenerator.cpp#2 $"); 00031 00032 static uint8_t LhxHashGeneratorMagicTable[256] = 00033 { 00034 1, 87, 49, 12, 176, 178, 102, 166, 121, 193, 6, 84, 00035 249, 230, 44, 163, 14, 197, 213, 181, 161, 85, 218, 80, 00036 64, 239, 24, 226, 236, 142, 38, 200, 110, 177, 104, 103, 00037 141, 253, 255, 50, 77, 101, 81, 18, 45, 96, 31, 222, 00038 25, 107, 190, 70, 86, 237, 240, 34, 72, 242, 20, 226, 00039 236, 142, 38, 235, 97, 234, 57, 22, 60, 250, 82, 175, 00040 208, 5, 127, 199, 111, 62, 135, 248, 174, 169, 211, 58, 00041 66, 154, 106, 195, 245, 171, 17, 187, 182, 179, 0, 243, 00042 132, 56, 148, 75, 128, 133, 158, 100, 130, 126, 91, 13, 00043 153, 246, 216, 219, 119, 68, 223, 78, 83, 88, 201, 99, 00044 122, 11, 92, 32, 136, 114, 52, 10, 138, 30, 48, 183, 00045 156, 35, 61, 26, 143, 74, 251, 94, 129, 162, 63, 152, 00046 170, 7, 115, 167, 241, 206, 3, 150, 55, 59, 151, 220, 00047 90, 53, 23, 131, 125, 173, 15, 238, 79, 95, 89, 16, 00048 105, 137, 225, 224, 217, 160, 37, 123, 118, 73, 2, 157, 00049 46, 116, 9, 145, 134, 228, 207, 212, 202, 215, 69, 229, 00050 27, 188, 67, 124, 168, 252, 42, 4, 29, 108, 21, 247, 00051 19, 205, 39, 203, 233, 40, 186, 147, 198, 192, 155, 33, 00052 164, 191, 98, 204, 165, 180, 117, 76, 140, 36, 210, 172, 00053 41, 54, 159, 8, 185, 232, 113, 196, 231, 47, 146, 120, 00054 51, 65, 28, 144, 254, 221, 93, 189, 194, 139, 112, 43, 00055 71, 109, 184, 209 00056 }; 00057 00058 void LhxHashGenerator::init(uint levelInit) 00059 { 00060
00061 00062 00063 00064 00065 if (levelInit > 63) { 00066 ostringstream errMsg; 00067 errMsg << " Hash recursion level can not be deeper than 63"; 00068 throw FennelExcn(errMsg.str()); 00069 } 00070 00071 level = levelInit; 00072 magicTable = LhxHashGeneratorMagicTable; 00073 00074 uint base = level * 4; 00075 hashValueSeed 00076 = (uint8_t(base) << 24) 00077 | (uint8_t(base + 1) << 16) 00078 | (uint8_t(base + 2) << 8) 00079 | (uint8_t(base + 3)); 00080 } 00081 00082 00083 00084 00085 00086 void LhxHashGenerator::hashOneBuffer( 00087 uint &hashValue, 00088 PConstBuffer pBuf, 00089 uint bufSize) 00090 { 00091 uint numValueBytes = sizeof(uint); 00092 uint8_t byteForNull = 0xff; 00093 00094 if (pBuf == NULL) { 00095 bufSize = 1; 00096 pBuf = &byteForNull; 00097 } 00098 00099 for (int count = 0; count < bufSize; count ++) { 00100 PBuffer pByte = (PBuffer) &hashValue; 00101 00102 for (int i = 0; i < numValueBytes; i++) { 00103 *pByte = magicTable[(*pByte) ^ (*pBuf)]; 00104 pByte ++; 00105 } 00106 00107 pBuf ++; 00108 } 00109 } 00110 00111 void LhxHashGenerator::hashOneColumn( 00112 uint &hashValue, 00113 TupleDatum const &inputCol, 00114 LhxHashTrim isVarChar) 00115 { 00116 uint trimmedLength = inputCol.cbData; 00117 PConstBuffer pData = inputCol.pData; 00118 00119 if (pData) { 00120
00121 00122 00123 if (isVarChar == HASH_TRIM_VARCHAR) { 00124 PConstBuffer pChar = pData + trimmedLength - 1; 00125 while ((pChar >= pData) && (*pChar == ' ')) { 00126 --pChar; 00127 } 00128 trimmedLength = pChar - pData + 1; 00129 } else if (isVarChar == HASH_TRIM_UNICODE_VARCHAR) { 00130 PConstBuffer pChar = pData + trimmedLength - 2; 00131 while ((pChar >= pData) 00132 && (*reinterpret_cast<uint16_t const *>(pChar) == ' ')) 00133 { 00134 pChar -= 2; 00135 } 00136 trimmedLength = pChar - pData + 2; 00137 } 00138 } 00139 00140
00141
00142
00143 00144
00145 00146 00147 00148 if (pData) { 00149 hashOneBuffer( 00150 hashValue, 00151 (PConstBuffer) &(trimmedLength), 00152 sizeof(TupleStorageByteLength)); 00153 } 00154 00155
00156 00157 00158 hashOneBuffer( 00159 hashValue, 00160 pData, 00161 trimmedLength); 00162 } 00163 00164 uint LhxHashGenerator::hash( 00165 TupleData const &inputTuple, 00166 TupleProjection const &keyProjection, 00167 vector const &isKeyColVarChar) 00168 { 00169 uint keyLength = keyProjection.size(); 00170 00171
00172 00173 00174 uint hashValue = hashValueSeed; 00175 00176 for (int i = 0; i < keyLength; i++) { 00177 TupleDatum const &col = inputTuple[keyProjection[i]]; 00178 hashOneColumn(hashValue, col, isKeyColVarChar[i]); 00179 } 00180 00181
00182 00183 00184 00185 return hashValue; 00186 } 00187 00188 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/hashexe/LhxHashGenerator.cpp#2 $"); 00189 00190