DbtuxCmp.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #define DBTUX_CMP_CPP
  14. #include "Dbtux.hpp"
  15. /*
  16.  * Search key vs node prefix or entry
  17.  *
  18.  * The comparison starts at given attribute position.  The position is
  19.  * updated by number of equal initial attributes found.  The entry data
  20.  * may be partial in which case CmpUnknown may be returned.
  21.  */
  22. int
  23. Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, ConstData entryData, unsigned maxlen)
  24. {
  25.   const unsigned numAttrs = frag.m_numAttrs;
  26.   const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
  27.   // number of words of attribute data left
  28.   unsigned len2 = maxlen;
  29.   // skip to right position in search key only
  30.   for (unsigned i = 0; i < start; i++) {
  31.     jam();
  32.     searchKey += AttributeHeaderSize + searchKey.ah().getDataSize();
  33.   }
  34.   int ret = 0;
  35.   while (start < numAttrs) {
  36.     if (len2 <= AttributeHeaderSize) {
  37.       jam();
  38.       ret = NdbSqlUtil::CmpUnknown;
  39.       break;
  40.     }
  41.     len2 -= AttributeHeaderSize;
  42.     if (! searchKey.ah().isNULL()) {
  43.       if (! entryData.ah().isNULL()) {
  44.         jam();
  45.         // current attribute
  46.         const DescAttr& descAttr = descEnt.m_descAttr[start];
  47.         // full data size
  48.         const unsigned size1 = AttributeDescriptor::getSizeInWords(descAttr.m_attrDesc);
  49.         ndbrequire(size1 != 0 && size1 == entryData.ah().getDataSize());
  50.         const unsigned size2 = min(size1, len2);
  51.         len2 -= size2;
  52.         // compare
  53.         NdbSqlUtil::Cmp* const cmp = c_sqlCmp[start];
  54.         const Uint32* const p1 = &searchKey[AttributeHeaderSize];
  55.         const Uint32* const p2 = &entryData[AttributeHeaderSize];
  56.         ret = (*cmp)(0, p1, p2, size1, size2);
  57.         if (ret != 0) {
  58.           jam();
  59.           break;
  60.         }
  61.       } else {
  62.         jam();
  63.         // not NULL > NULL
  64.         ret = +1;
  65.         break;
  66.       }
  67.     } else {
  68.       if (! entryData.ah().isNULL()) {
  69.         jam();
  70.         // NULL < not NULL
  71.         ret = -1;
  72.         break;
  73.       }
  74.     }
  75.     searchKey += AttributeHeaderSize + searchKey.ah().getDataSize();
  76.     entryData += AttributeHeaderSize + entryData.ah().getDataSize();
  77.     start++;
  78.   }
  79.   return ret;
  80. }
  81. /*
  82.  * Scan bound vs node prefix or entry.
  83.  *
  84.  * Compare lower or upper bound and index entry data.  The entry data
  85.  * may be partial in which case CmpUnknown may be returned.  Otherwise
  86.  * returns -1 if the bound is to the left of the entry and +1 if the
  87.  * bound is to the right of the entry.
  88.  *
  89.  * The routine is similar to cmpSearchKey, but 0 is never returned.
  90.  * Suppose all attributes compare equal.  Recall that all bounds except
  91.  * possibly the last one are non-strict.  Use the given bound direction
  92.  * (0-lower 1-upper) and strictness of last bound to return -1 or +1.
  93.  *
  94.  * Following example illustrates this.  We are at (a=2, b=3).
  95.  *
  96.  * dir  bounds                  strict          return
  97.  * 0    a >= 2 and b >= 3       no              -1
  98.  * 0    a >= 2 and b >  3       yes             +1
  99.  * 1    a <= 2 and b <= 3       no              +1
  100.  * 1    a <= 2 and b <  3       yes             -1
  101.  */
  102. int
  103. Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigned boundCount, ConstData entryData, unsigned maxlen)
  104. {
  105.   const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff);
  106.   // direction 0-lower 1-upper
  107.   ndbrequire(dir <= 1);
  108.   // number of words of data left
  109.   unsigned len2 = maxlen;
  110.   // in case of no bounds, init last type to something non-strict
  111.   unsigned type = 4;
  112.   while (boundCount != 0) {
  113.     if (len2 <= AttributeHeaderSize) {
  114.       jam();
  115.       return NdbSqlUtil::CmpUnknown;
  116.     }
  117.     len2 -= AttributeHeaderSize;
  118.     // get and skip bound type (it is used after the loop)
  119.     type = boundInfo[0];
  120.     boundInfo += 1;
  121.     if (! boundInfo.ah().isNULL()) {
  122.       if (! entryData.ah().isNULL()) {
  123.         jam();
  124.         // current attribute
  125.         const unsigned index = boundInfo.ah().getAttributeId();
  126.         ndbrequire(index < frag.m_numAttrs);
  127.         const DescAttr& descAttr = descEnt.m_descAttr[index];
  128.         ndbrequire(entryData.ah().getAttributeId() == descAttr.m_primaryAttrId);
  129.         // full data size
  130.         const unsigned size1 = boundInfo.ah().getDataSize();
  131.         ndbrequire(size1 != 0 && size1 == entryData.ah().getDataSize());
  132.         const unsigned size2 = min(size1, len2);
  133.         len2 -= size2;
  134.         // compare
  135.         NdbSqlUtil::Cmp* const cmp = c_sqlCmp[index];
  136.         const Uint32* const p1 = &boundInfo[AttributeHeaderSize];
  137.         const Uint32* const p2 = &entryData[AttributeHeaderSize];
  138.         int ret = (*cmp)(0, p1, p2, size1, size2);
  139.         if (ret != 0) {
  140.           jam();
  141.           return ret;
  142.         }
  143.       } else {
  144.         jam();
  145.         // not NULL > NULL
  146.         return +1;
  147.       }
  148.     } else {
  149.       jam();
  150.       if (! entryData.ah().isNULL()) {
  151.         jam();
  152.         // NULL < not NULL
  153.         return -1;
  154.       }
  155.     }
  156.     boundInfo += AttributeHeaderSize + boundInfo.ah().getDataSize();
  157.     entryData += AttributeHeaderSize + entryData.ah().getDataSize();
  158.     boundCount -= 1;
  159.   }
  160.   // all attributes were equal
  161.   const int strict = (type & 0x1);
  162.   return (dir == 0 ? (strict == 0 ? -1 : +1) : (strict == 0 ? +1 : -1));
  163. }