1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
#include <drizzled/definitions.h>
31
Such interval is "discrete": it is the set of
32
{ auto_inc_interval_min + k * increment,
33
0 <= k <= (auto_inc_interval_values-1) }
34
Where "increment" is maintained separately by the user of this class (and is
35
currently only session->variables.auto_increment_increment).
36
It mustn't derive from memory::SqlAlloc, because SET INSERT_ID needs to
37
allocate memory which must stay allocated for use by the next statement.
39
class Discrete_interval {
41
uint64_t interval_min;
42
uint64_t interval_values;
43
uint64_t interval_max; // excluded bound. Redundant.
45
Discrete_interval *next; // used when linked into Discrete_intervals_list
46
void replace(uint64_t start, uint64_t val, uint64_t incr)
50
interval_max= (val == UINT64_MAX) ? val : start + val * incr;
52
Discrete_interval(uint64_t start, uint64_t val, uint64_t incr) :
53
interval_min(start), interval_values(val),
54
interval_max((val == UINT64_MAX) ? val : start + val * incr),
58
interval_min(0), interval_values(0),
59
interval_max(0), next(NULL)
61
uint64_t minimum() const { return interval_min; }
62
uint64_t values() const { return interval_values; }
63
uint64_t maximum() const { return interval_max; }
65
If appending [3,5] to [1,2], we merge both in [1,5] (they should have the
66
same increment for that, user of the class has to ensure that). That is
67
just a space optimization. Returns 0 if merge succeeded.
69
bool merge_if_contiguous(uint64_t start, uint64_t val, uint64_t incr)
71
if (interval_max == start)
73
if (val == UINT64_MAX)
75
interval_values= interval_max= val;
79
interval_values+= val;
80
interval_max= start + val * incr;
90
/* List of Discrete_interval objects */
91
class Discrete_intervals_list {
93
Discrete_interval *head;
94
Discrete_interval *tail;
96
When many intervals are provided at the beginning of the execution of a
97
statement (in a replication slave or SET INSERT_ID), "current" points to
98
the interval being consumed by the thread now (so "current" goes from
99
"head" to "tail" then to NULL).
101
Discrete_interval *current;
102
uint32_t elements; // number of elements
104
/* helper function for copy construct and assignment operator */
105
void copy_(const Discrete_intervals_list& from)
107
for (Discrete_interval *i= from.head; i; i= i->next)
109
Discrete_interval j= *i;
114
Discrete_intervals_list() :
115
head(NULL), tail(NULL),
116
current(NULL), elements(0) {}
117
Discrete_intervals_list(const Discrete_intervals_list& from) :
118
head(NULL), tail(NULL),
119
current(NULL), elements(0)
123
Discrete_intervals_list& operator=(const Discrete_intervals_list& from)
136
for (Discrete_interval *i= head; i;)
138
Discrete_interval *next= i->next;
145
const Discrete_interval* get_next()
147
Discrete_interval *tmp= current;
149
current= current->next;
152
~Discrete_intervals_list() { empty(); }
153
uint64_t minimum() const { return (head ? head->minimum() : 0); }
154
uint64_t maximum() const { return (head ? tail->maximum() : 0); }
155
uint32_t nb_elements() const { return elements; }
157
bool append(uint64_t start, uint64_t val, uint64_t incr)
159
/* first, see if this can be merged with previous */
160
if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
162
/* it cannot, so need to add a new interval */
163
Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
164
return(append(new_interval));
169
bool append(Discrete_interval *new_interval)
171
if (unlikely(new_interval == NULL))
174
head= current= new_interval;
176
tail->next= new_interval;
184
} /* namespace drizzled */