~vadim-tk/percona-server/percona-galera-5.1.57

« back to all changes in this revision

Viewing changes to storage/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp

  • Committer: root
  • Date: 2011-07-10 16:09:24 UTC
  • Revision ID: root@r815.office.percona.com-20110710160924-fyffqsbaclgu6vui
Initial port

Show diffs side-by-side

added added

removed removed

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