16 #include <ndb_global.h> 
   18 #include <NdbTransaction.hpp> 
   19 #include <NdbRecAttr.hpp> 
   22 #include <Bitmask.hpp> 
   23 #include <NdbSqlUtil.hpp> 
   24 #include <NdbRecord.hpp> 
   25 #include <NdbEventOperation.hpp> 
   26 #include "NdbIndexStatImpl.hpp" 
   30 #define min(a, b) ((a) <= (b) ? (a) : (b)) 
   31 #define max(a, b) ((a) >= (b) ? (a) : (b)) 
   33 static const char* 
const g_headtable_name = NDB_INDEX_STAT_HEAD_TABLE;
 
   34 static const char* 
const g_sampletable_name = NDB_INDEX_STAT_SAMPLE_TABLE;
 
   35 static const char* 
const g_sampleindex1_name = NDB_INDEX_STAT_SAMPLE_INDEX1;
 
   37 static const int ERR_NoSuchObject[] = { 709, 723, 4243, 0 };
 
   38 static const int ERR_TupleNotFound[] = { 626, 0 };
 
   40 NdbIndexStatImpl::NdbIndexStatImpl(
NdbIndexStat& facade) :
 
   43   m_keyData(m_keySpec, false, 2),
 
   44   m_valueData(m_valueSpec, false, 2)
 
   47   m_query_mutex = NdbMutex_Create();
 
   48   assert(m_query_mutex != 0);
 
   50   m_mem_handler = &c_mem_default_handler;
 
   54 NdbIndexStatImpl::init()
 
   72   init_head(m_facadeHead);
 
   75 NdbIndexStatImpl::~NdbIndexStatImpl()
 
   78   if (m_query_mutex != 0)
 
   80     NdbMutex_Destroy(m_query_mutex);
 
   91   m_dic = m_ndb->getDictionary();
 
   98 NdbIndexStatImpl::Sys::~Sys()
 
  100   m_impl->sys_release(*
this);
 
  104 NdbIndexStatImpl::sys_release(Sys& sys)
 
  108   (void)dic->
endSchemaTrans(NdbDictionary::Dictionary::SchemaTransAbort);
 
  110   if (sys.m_headtable != 0)
 
  112     sys.m_dic->removeTableGlobal(*sys.m_headtable, 
false);
 
  115   if (sys.m_sampletable != 0)
 
  117     sys.m_dic->removeTableGlobal(*sys.m_sampletable, 
false);
 
  118     sys.m_sampletable = 0;
 
  120   if (sys.m_sampleindex1 != 0)
 
  122     sys.m_dic->removeIndexGlobal(*sys.m_sampleindex1, 
false);
 
  123     sys.m_sampleindex1 = 0;
 
  133   ret = tab.
setFrm(g_ndb_index_stat_head_frm_data,
 
  134                    g_ndb_index_stat_head_frm_len);
 
  137     setError(ret, __LINE__);
 
  144     col.setPrimaryKey(
true);
 
  150     col.setPrimaryKey(
true);
 
  157     col.setNullable(
false);
 
  163     col.setNullable(
false);
 
  170     col.setNullable(
false);
 
  176     col.setNullable(
false);
 
  182     col.setNullable(
false);
 
  188     col.setNullable(
false);
 
  194     col.setNullable(
false);
 
  199     setError(error.
code, __LINE__);
 
  208   tab.
setName(g_sampletable_name);
 
  211   ret = tab.
setFrm(g_ndb_index_stat_sample_frm_data,
 
  212                    g_ndb_index_stat_sample_frm_len);
 
  215     setError(ret, __LINE__);
 
  222     col.setPrimaryKey(
true);
 
  228     col.setPrimaryKey(
true);
 
  234     col.setPrimaryKey(
true);
 
  240     col.setPrimaryKey(
true);
 
  241     col.setLength(MaxKeyBytes);
 
  248     col.setNullable(
false);
 
  249     col.setLength(MaxValueCBytes);
 
  254     setError(error.
code, __LINE__);
 
  264   ind.
