~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/sp_key.c

  • Committer: Brian Aker
  • Date: 2008-07-06 05:41:53 UTC
  • Revision ID: brian@tangent.org-20080706054153-9w5ltr9u3xt4pnro
Remove SP bits from MyISAM

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000 MySQL AB & Ramil Kalimullin
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
 
#include "myisamdef.h"
17
 
 
18
 
#ifdef HAVE_SPATIAL
19
 
 
20
 
#include "sp_defs.h"
21
 
 
22
 
static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims, 
23
 
                             uchar byte_order, double *mbr);
24
 
static int sp_get_point_mbr(uchar *(*wkb), uchar *end, uint n_dims, 
25
 
                           uchar byte_order, double *mbr);
26
 
static int sp_get_linestring_mbr(uchar *(*wkb), uchar *end, uint n_dims, 
27
 
                                uchar byte_order, double *mbr);
28
 
static int sp_get_polygon_mbr(uchar *(*wkb), uchar *end, uint n_dims, 
29
 
                             uchar byte_order, double *mbr);
30
 
static int sp_get_geometry_mbr(uchar *(*wkb), uchar *end, uint n_dims, 
31
 
                              double *mbr, int top);
32
 
static int sp_mbr_from_wkb(uchar (*wkb), uint size, uint n_dims, double *mbr);
33
 
 
34
 
uint sp_make_key(register MI_INFO *info, uint keynr, uchar *key,
35
 
                 const uchar *record, my_off_t filepos)
36
 
{
37
 
  HA_KEYSEG *keyseg;
38
 
  MI_KEYDEF *keyinfo = &info->s->keyinfo[keynr];
39
 
  uint len = 0;
40
 
  uchar *pos;
41
 
  uint dlen;
42
 
  uchar *dptr;
43
 
  double mbr[SPDIMS * 2];
44
 
  uint i;
45
 
  
46
 
  keyseg = &keyinfo->seg[-1];
47
 
  pos = (uchar*)record + keyseg->start;
48
 
  
49
 
  dlen = _mi_calc_blob_length(keyseg->bit_start, pos);
50
 
  memcpy_fixed(&dptr, pos + keyseg->bit_start, sizeof(char*));
51
 
  if (!dptr)
52
 
  {
53
 
    my_errno= HA_ERR_NULL_IN_SPATIAL;
54
 
    return 0;
55
 
  }
56
 
  sp_mbr_from_wkb(dptr + 4, dlen - 4, SPDIMS, mbr);     /* SRID */
57
 
  
58
 
  for (i = 0, keyseg = keyinfo->seg; keyseg->type; keyseg++, i++)
59
 
  {
60
 
    uint length = keyseg->length, start= keyseg->start;
61
 
    double val;
62
 
 
63
 
    DBUG_ASSERT(length == sizeof(double));
64
 
    DBUG_ASSERT(!(start % sizeof(double)));
65
 
    DBUG_ASSERT(start < sizeof(mbr));
66
 
    DBUG_ASSERT(keyseg->type == HA_KEYTYPE_DOUBLE);
67
 
    
68
 
    val= mbr[start / sizeof (double)];
69
 
#ifdef HAVE_ISNAN
70
 
    if (isnan(val))
71
 
    {
72
 
      bzero(key, length);
73
 
      key+= length;
74
 
      len+= length;
75
 
      continue;
76
 
    }
77
 
#endif
78
 
 
79
 
    if (keyseg->flag & HA_SWAP_KEY)
80
 
    {
81
 
      uchar buf[sizeof(double)];
82
 
 
83
 
      float8store(buf, val);
84
 
      pos= &buf[length];
85
 
      while (pos > buf)
86
 
        *key++ = *--pos;
87
 
    }
88
 
    else
89
 
    {
90
 
      float8store((uchar *)key, val);
91
 
      key += length;
92
 
    }
93
 
    len+= length;
94
 
  }
95
 
  _mi_dpointer(info, key, filepos);
96
 
  return len;
97
 
}
98
 
 
99
 
/*
100
 
Calculate minimal bounding rectangle (mbr) of the spatial object
101
 
stored in "well-known binary representation" (wkb) format.
102
 
*/
103
 
static int sp_mbr_from_wkb(uchar *wkb, uint size, uint n_dims, double *mbr)
104
 
{
105
 
  uint i;
106
 
 
107
 
  for (i=0; i < n_dims; ++i)
108
 
  {
109
 
    mbr[i * 2] = DBL_MAX;
110
 
    mbr[i * 2 + 1] = -DBL_MAX;
111
 
  }
112
 
 
113
 
  return sp_get_geometry_mbr(&wkb, wkb + size, n_dims, mbr, 1);
114
 
}
115
 
 
116
 
/*
117
 
  Add one point stored in wkb to mbr
118
 
*/
119
 
 
120
 
static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims, 
121
 
                               uchar byte_order __attribute__((unused)),
122
 
                               double *mbr)
123
 
{
124
 
  double ord;
125
 
  double *mbr_end= mbr + n_dims * 2;
126
 
 
127
 
  while (mbr < mbr_end)
128
 
  {
129
 
    if ((*wkb) > end - 8)
130
 
      return -1;
131
 
    float8get(ord, (const uchar*) *wkb);
132
 
    (*wkb)+= 8;
133
 
    if (ord < *mbr)
134
 
      *mbr= ord;
135
 
    mbr++;
136
 
    if (ord > *mbr)
137
 
      *mbr= ord;
138
 
    mbr++;
139
 
  }
140
 
  return 0;
141
 
}
142
 
 
143
 
 
144
 