setName(g_sampleindex1_name);
 
  280   for (uint 
i = 0; 
i < 
n; 
i++)
 
  284     require(col1 != 0 && col2 != 0);
 
  285     if (!col1->
equal(*col2))
 
  298   for (uint 
i = 0; 
i < 
n; 
i++)
 
  302     require(col1 != 0 && col2 != 0);
 
  304     if (!col1->
equal(*col2))
 
  311 NdbIndexStatImpl::get_systables(Sys& sys)
 
  313   Ndb* ndb = sys.m_ndb;
 
  315   const int NoSuchTable = 723;
 
  316   const int NoSuchIndex = 4243;
 
  318   sys.m_headtable = dic->getTableGlobal(g_headtable_name);
 
  319   if (sys.m_headtable == 0)
 
  322     if (code != NoSuchTable) {
 
  323       setError(code, __LINE__);
 
  331     if (check_table(*sys.m_headtable, tab) == -1)
 
  333       setError(BadSysTables, __LINE__);
 
  339   sys.m_sampletable = dic->getTableGlobal(g_sampletable_name);
 
  340   if (sys.m_sampletable == 0)
 
  343     if (code != NoSuchTable) {
 
  344       setError(code, __LINE__);
 
  351     make_sampletable(tab);
 
  352     if (check_table(*sys.m_sampletable, tab) == -1)
 
  354       setError(BadSysTables, __LINE__);
 
  360   if (sys.m_sampletable != 0)
 
  362     sys.m_sampleindex1 = dic->getIndexGlobal(g_sampleindex1_name, *sys.m_sampletable);
 
  363     if (sys.m_sampleindex1 == 0)
 
  366       if (code != NoSuchIndex) {
 
  367         setError(code, __LINE__);
 
  374       make_sampleindex1(ind);
 
  375       if (check_index(*sys.m_sampleindex1, ind) == -1)
 
  377         setError(BadSysTables, __LINE__);
 
  388 NdbIndexStatImpl::create_systables(
Ndb* ndb)
 
  392   if (get_systables(sys) == -1)
 
  395   if (sys.m_obj_cnt == Sys::ObjCnt)
 
  397     setError(HaveSysTables, __LINE__);
 
  401   if (sys.m_obj_cnt != 0)
 
  403     setError(BadSysTables, __LINE__);
 
  417     if (make_headtable(tab) == -1)
 
  425     sys.m_headtable = dic->getTableGlobal(tab.
getName());
 
  426     if (sys.m_headtable == 0)
 
  435     if (make_sampletable(tab) == -1)
 
  441       const char* p = NdbEnv_GetEnv(
"NDB_INDEX_STAT_ABORT_SYS_CREATE", (
char*)0, 0);
 
  442       if (p != 0 && strchr(
"1Y", p[0]) != 0)
 
  444         setError(9999, __LINE__);
 
  456     sys.m_sampletable = dic->getTableGlobal(tab.
getName());
 
  457     if (sys.m_sampletable == 0)
 
  466     if (make_sampleindex1(ind) == -1)
 
  468     if (dic->
createIndex(ind, *sys.m_sampletable) == -1)
 
  474     sys.m_sampleindex1 = dic->getIndexGlobal(ind.
getName(), sys.m_sampletable->getName());
 
  475     if (sys.m_sampleindex1 == 0)
 
  492 NdbIndexStatImpl::drop_systables(
Ndb* ndb)
 
  496   if (get_systables(sys) == -1 &&
 
  497       m_error.
code != BadSysTables)
 
  508   if (sys.m_headtable != 0)
 
  510     if (dic->dropTableGlobal(*sys.m_headtable) == -1)
 
  517   if (sys.m_sampletable != 0)
 
  523       const char* p = NdbEnv_GetEnv(
"NDB_INDEX_STAT_ABORT_SYS_DROP", (
char*)0, 0);
 
  524       if (p != 0 && strchr(
"1Y", p[0]) != 0)
 
  526         setError(9999, __LINE__);
 
  532     if (dic->dropTableGlobal(*sys.m_sampletable) == -1)
 
  549 NdbIndexStatImpl::check_systables(Sys& sys)
 
  551   if (get_systables(sys) == -1)
 
  554   if (sys.m_obj_cnt == 0)
 
  556     setError(NoSysTables, __LINE__);
 
  560   if (sys.m_obj_cnt != Sys::ObjCnt)
 
  562     setError(BadSysTables, __LINE__);
 
  570 NdbIndexStatImpl::check_systables(
Ndb* ndb)
 
  574   if (check_systables(sys) == -1)
 
  587   head.m_indexId = m_impl->m_indexId;
 
  588   head.m_indexVersion = m_impl->m_indexVersion;
 
  589   m_dic = m_ndb->getDictionary();
 
  598   m_cacheKeyOffset = 0;
 
  599   m_cacheValueOffset = 0;
 
  601   m_start.micro_seconds = 0;
 
  604 NdbIndexStatImpl::Con::~Con()
 
  606   if (m_cacheBuild != 0)
 
  608     m_impl->free_cache(m_cacheBuild);
 
  616   m_impl->sys_release(*
this);
 
  620 NdbIndexStatImpl::Con::startTransaction()
 
  622   assert(m_headtable != 0 && m_ndb != 0 && m_tx == 0);
 
  625     m_head.m_indexVersion
 
  627   m_tx = m_ndb->startTransaction(m_headtable, (
const char*)key, 
sizeof(key));
 
  634 NdbIndexStatImpl::Con::execute(
bool commit)
 
  641     m_ndb->closeTransaction(m_tx);
 
  653 NdbIndexStatImpl::Con::getNdbOperation()
 
  655   assert(m_headtable != 0);
 
  656   assert(m_tx != 0 && m_op == 0);
 
  657   m_op = m_tx->getNdbOperation(m_headtable);
 
  664 NdbIndexStatImpl::Con::getNdbIndexScanOperation()
 
  666   assert(m_sampletable != 0 && m_sampleindex1 != 0);
 
  667   assert( m_tx != 0 && m_scanop == 0);
 
  668   m_scanop = m_tx->getNdbIndexScanOperation(m_sampleindex1, m_sampletable);
 
  675 NdbIndexStatImpl::Con::set_time()
 
  677   NdbTick_getMicroTimer(&m_start);
 
  681 NdbIndexStatImpl::Con::get_time()
 
  684   NdbTick_getMicroTimer(&stop);
 
  685   NDB_TICKS us = NdbTick_getMicrosPassed(m_start, stop);
 
  697     setError(UsageError, __LINE__);
 
  704   m_valueAttrs = 1 + m_keyAttrs;
 
  707     setError(InternalError, __LINE__);
 
  710   if (m_keyAttrs > MaxKeyCount)
 
  712     setError(InternalError, __LINE__);
 
  719   if (m_keySpecBuf == 0 || m_valueSpecBuf == 0)
 
  721     setError(NoMemError, __LINE__);
 
  724   m_keySpec.set_buf(m_keySpecBuf, m_keyAttrs);
 
  725   m_valueSpec.set_buf(m_valueSpecBuf, m_valueAttrs);
 
  729     for (uint 
i = 0; 
i < m_keyAttrs; 
i++)
 
  734         setError(UsageError, __LINE__);
 
  739         icol->getSizeInBytes(),
 
  743       if (m_keySpec.add(
type) == -1)
 
  745         setError(UsageError, __LINE__, m_keySpec.get_error_code());
 
  754     if (m_valueSpec.add(
type, m_valueAttrs) == -1)
 
  756       setError(InternalError, __LINE__, m_valueSpec.get_error_code());
 
  762   m_keyDataBuf = 
new Uint8 [m_keyData.get_max_len4()];
 
  763   m_valueDataBuf = 
new Uint8 [m_valueData.get_max_len4()];
 
  764   if (m_keyDataBuf == 0 || m_valueDataBuf == 0)
 
  766     setError(NoMemError, __LINE__);
 
  769   m_keyData.set_buf(m_keyDataBuf, m_keyData.get_max_len());
 
  770   m_valueData.set_buf(m_valueDataBuf, m_valueData.get_max_len());
 
  777 NdbIndexStatImpl::reset_index()
 
  782   delete [] m_keySpecBuf;
 
  783   delete [] m_valueSpecBuf;
 
  784   delete [] m_keyDataBuf;
 
  785   delete [] m_valueDataBuf;
 
  792 NdbIndexStatImpl::init_head(Head& head)
 
  795   head.m_eventType = -1;
 
  797   head.m_indexVersion = 0;
 
  799   head.m_fragCount = 0;
 
  800   head.m_valueFormat = 0;
 
  801   head.m_sampleVersion = 0;
 
  803   head.m_sampleCount = 0;
 
  810 NdbIndexStatImpl::sys_init(
Con& con)
 
  812   Ndb* ndb = con.m_ndb;
 
  816   con.m_headtable = dic->getTableGlobal(g_headtable_name);
 
  817   if (con.m_headtable == 0)
 
  819     setError(con, __LINE__);
 
  820     mapError(ERR_NoSuchObject, NoSysTables);
 
  823   con.m_sampletable = dic->getTableGlobal(g_sampletable_name);
 
  824   if (con.m_sampletable == 0)
 
  826     setError(con, __LINE__);
 
  827     mapError(ERR_NoSuchObject, NoSysTables);
 
  830   con.m_sampleindex1 = dic->getIndexGlobal(g_sampleindex1_name, *con.m_sampletable);
 
  831   if (con.m_sampleindex1 == 0)
 
  833     setError(con, __LINE__);
 
  834     mapError(ERR_NoSuchObject, NoSysTables);
 
  841 NdbIndexStatImpl::sys_release(
Con& con)
 
  843   if (con.m_headtable != 0)
 
  845     con.m_dic->removeTableGlobal(*con.m_headtable, 
false);
 
  848   if (con.m_sampletable != 0)
 
  850     con.m_dic->removeTableGlobal(*con.m_sampletable, 
false);
 
  851     con.m_sampletable = 0;
 
  853   if (con.m_sampleindex1 != 0)
 
  855     con.m_dic->removeIndexGlobal(*con.m_sampleindex1, 
false);
 
  856     con.m_sampleindex1 = 0;
 
  861 NdbIndexStatImpl::sys_read_head(
Con& con, 
bool commit)
 
  863   Head& head = con.m_head;
 
  864   head.m_sampleVersion = 0;
 
  865   head.m_found = 
false;
 
  867   if (con.getNdbOperation() == -1)
 
  869     setError(con, __LINE__);
 
  874     setError(con, __LINE__);
 
  877   if (sys_head_setkey(con) == -1)
 
  879   if (sys_head_getvalue(con) == -1)
 
  881   if (con.execute(commit) == -1)
 
  883     setError(con, __LINE__);
 
  884     mapError(ERR_TupleNotFound, NoIndexStats);
 
  888   if (head.m_sampleVersion == 0)
 
  890     setError(NoIndexStats, __LINE__);
 
  897 NdbIndexStatImpl::sys_head_setkey(
Con& con)
 
  899   Head& head = con.m_head;
 
  901   if (op->
equal(
"index_id", (
char*)&head.m_indexId) == -1)
 
  903     setError(con, __LINE__);
 
  906   if (op->
equal(
"index_version", (
char*)&head.m_indexVersion) == -1)
 
  908     setError(con, __LINE__);
 
  915 NdbIndexStatImpl::sys_head_getvalue(
Con& con)
 
  917   Head& head = con.m_head;
 
  919   if (op->
getValue(
"table_id", (
char*)&head.m_tableId) == 0)
 
  921     setError(con, __LINE__);
 
  924   if (op->
getValue(
"frag_count", (
char*)&head.m_fragCount) == 0)
 
  926     setError(con, __LINE__);
 
  929   if (op->
getValue(
"value_format", (
char*)&head.m_valueFormat) == 0)
 
  931     setError(con, __LINE__);
 
  934   if (op->
getValue(
"sample_version", (
char*)&head.m_sampleVersion) == 0)
 
  936     setError(con, __LINE__);
 
  939   if (op->
getValue(
"load_time", (
char*)&head.m_loadTime) == 0)
 
  941     setError(con, __LINE__);
 
  944   if (op->
getValue(
"sample_count", (
char*)&head.m_sampleCount) == 0)
 
  946     setError(con, __LINE__);
 
  949   if (op->
getValue(
"key_bytes", (
char*)&head.m_keyBytes) == 0)
 
  951     setError(con, __LINE__);
 
  958 NdbIndexStatImpl::sys_sample_setkey(
Con& con)
 
  960   Head& head = con.m_head;
 
  962   if (op->
equal(
"index_id", (
char*)&head.m_indexId) == -1)
 
  964     setError(con, __LINE__);
 
  967   if (op->
equal(
"index_version", (
char*)&head.m_indexVersion) == -1)
 
  969     setError(con, __LINE__);
 
  972   if (op->
equal(
"sample_version", (
char*)&head.m_sampleVersion) == -1)
 
  974     setError(con, __LINE__);
 
  977   if (op->
equal(
"stat_key", (
char*)m_keyData.get_full_buf()) == -1)
 
  979     setError(con, __LINE__);
 
  986 NdbIndexStatImpl::sys_sample_getvalue(
Con& con)
 
  989   if (op->
getValue(
"stat_key", (
char*)m_keyData.get_full_buf()) == 0)
 
  991     setError(con, __LINE__);
 
  994   if (op->
getValue(
"stat_value", (
char*)m_valueData.get_full_buf()) == 0)
 
  996     setError(con, __LINE__);
 
 1003 NdbIndexStatImpl::sys_sample_setbound(
Con& con, 
int sv_bound)
 
 1005   Head& head = con.m_head;
 
 1010   if (op->
setBound(
"index_id", eq_bound, &head.m_indexId) == -1)
 
 1012     setError(con, __LINE__);
 
 1015   if (op->
setBound(
"index_version", eq_bound, &head.m_indexVersion) == -1)
 
 1017     setError(con, __LINE__);
 
 1022     if (op->
setBound(
"sample_version", sv_bound, &head.m_sampleVersion) == -1)
 
 1024       setError(con, __LINE__);
 
 1034 NdbIndexStatImpl::update_stat(
Ndb* ndb, Head& head)
 
 1036   Con con(
this, head, ndb);
 
 1037   if (con.m_dic->updateIndexStat(m_indexId, m_indexVersion, m_tableId) == -1)
 
 1039     setError(con, __LINE__);
 
 1046 NdbIndexStatImpl::delete_stat(
Ndb* ndb, Head& head)
 
 1048   Con con(
this, head, ndb);
 
 1049   if (con.m_dic->deleteIndexStat(m_indexId, m_indexVersion, m_tableId) == -1)
 
 1051     setError(con, __LINE__);
 
 1060 NdbIndexStatImpl::read_head(
Ndb* ndb, Head& head)
 
 1062   Con con(
this, head, ndb);
 
 1065     setError(UsageError, __LINE__);
 
 1068   if (sys_init(con) == -1)
 
 1070   if (con.startTransaction() == -1)
 
 1072     setError(con, __LINE__);
 
 1075   if (sys_read_head(con, 
true) == -1)
 
 1081 NdbIndexStatImpl::read_stat(
Ndb* ndb, Head& head)
 
 1083   Con con(
this, head, ndb);
 
 1086   if (read_start(con) == -1)
 
 1088   if (save_start(con) == -1)
 
 1092     int ret = read_next(con);
 
 1097     if (save_next(con) == -1)
 
 1100   if (read_commit(con) == -1)
 
 1103   NDB_TICKS save_time = con.get_time();
 
 1106   if (save_commit(con) == -1)
 
 1108   NDB_TICKS sort_time = con.get_time();
 
 1110   const Cache& c = *m_cacheBuild;
 
 1111   c.m_save_time = save_time;
 
 1112   c.m_sort_time = sort_time;
 
 1117 NdbIndexStatImpl::read_start(
Con& con)
 
 1122     setError(UsageError, __LINE__);
 
 1125   if (sys_init(con) == -1)
 
 1127   if (con.startTransaction() == -1)
 
 1129     setError(con, __LINE__);
 
 1132   if (sys_read_head(con, 
false) == -1)
 
 1134   if (con.getNdbIndexScanOperation() == -1)
 
 1136     setError(con, __LINE__);
 
 1141     setError(con, __LINE__);
 
 1146   if (sys_sample_getvalue(con) == -1)
 
 1148   if (con.execute(
false) == -1)
 
 1150     setError(con, __LINE__);
 
 1157 NdbIndexStatImpl::read_next(
Con& con)
 
 1160   m_valueData.reset();
 
 1165       setError(con, __LINE__);
 
 1173   const NdbPack::Endian::Value from_endian = NdbPack::Endian::Little;
 
 1174   const NdbPack::Endian::Value to_endian = NdbPack::Endian::Native;
 
 1176   if (m_keyData.desc_all(m_keyAttrs, from_endian) == -1)
 
 1178     setError(InternalError, __LINE__, m_keyData.get_error_code());
 
 1181   if (m_keyData.convert(to_endian) == -1)
 
 1183     setError(InternalError, __LINE__, m_keyData.get_error_code());
 
 1186   if (m_valueData.desc_all(m_valueAttrs, from_endian) == -1)
 
 1188     setError(InternalError, __LINE__, m_valueData.get_error_code());
 
 1191   if (m_valueData.convert(to_endian) == -1)
 
 1193     setError(InternalError, __LINE__, m_valueData.get_error_code());
 
 1200 NdbIndexStatImpl::read_commit(
Con& con)
 
 1202   if (con.execute(
true) == -1)
 
 1204     setError(con, __LINE__);
 
 1213 NdbIndexStatImpl::save_start(
Con& con)
 
 1215   if (m_cacheBuild != 0)
 
 1217     free_cache(m_cacheBuild);
 
 1220   con.m_cacheBuild = 
new Cache;
 
 1221   if (con.m_cacheBuild == 0)
 
 1223     setError(NoMemError, __LINE__);
 
 1226   new (con.m_cacheBuild) Cache;
 
 1227   if (cache_init(con) == -1)
 
 1233 NdbIndexStatImpl::save_next(
Con& con)
 
 1235   if (cache_insert(con) == -1)
 
 1241 NdbIndexStatImpl::save_commit(
Con& con)
 
 1243   if (cache_commit(con) == -1)
 
 1245   m_cacheBuild = con.m_cacheBuild;
 
 1246   con.m_cacheBuild = 0;
 
 1253 NdbIndexStatImpl::Cache::get_keyaddr(uint pos)
 const 
 1255   assert(pos < m_sampleCount);
 
 1256   const uint 
offset = pos * m_addrLen;
 
 1257   assert(offset + m_addrLen <= m_addrBytes);
 
 1258   const Uint8* src = &m_addrArray[
offset];
 
 1260   switch (m_addrLen) {
 
 1262     addr += src[3] << 24;
 
 1264     addr += src[2] << 16;
 
 1266     addr += src[1] << 8;
 
 1268     addr += src[0] << 0;
 
 1277 NdbIndexStatImpl::Cache::set_keyaddr(uint pos, uint addr)
 
 1279   assert(pos < m_sampleCount);
 
 1280   const uint offset = pos * m_addrLen;
 
 1281   assert(offset + m_addrLen <= m_addrBytes);
 
 1282   Uint8* dst = &m_addrArray[
offset];
 
 1283   switch (m_addrLen) {
 
 1285     dst[3] = (addr >> 24) & 0xFF;
 
 1287     dst[2] = (addr >> 16) & 0xFF;
 
 1289     dst[1] = (addr >> 8) & 0xFF;
 
 1291     dst[0] = (addr >> 0) & 0xFF;
 
 1296   assert(get_keyaddr(pos) == addr);
 
 1300 NdbIndexStatImpl::Cache::get_keyptr(uint addr)
 const 
 1302   assert(addr < m_keyBytes);
 
 1303   return &m_keyArray[addr];
 
 1307 NdbIndexStatImpl::Cache::get_keyptr(uint addr)
 
 1309   assert(addr < m_keyBytes);
 
 1310   return &m_keyArray[addr];
 
 1314 NdbIndexStatImpl::Cache::get_valueptr(uint pos)
 const 
 1316   assert(pos < m_sampleCount);
 
 1317   return &m_valueArray[pos * m_valueLen];
 
 1321 NdbIndexStatImpl::Cache::get_valueptr(uint pos)
 
 1323   assert(pos < m_sampleCount);
 
 1324   return &m_valueArray[pos * m_valueLen];
 
 1328 NdbIndexStatImpl::Cache::swap_entry(uint pos1, uint pos2)
 
 1331   Uint8 hold_value[MaxValueBytes];
 
 1333   hold_addr = get_keyaddr(pos1);
 
 1334   memcpy(hold_value, get_valueptr(pos1), m_valueLen);
 
 1335   set_keyaddr(pos1, get_keyaddr(pos2));
 
 1336   memcpy(get_valueptr(pos1), get_valueptr(pos2), m_valueLen);
 
 1337   set_keyaddr(pos2, hold_addr);
 
 1338   memcpy(get_valueptr(pos2), hold_value, m_valueLen);
 
 1342 NdbIndexStatImpl::Cache::get_rir(uint pos)
 const 
 1344   const Uint8* ptr = get_valueptr(pos);
 
 1346   memcpy(&n, &ptr[0], 4);
 
 1347   double x = (double)m_fragCount * (
double)
n;
 
 1352 NdbIndexStatImpl::Cache::get_rir(uint pos1, uint pos2)
 const 
 1354   assert(pos2 > pos1);
 
 1355   return get_rir(pos2) - get_rir(pos1);
 
 1359 NdbIndexStatImpl::Cache::get_unq(uint pos, uint k)
 const 
 1361   assert(k < m_keyAttrs);
 
 1362   const Uint8* ptr = get_valueptr(pos);
 
 1364   memcpy(&n, &ptr[4 + k * 4], 4);
 
 1365   double x = (double)m_fragCount * (
double)
n;
 
 1370 NdbIndexStatImpl::Cache::get_unq(uint pos1, uint pos2, uint k)
 const 
 1372   assert(pos2 > pos1);
 
 1373   return get_unq(pos2, k) - get_unq(pos1, k);
 
 1377 NdbIndexStatImpl::Cache::get_rpk(uint pos, uint k)
 const 
 1379   return get_rir(pos) / get_unq(pos, k);
 
 1383 NdbIndexStatImpl::Cache::get_rpk(uint pos1, uint pos2, uint k)
 const 
 1385   assert(pos2 > pos1);
 
 1386   return get_rir(pos1, pos2) / get_unq(pos1, pos2, k);
 
 1391 NdbIndexStatImpl::Cache::Cache()
 
 1397   m_sampleVersion = 0;
 
 1414 NdbIndexStatImpl::cache_init(
Con& con)
 
 1416   Cache& c = *con.m_cacheBuild;
 
 1417   Head& head = con.m_head;
 
 1418   Mem* mem = m_mem_handler;
 
 1420   if (m_keyAttrs == 0)
 
 1422     setError(InternalError, __LINE__);
 
 1425   c.m_keyAttrs = m_keyAttrs;
 
 1426   c.m_valueAttrs = m_valueAttrs;
 
 1427   c.m_fragCount = head.m_fragCount;
 
 1428   c.m_sampleCount = head.m_sampleCount;
 
 1429   c.m_keyBytes = head.m_keyBytes;
 
 1430   c.m_valueLen = 4 + c.m_keyAttrs * 4;
 
 1431   c.m_valueBytes = c.m_sampleCount * c.m_valueLen;
 
 1433     c.m_keyBytes < (1 << 8) ? 1 :
 
 1434     c.m_keyBytes < (1 << 16) ? 2 :
 
 1435     c.m_keyBytes < (1 << 24) ? 3 : 4;
 
 1436   c.m_addrBytes = c.m_sampleCount * c.m_addrLen;
 
 1439   c.m_addrArray = (Uint8*)mem->mem_alloc(c.m_addrBytes);
 
 1440   if (c.m_addrArray == 0)
 
 1442     setError(NoMemError, __LINE__);
 
 1445   c.m_keyArray = (Uint8*)mem->mem_alloc(c.m_keyBytes);
 
 1446   if (c.m_keyArray == 0)
 
 1448     setError(NoMemError, __LINE__);
 
 1451   c.m_valueArray = (Uint8*)mem->mem_alloc(c.m_valueBytes);
 
 1452   if (c.m_valueArray == 0)
 
 1454     setError(NoMemError, __LINE__);
 
 1461 NdbIndexStatImpl::cache_insert(
Con& con)
 
 1463   Cache& c = *con.m_cacheBuild;
 
 1465   const uint nextPos = con.m_cachePos + 1;
 
 1466   if (nextPos > c.m_sampleCount)
 
 1468     setError(InternalError, __LINE__);
 
 1471   assert(m_keyData.is_full());
 
 1472   const uint keyLen = m_keyData.get_data_len();
 
 1473   const uint nextKeyOffset = con.m_cacheKeyOffset + keyLen;
 
 1474   if (nextKeyOffset > c.m_keyBytes)
 
 1476     setError(InternalError, __LINE__);
 
 1479   if (m_valueData.get_data_len() != c.m_valueLen)
 
 1481     setError(InternalError, __LINE__);
 
 1484   const uint nextValueOffset = con.m_cacheValueOffset + c.m_valueLen;
 
 1485   if (nextValueOffset > c.m_valueBytes)
 
 1487     setError(InternalError, __LINE__);
 
 1491   c.set_keyaddr(con.m_cachePos, con.m_cacheKeyOffset);
 
 1492   con.m_cachePos = nextPos;
 
 1494   Uint8* cacheKeyPtr = &c.m_keyArray[con.m_cacheKeyOffset];
 
 1495   const Uint8* keyPtr = (
const Uint8*)m_keyData.get_data_buf();
 
 1496   memcpy(cacheKeyPtr, keyPtr, keyLen);
 
 1497   con.m_cacheKeyOffset = nextKeyOffset;
 
 1499   Uint8* cacheValuePtr = &c.m_valueArray[con.m_cacheValueOffset];
 
 1500   const Uint8* valuePtr = (
const Uint8*)m_valueData.get_data_buf();
 
 1501   memcpy(cacheValuePtr, valuePtr, c.m_valueLen);
 
 1502   con.m_cacheValueOffset = nextValueOffset;
 
 1506     const Uint8* rir_ptr = &cacheValuePtr[0];
 
 1508     memcpy(&rir, rir_ptr, 4);
 
 1511       setError(InvalidCache, __LINE__);
 
 1514     Uint32 unq_prev = 0;
 
 1515     for (uint k = 0; k < c.m_keyAttrs; k++)
 
 1517       Uint8* unq_ptr = &cacheValuePtr[4 + k * 4];
 
 1519       memcpy(&unq, unq_ptr, 4);
 
 1522         setError(InvalidCache, __LINE__);
 
 1527         setError(InvalidCache, __LINE__);
 
 1530       if (!(unq >= unq_prev))
 
 1532         setError(InvalidCache, __LINE__);
 
 1542 NdbIndexStatImpl::cache_commit(
Con& con)
 
 1544   Cache& c = *con.m_cacheBuild;
 
 1545   Head& head = con.m_head;
 
 1546   if (con.m_cachePos != c.m_sampleCount)
 
 1548     setError(InternalError, __LINE__);
 
 1551   if (con.m_cacheKeyOffset != c.m_keyBytes)
 
 1553     setError(InternalError, __LINE__);
 
 1556   if (con.m_cacheValueOffset != c.m_valueBytes)
 
 1558     setError(InternalError, __LINE__);
 
 1561   c.m_sampleVersion = head.m_sampleVersion;
 
 1562   if (cache_sort(c) == -1)
 
 1564   if (cache_verify(c) == -1)
 
 1571 NdbIndexStatImpl::cache_cmpaddr(
const Cache& c, uint addr1, uint addr2)
 const 
 1573   const Uint8* key1 = c.get_keyptr(addr1);
 
 1574   const Uint8* key2 = c.get_keyptr(addr2);
 
 1578   keyData1.set_buf(key1, c.m_keyBytes - addr1, c.m_keyAttrs);
 
 1579   keyData2.set_buf(key2, c.m_keyBytes - addr2, c.m_keyAttrs);
 
 1582   int res = keyData1.cmp(keyData2, c.m_keyAttrs, num_eq);
 
 1583   assert(addr1 == addr2 || res != 0);
 
 1588 NdbIndexStatImpl::cache_cmppos(
const Cache& c, uint pos1, uint pos2)
 const 
 1590   uint addr1 = c.get_keyaddr(pos1);
 
 1591   uint addr2 = c.get_keyaddr(pos2);
 
 1592   return cache_cmpaddr(c, addr1, addr2);
 
 1601 NdbIndexStatImpl::cache_sort(Cache& c)
 
 1603   if (c.m_sampleCount > 1)
 
 1610 NdbIndexStatImpl::cache_isort(Cache& c)
 
 1612   int n = c.m_sampleCount;
 
 1613   for (
int i = 1; 
i < 
n; 
i++)
 
 1615     for (
int j = 
i - 1; j >= 0; j--)
 
 1617       int res = cache_cmppos(c, j, j + 1);
 
 1620       c.swap_entry(j, j + 1);
 
 1627 NdbIndexStatImpl::cache_hsort(Cache& c)
 
 1629   int count = c.m_sampleCount;
 
 1638     cache_hsort_sift(c, i, count);
 
 1644 #ifdef ndb_index_stat_hsort_verify 
 1645   cache_hsort_verify(c, count);
 
 1656     cache_hsort_sift(c, 0, i);
 
 1657 #ifdef ndb_index_stat_hsort_verify 
 1658     cache_hsort_verify(c, i);
 
 1665 NdbIndexStatImpl::cache_hsort_sift(Cache& c, 
int i, 
int count)
 
 1672     int child = parent * 2 + 1;
 
 1673     if (! (child < count))
 
 1677     if (child + 1 < count && cache_cmppos(c, child, child + 1) < 0)
 
 1681     if (cache_cmppos(c, child, parent) < 0)
 
 1684     c.swap_entry(parent, child);
 
 1691 NdbIndexStatImpl::cache_hsort_verify(Cache& c, 
int count)
 
 1693   for (
int i = 0; i < count; i++)
 
 1696     int child1 = 2 * i + 1;
 
 1697     int child2 = 2 * i + 2;
 
 1700       assert(cache_cmppos(c, child1, parent) < 0);
 
 1704       assert(cache_cmppos(c, child2, parent) < 0);
 
 1710 NdbIndexStatImpl::cache_verify(
const Cache& c)
 
 1712   for (uint pos1 = 0; pos1 < c.m_sampleCount; pos1++)
 
 1714     const uint addr1 = c.get_keyaddr(pos1);
 
 1715     const Uint8* key1 = c.get_keyptr(addr1);
 
 1717     keyData1.set_buf(key1, c.m_keyBytes - addr1, c.m_keyAttrs);
 
 1718     uint pos2 = pos1 + 1;
 
 1719     if (pos2 < c.m_sampleCount)
 
 1721       const uint addr2 = c.get_keyaddr(pos2);
 
 1722       const Uint8* key2 = c.get_keyptr(addr2);
 
 1724       keyData2.set_buf(key2, c.m_keyBytes - addr2, c.m_keyAttrs);
 
 1726       int res = keyData1.cmp(keyData2, c.m_keyAttrs, num_eq);
 
 1729         setError(InvalidCache, __LINE__);
 
 1732       const Uint8* ptr1 = c.get_valueptr(pos1);
 
 1733       const Uint8* ptr2 = c.get_valueptr(pos2);
 
 1736       memcpy(&rir1, &ptr1[0], 4);
 
 1737       memcpy(&rir2, &ptr2[0], 4);
 
 1740         setError(InvalidCache, __LINE__);
 
 1743       for (uint k = 0; k < c.m_keyAttrs; k++)
 
 1747         memcpy(&unq1, &ptr1[4 + k * 4], 4);
 
 1748         memcpy(&unq2, &ptr2[4 + k * 4], 4);
 
 1749         if (!(unq1 <= unq2))
 
 1751           setError(InvalidCache, __LINE__);
 
 1754         if (k == c.m_keyAttrs - 1 && !(unq1 < unq2))
 
 1756           setError(InvalidCache, __LINE__);
 
 1766 NdbIndexStatImpl::move_cache()
 
 1768   Cache* cacheTmp = m_cacheQuery;
 
 1770   NdbMutex_Lock(m_query_mutex);
 
 1771   m_cacheQuery = m_cacheBuild;
 
 1772   NdbMutex_Unlock(m_query_mutex);
 
 1777     cacheTmp->m_nextClean = m_cacheClean;
 
 1778     m_cacheClean = cacheTmp;
 
 1783 NdbIndexStatImpl::clean_cache()
 
 1785   while (m_cacheClean != 0)
 
 1788     m_cacheClean = tmp->m_nextClean;
 
 1794 NdbIndexStatImpl::free_cache(Cache* c)
 
 1796   Mem* mem = m_mem_handler;
 
 1797   mem->mem_free(c->m_addrArray);
 
 1798   mem->mem_free(c->m_keyArray);
 
 1799   mem->mem_free(c->m_valueArray);
 
 1804 NdbIndexStatImpl::free_cache()
 
 1815   m_keyData(impl.m_keySpec, false),
 
 1816   m_valueData(impl.m_valueSpec, false)
 
 1818   m_keyCount = impl.m_keyAttrs;
 
 1824 NdbIndexStatImpl::dump_cache_start(CacheIter& iter)
 
 1826   if (m_cacheQuery == 0)
 
 1828     setError(UsageError, __LINE__);
 
 1831   const Cache& c = *m_cacheQuery;
 
 1832   new (&iter) CacheIter(*
this);
 
 1833   iter.m_sampleCount = c.m_sampleCount;
 
 1834   iter.m_sampleIndex = ~(Uint32)0;
 
 1839 NdbIndexStatImpl::dump_cache_next(CacheIter& iter)
 
 1841   if (iter.m_sampleIndex == ~(Uint32)0)
 
 1842     iter.m_sampleIndex = 0;
 
 1844     iter.m_sampleIndex++;
 
 1845   if (iter.m_sampleIndex >= iter.m_sampleCount)
 
 1847   const Cache& c = *m_cacheQuery;
 
 1848   const uint pos = iter.m_sampleIndex;
 
 1849   const uint addr = c.get_keyaddr(pos);
 
 1850   const Uint8* key = c.get_keyptr(addr);
 
 1851   const Uint8* value = c.get_valueptr(pos);
 
 1852   iter.m_keyData.set_buf(key, c.m_keyBytes - addr, c.m_keyAttrs);
 
 1853   iter.m_valueData.set_buf(value, c.m_valueLen, c.m_valueAttrs);
 
 1860 NdbIndexStatImpl::finalize_bound(Bound& bound)
 
 1862   assert(bound.m_type == 0 || bound.m_type == 1);
 
 1864   if (bound.m_data.get_cnt() == 0)
 
 1866     if (bound.m_strict != -1)
 
 1868       setError(UsageError, __LINE__);
 
 1874     if (bound.m_strict == -1)
 
 1876       setError(UsageError, __LINE__);
 
 1879     if (bound.m_type == 0)
 
 1880       side = bound.m_strict ? +1 : -1;
 
 1882       side = bound.m_strict ? -1 : +1;
 
 1884   if (bound.m_bound.finalize(side) == -1)
 
 1886     setError(UsageError, __LINE__);
 
 1895 NdbIndexStatImpl::convert_range(Range& range,
 
 1901   if (ib->low_key_count == 0 && ib->high_key_count == 0)
 
 1903   for (uint j = 0; j <= 1; j++)
 
 1905     Bound& bound = j == 0 ? range.m_bound1 : range.m_bound2;
 
 1906     bound.m_bound.reset();
 
 1907     const char* key = j == 0 ? ib->low_key : ib->high_key;
 
 1908     const uint key_count = j == 0 ? ib->low_key_count : ib->high_key_count;
 
 1909     const bool inclusive = j == 0 ? ib->low_inclusive : ib->high_inclusive;
 
 1911     for (uint i = 0; i < key_count; i++)
 
 1913       const uint i2 = key_record->key_indexes[
i];
 
 1914       require(i2 < key_record->noOfColumns);
 
 1916       if (!attr.is_null(key))
 
 1918         const char* data = key + attr.offset;
 
 1920         if (attr.flags & NdbRecord::IsMysqldShrinkVarchar)
 
 1923           if (!attr.shrink_varchar(key, len, buf))
 
 1925             setError(InternalError, __LINE__);
 
 1930         if (bound.m_data.add(data, &len_out) == -1)
 
 1932           setError(InternalError, __LINE__, bound.m_data.get_error_code());
 
 1938         if (bound.m_data.add_null(&len_out) == -1)
 
 1940           setError(InternalError, __LINE__, bound.m_data.get_error_code());
 
 1946       bound.m_strict = !inclusive;
 
 1947     if (finalize_bound(bound) == -1)
 
 1949       setError(InternalError, __LINE__);
 
 1960 NdbIndexStatImpl::query_normalize(
const Cache& c, StatValue& value)
 
 1964     if (value.m_rir < 1.0)
 
 1966     for (uint k = 0; k < c.m_keyAttrs; k++)
 
 1968       if (value.m_unq[k] < 1.0)
 
 1969         value.m_unq[k] = 1.0;
 
 1975     for (uint k = 0; k < c.m_keyAttrs; k++)
 
 1976       value.m_unq[k] = 1.0;
 
 1981 NdbIndexStatImpl::query_stat(
const Range& range, Stat& stat)
 
 1983   NdbMutex_Lock(m_query_mutex);
 
 1984   const Cache* cacheTmp = m_cacheQuery;
 
 1985   NdbMutex_Unlock(m_query_mutex);
 
 1987   if (unlikely(cacheTmp == 0))
 
 1989     setError(UsageError, __LINE__);
 
 1992   const Cache& c = *cacheTmp;
 
 1993   if (unlikely(!c.m_valid))
 
 1995     setError(InvalidCache, __LINE__);
 
 1999   query_interpolate(c, range, stat);
 
 2000   query_normalize(c, stat.m_value);
 
 2005 NdbIndexStatImpl::query_interpolate(
const Cache& c,
 
 2009   const uint keyAttrs = c.m_keyAttrs;
 
 2010   StatValue& value = stat.m_value;
 
 2011   value.m_empty = 
false;
 
 2012   stat.m_rule[0] = 
"-";
 
 2013   stat.m_rule[1] = 
"-";
 
 2014   stat.m_rule[2] = 
"-";
 
 2016   if (c.m_sampleCount == 0)
 
 2018     stat.m_rule[0] = 
"r1.1";
 
 2019     value.m_empty = 
true;
 
 2022   const uint posMIN = 0;
 
 2023   const uint posMAX = c.m_sampleCount - 1;
 
 2025   const Bound& bound1 = range.m_bound1;
 
 2026   const Bound& bound2 = range.m_bound2;
 
 2027   if (bound1.m_data.is_empty() && bound2.m_data.is_empty())
 
 2029     stat.m_rule[0] = 
"r1.2";
 
 2030     value.m_rir = c.get_rir(posMAX);
 
 2031     for (uint k = 0; k < keyAttrs; k++)
 
 2032       value.m_unq[k] = c.get_unq(posMAX, k);
 
 2036   StatBound& stat1 = stat.m_stat1;
 
 2037   StatBound& stat2 = stat.m_stat2;
 
 2038   if (!bound1.m_data.is_empty())
 
 2040     query_interpolate(c, bound1, stat1);
 
 2041     query_normalize(c, stat1.m_value);
 
 2042     stat.m_rule[1] = stat1.m_rule;
 
 2044   if (!bound2.m_data.is_empty())
 
 2046     query_interpolate(c, bound2, stat2);
 
 2047     query_normalize(c, stat2.m_value);
 
 2048     stat.m_rule[2] = stat2.m_rule;
 
 2051   const StatValue& value1 = stat1.m_value;
 
 2052   const StatValue& value2 = stat2.m_value;
 
 2053   const uint posL1 = stat1.m_pos - 1; 
 
 2054   const uint posH1 = stat1.m_pos;
 
 2055   const uint posL2 = stat2.m_pos - 1; 
 
 2056   const uint posH2 = stat2.m_pos;
 
 2057   const uint cnt1 = bound1.m_data.get_cnt();
 
 2058   const uint cnt2 = bound2.m_data.get_cnt();
 
 2059   const int side1 = bound1.m_bound.get_side();
 
 2060   const int side2 = bound2.m_bound.get_side();
 
 2061   const uint mincnt = min(cnt1, cnt2);
 
 2064   if (bound1.m_data.is_empty())
 
 2066     stat.m_rule[0] = 
"r1.3";
 
 2067     value.m_rir = value2.m_rir;
 
 2068     for (uint k = 0; k < keyAttrs; k++)
 
 2069       value.m_unq[k] = value2.m_unq[k];
 
 2072   if (bound2.m_data.is_empty())
 
 2074     stat.m_rule[0] = 
"r1.4";
 
 2075     value.m_rir = c.get_rir(posMAX) - value1.m_rir;
 
 2076     for (uint k = 0; k < keyAttrs; k++)
 
 2077       value.m_unq[k] = c.get_unq(posMAX, k) - value1.m_unq[k];
 
 2082     stat.m_rule[0] = 
"r1.5";
 
 2083     value.m_empty = 
true;
 
 2087   if (bound1.m_bound.cmp(bound2.m_bound, mincnt, numEq) >= 0)
 
 2089     stat.m_rule[0] = 
"r1.6";
 
 2090     value.m_empty = 
true;
 
 2093   if (posH1 == posMIN)
 
 2095     stat.m_rule[0] = 
"r1.7";
 
 2096     value.m_rir = value2.m_rir - value1.m_rir;
 
 2097     for (uint k = 0; k < keyAttrs; k++)
 
 2098       value.m_unq[k] = value2.m_unq[k] - value1.m_unq[k];
 
 2101   if (posH2 == posMAX + 1)
 
 2103     stat.m_rule[0] = 
"r1.8";
 
 2104     value.m_rir = value2.m_rir - value1.m_rir;
 
 2105     for (uint k = 0; k <= keyAttrs; k++)
 
 2106       value.m_unq[k] = value2.m_unq[k] - value1.m_unq[k];
 
 2111     assert(posH1 == posH2);
 
 2112     if (cnt1 == keyAttrs &&
 
 2114         numEq == keyAttrs) {
 
 2115       stat.m_rule[0] = 
"r2.1";
 
 2116       assert(side1 == -1 && side2 == +1);
 
 2117       assert(stat1.m_numEqL < keyAttrs && stat2.m_numEqH < keyAttrs);
 
 2118       value.m_rir = c.get_rpk(posL1, posH1, keyAttrs - 1);
 
 2119       for (uint k = 0; k < keyAttrs; k++)
 
 2120         value.m_unq[k] = value.m_rir / c.get_rpk(posL1, posH1, k);
 
 2125       stat.m_rule[0] = 
"r2.2";
 
 2130       stat.m_rule[0] = 
"r2.3";
 
 2131       const double w = 0.5;
 
 2132       value.m_rir = w * c.get_rir(posL1, posH1);
 
 2133       for (uint k = 0; k < keyAttrs; k++)
 
 2134         value.m_unq[k] = w * c.get_unq(posL1, posH1, k);
 
 2140     if (cnt1 == keyAttrs &&
 
 2142         numEq == keyAttrs) {
 
 2143       stat.m_rule[0] = 
"r3.1";
 
 2144       assert(side1 == -1 && side2 == +1);
 
 2145       assert(stat1.m_numEqH == keyAttrs && stat2.m_numEqL == keyAttrs);
 
 2146       value.m_rir = value2.m_rir - value1.m_rir;
 
 2147       for (uint k = 0; k < keyAttrs; k++)
 
 2148         value.m_unq[k] = value2.m_unq[k] - value1.m_unq[k];
 
 2153       stat.m_rule[0] = 
"r3.2";
 
 2158       stat.m_rule[0] = 
"r3.3";
 
 2159       const double w = 0.5;
 
 2160       value.m_rir = w * c.get_rir(posL1, posH1);
 
 2161       for (uint k = 0; k < keyAttrs; k++)
 
 2162         value.m_unq[k] = w * c.get_unq(posL1, posH1, k);
 
 2168     stat.m_rule[0] = 
"r4";
 
 2169     value.m_rir = value2.m_rir - value1.m_rir;
 
 2170     for (uint k = 0; k < keyAttrs; k++)
 
 2171       value.m_unq[k] = value2.m_unq[k] - value1.m_unq[k];
 
 2177 NdbIndexStatImpl::query_interpolate(
const Cache& c,
 
 2181   const uint keyAttrs = c.m_keyAttrs;
 
 2182   StatValue& value = stat.m_value;
 
 2183   value.m_empty = 
false;
 
 2186   query_search(c, bound, stat);
 
 2188   const uint posMIN = 0;
 
 2189   const uint posMAX = c.m_sampleCount - 1;
 
 2190   const uint posL = stat.m_pos - 1; 
 
 2191   const uint posH = stat.m_pos;
 
 2192   const uint cnt = bound.m_data.get_cnt();
 
 2193   const int side = bound.m_bound.get_side();
 
 2197     if (cnt == keyAttrs &&
 
 2198         cnt == stat.m_numEqH) {
 
 2199       stat.m_rule = 
"b1.1";
 
 2201       value.m_rir = c.get_rir(posMIN) - c.get_rpk(posMIN, keyAttrs - 1);
 
 2202       for (uint k = 0; k < keyAttrs; k++)
 
 2203         value.m_unq[k] = c.get_unq(posMIN, k) - 1;
 
 2208       stat.m_rule = 
"b1.2";
 
 2209       value.m_empty = 
true;
 
 2213   if (posH == posMAX + 1)
 
 2216     value.m_rir = c.get_rir(posMAX);
 
 2217     for (uint k = 0; k < keyAttrs; k++)
 
 2218       value.m_unq[k] = c.get_unq(posMAX, k);
 
 2221   if (cnt == keyAttrs &&
 
 2222       cnt == stat.m_numEqL) {
 
 2223     stat.m_rule = 
"b3.1";
 
 2225     value.m_rir = c.get_rir(posL);
 
 2226     for (uint k = 0; k < keyAttrs; k++)
 
 2227       value.m_unq[k] = c.get_unq(posL, k);
 
 2230   if (cnt == keyAttrs &&
 
 2231       cnt == stat.m_numEqH &&
 
 2233     stat.m_rule = 
"b3.2";
 
 2234     value.m_rir = c.get_rir(posH);
 
 2235     for (uint k = 0; k < keyAttrs; k++)
 
 2236       value.m_unq[k] = c.get_unq(posH, k);
 
 2239   if (cnt == keyAttrs &&
 
 2240       cnt == stat.m_numEqH &&
 
 2242     stat.m_rule = 
"b3.3";
 
 2243     const double u = c.get_unq(posL, posH, keyAttrs - 1);
 
 2244     const double wL = 1.0 / u;
 
 2245     const double wH = 1.0 - wL;
 
 2246     value.m_rir = wL * c.get_rir(posL) + wH * c.get_rir(posH);
 
 2247     for (uint k = 0; k < keyAttrs; k++)
 
 2248       value.m_unq[k] = wL * c.get_unq(posL, k) + wH * c.get_unq(posH, k);
 
 2254     const double wL = 0.5;
 
 2255     const double wH = 0.5;
 
 2256     value.m_rir = wL * c.get_rir(posL) + wH * c.get_rir(posH);
 
 2257     for (uint k = 0; k < keyAttrs; k++)
 
 2258       value.m_unq[k] = wL * c.get_unq(posL, k) + wH * c.get_unq(posH, k);
 
 2264 NdbIndexStatImpl::query_search(
const Cache& c,
 
 2268   assert(c.m_sampleCount > 0);
 
 2269   assert(!bound.m_data.is_empty());
 
 2273   int hi = c.m_sampleCount;
 
 2276     int j = (hi + lo) / 2;
 
 2277     assert(lo < j && j < hi);
 
 2278     int res = query_keycmp(c, bound, j, numEq);
 
 2289   assert(hi - lo == 1);
 
 2294     (void)query_keycmp(c, bound, stat.m_pos - 1, stat.m_numEqL);
 
 2296   if (stat.m_pos < c.m_sampleCount)
 
 2298     (void)query_keycmp(c, bound, stat.m_pos, stat.m_numEqH);
 
 2304 NdbIndexStatImpl::query_keycmp(
const Cache& c,
 
 2306                                uint pos, Uint32& numEq)
 
 2308   const uint addr = c.get_keyaddr(pos);
 
 2309   const Uint8* key = c.get_keyptr(addr);
 
 2311   keyData.set_buf(key, c.m_keyBytes - addr, c.m_keyAttrs);
 
 2313   Uint32 cnt = bound.m_bound.get_data().get_cnt();
 
 2314   int res = (-1) * bound.m_bound.cmp(keyData, cnt, numEq);
 
 2321 NdbIndexStatImpl::create_sysevents(
Ndb* ndb)
 
 2326   if (check_systables(sys) == -1)
 
 2331   const char* 
const evname = NDB_INDEX_STAT_HEAD_EVENT;
 
 2337     ev.addEventColumn(i);
 
 2338   ev.setReport(NdbDictionary::Event::ER_UPDATED);
 
 2349 NdbIndexStatImpl::drop_sysevents(
Ndb* ndb)
 
 2354   if (check_systables(sys) == -1)
 
 2357   const char* 
const evname = NDB_INDEX_STAT_HEAD_EVENT;
 
 2371 NdbIndexStatImpl::check_sysevents(
Ndb* ndb)
 
 2376   if (check_systables(sys) == -1)
 
 2379   const char* 
const evname = NDB_INDEX_STAT_HEAD_EVENT;
 
 2391 NdbIndexStatImpl::create_listener(
Ndb* ndb)
 
 2395     setError(UsageError, __LINE__);
 
 2398   const char* 
const evname = NDB_INDEX_STAT_HEAD_EVENT;
 
 2407   Head& head = m_facadeHead;
 
 2408   if (m_eventOp->
getValue(
"index_id", (
char*)&head.m_indexId) == 0 ||
 
 2409       m_eventOp->
getValue(
"index_version", (
char*)&head.m_indexVersion) == 0 ||
 
 2410       m_eventOp->
getValue(
"table_id", (
char*)&head.m_tableId) == 0 ||
 
 2411       m_eventOp->
getValue(
"frag_count", (
char*)&head.m_fragCount) == 0 ||
 
 2412       m_eventOp->
getValue(
"value_format", (
char*)&head.m_valueFormat) == 0 ||
 
 2413       m_eventOp->
getValue(
"sample_version", (
char*)&head.m_sampleVersion) == 0 ||
 
 2414       m_eventOp->
getValue(
"load_time", (
char*)&head.m_loadTime) == 0 ||
 
 2415       m_eventOp->
getValue(
"sample_count", (
char*)&head.m_sampleCount) == 0 ||
 
 2416       m_eventOp->
getValue(
"key_bytes", (
char*)&head.m_keyBytes) == 0)
 
 2423   if (m_eventOp->
getPreValue(
"index_id", (
char*)&xxx.m_indexId) == 0 ||
 
 2424       m_eventOp->
getPreValue(
"index_version", (
char*)&xxx.m_indexVersion) == 0 ||
 
 2425       m_eventOp->
getPreValue(
"table_id", (
char*)&xxx.m_tableId) == 0 ||
 
 2426       m_eventOp->
getPreValue(
"frag_count", (
char*)&xxx.m_fragCount) == 0 ||
 
 2427       m_eventOp->
getPreValue(
"value_format", (
char*)&xxx.m_valueFormat) == 0 ||
 
 2428       m_eventOp->
getPreValue(
"sample_version", (
char*)&xxx.m_sampleVersion) == 0 ||
 
 2429       m_eventOp->
getPreValue(
"load_time", (
char*)&xxx.m_loadTime) == 0 ||
 
 2430       m_eventOp->
getPreValue(
"sample_count", (
char*)&xxx.m_sampleCount) == 0 ||
 
 2431       m_eventOp->
getPreValue(
"key_bytes", (
char*)&xxx.m_keyBytes) == 0)
 
 2440 NdbIndexStatImpl::execute_listener(
Ndb* ndb)
 
 2444     setError(UsageError, __LINE__);
 
 2447   if (m_eventOp->
execute() == -1)
 
 2456 NdbIndexStatImpl::poll_listener(
Ndb* ndb, 
int max_wait_ms)
 
 2459   if ((ret = ndb->
pollEvents(max_wait_ms)) < 0)
 
 2464   return (ret == 0 ? 0 : 1);
 
 2468 NdbIndexStatImpl::next_listener(
Ndb* ndb)
 
 2474   Head& head = m_facadeHead;
 
 2480 NdbIndexStatImpl::drop_listener(
Ndb* ndb)
 
 2484     setError(UsageError, __LINE__);
 
 2498 NdbIndexStatImpl::MemDefault::MemDefault()
 
 2502 NdbIndexStatImpl::MemDefault::~MemDefault()
 
 2507 NdbIndexStatImpl::MemDefault::mem_alloc(UintPtr 
size)
 
 2509   void* ptr = malloc(size);
 
 2523 NdbIndexStatImpl::setError(
int code, 
int line, 
int extra)
 
 2526     code = InternalError;
 
 2527   m_error.
code = code;
 
 2528   m_error.line = line;
 
 2529   m_error.extra = extra;
 
 2531   const char* p = NdbEnv_GetEnv(
"NDB_INDEX_STAT_ABORT_ON_ERROR", (
char*)0, 0);
 
 2532   if (p != 0 && strchr(
"1Y", p[0]) != 0)
 
 2538 NdbIndexStatImpl::setError(
const Con& con, 
int line)
 
 2541   if (code == 0 && con.m_op != 0)
 
 2545   if (code == 0 && con.m_scanop != 0)
 
 2549   if (code == 0 && con.m_tx != 0)
 
 2553   if (code == 0 && con.m_dic != 0)
 
 2557   if (code == 0 && con.m_ndb != 0)
 
 2561   setError(code, line);
 
 2565 NdbIndexStatImpl::mapError(
const int* map, 
int code)
 
 2569     if (m_error.
code == *map) {
 
 2570       m_error.
code = code;