static int sp_get_point_mbr(uchar *(*wkb), uchar *end, uint n_dims, 
145
 
                           uchar byte_order, double *mbr)
146
 
{
147
 
  return sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr);
148
 
}
149
 
 
150
 
 
151
 
static int sp_get_linestring_mbr(uchar *(*wkb), uchar *end, uint n_dims, 
152
 
                                  uchar byte_order, double *mbr)
153
 
{
154
 
  uint n_points;
155
 
 
156
 
  n_points = uint4korr(*wkb);
157
 
  (*wkb) += 4;
158
 
  for (; n_points > 0; --n_points)
159
 
  {
160
 
    /* Add next point to mbr */
161
 
    if (sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr))
162
 
      return -1;
163
 
  }
164
 
  return 0;
165
 
}
166
 
 
167
 
 
168
 
static int sp_get_polygon_mbr(uchar *(*wkb), uchar *end, uint n_dims, 
169
 
                               uchar byte_order, double *mbr)
170
 
{
171
 
  uint n_linear_rings;
172
 
  uint n_points;
173
 
 
174
 
  n_linear_rings = uint4korr((*wkb));
175
 
  (*wkb) += 4;
176
 
 
177
 
  for (; n_linear_rings > 0; --n_linear_rings)
178
 
  {
179
 
    n_points = uint4korr((*wkb));
180
 
    (*wkb) += 4;
181
 
    for (; n_points > 0; --n_points)
182
 
    {
183
 
      /* Add next point to mbr */
184
 
      if (sp_add_point_to_mbr(wkb, end, n_dims, byte_order, mbr))
185
 
        return -1;
186
 
    }
187
 
  }
188
 
  return 0;
189
 
}
190
 
 
191
 
static int sp_get_geometry_mbr(uchar *(*wkb), uchar *end, uint n_dims,
192
 
                              double *mbr, int top)
193
 
{
194
 
  int res;
195
 
  uchar byte_order;
196
 
  uint wkb_type;
197
 
 
198
 
  byte_order = *(*wkb);
199
 
  ++(*wkb);
200
 
 
201
 
  wkb_type = uint4korr((*wkb));
202
 
  (*wkb) += 4;
203
 
 
204
 
  switch ((enum wkbType) wkb_type)
205
 
  {
206
 
    case wkbPoint:
207
 
      res = sp_get_point_mbr(wkb, end, n_dims, byte_order, mbr);
208
 
      break;
209
 
    case wkbLineString:
210
 
      res = sp_get_linestring_mbr(wkb, end, n_dims, byte_order, mbr);
211
 
      break;
212
 
    case wkbPolygon:
213
 
      res = sp_get_polygon_mbr(wkb, end, n_dims, byte_order, mbr);
214
 
      break;
215
 
    case wkbMultiPoint:
216
 
    {
217
 
      uint n_items;
218
 
      n_items = uint4korr((*wkb));
219
 
      (*wkb) += 4;
220
 
      for (; n_items > 0; --n_items)
221
 
      {
222
 
        byte_order = *(*wkb);
223
 
        ++(*wkb);
224
 
        (*wkb) += 4;
225
 
        if (sp_get_point_mbr(wkb, end, n_dims, byte_order, mbr))
226
 
          return -1;
227
 
      }
228
 
      res = 0;
229
 
      break;
230
 
    }
231
 
    case wkbMultiLineString:
232
 
    {
233
 
      uint n_items;
234
 
      n_items = uint4korr((*wkb));
235
 
      (*wkb) += 4;
236
 
      for (; n_items > 0; --n_items)
237
 
      {
238
 
        byte_order = *(*wkb);
239
 
        ++(*wkb);
240
 
        (*wkb) += 4;
241
 
        if (sp_get_linestring_mbr(wkb, end, n_dims, byte_order, mbr))
242
 
          return -1;
243
 
      }
244
 
      res = 0;
245
 
      break;
246
 
    }
247
 
    case wkbMultiPolygon:
248
 
    {
249
 
      uint n_items;
250
 
      n_items = uint4korr((*wkb));
251
 
      (*wkb) += 4;
252
 
      for (; n_items > 0; --n_items)
253
 
      {
254
 
        byte_order = *(*wkb);
255
 
        ++(*wkb);
256
 
        (*wkb) += 4;
257
 
        if (sp_get_polygon_mbr(wkb, end, n_dims, byte_order, mbr))
258
 
          return -1;
259
 
      }
260
 
      res = 0;
261
 
      break;
262
 
    }
263
 
    case wkbGeometryCollection:
264
 
    {
265
 
      uint n_items;
266
 
 
267
 
      if (!top)
268
 
        return -1;
269
 
 
270
 
      n_items = uint4korr((*wkb));
271
 
      (*wkb) += 4;
272
 
      for (; n_items > 0; --n_items)
273
 
      {
274
 
        if (sp_get_geometry_mbr(wkb, end, n_dims, mbr, 0))
275
 
          return -1;
276
 
      }
277
 
      res = 0;
278
 
      break;
279
 
    }
280
 
    default:
281
 
      res = -1;
282
 
  }
283
 
  return res;
284
 
}
285
 
 
286
 
#endif /*HAVE_SPATIAL*/