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
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
21
#ifndef DRIZZLED_DISCRETE_INTERVAL_H
22
#define DRIZZLED_DISCRETE_INTERVAL_H
26
#include "drizzled/definitions.h"
32
Such interval is "discrete": it is the set of
33
{ auto_inc_interval_min + k * increment,
34
0 <= k <= (auto_inc_interval_values-1) }
35
Where "increment" is maintained separately by the user of this class (and is
36
currently only session->variables.auto_increment_increment).
37
It mustn't derive from memory::SqlAlloc, because SET INSERT_ID needs to
38
allocate memory which must stay allocated for use by the next statement.
40
class Discrete_interval {
42
uint64_t interval_min;
43
uint64_t interval_values;
44
uint64_t interval_max; // excluded bound. Redundant.
46
Discrete_interval *next; // used when linked into Discrete_intervals_list
47
void replace(uint64_t start, uint64_t val, uint64_t incr)
51
interval_max= (val == UINT64_MAX) ? val : start + val * incr;
53
Discrete_interval(uint64_t start, uint64_t val, uint64_t incr) :
54
interval_min(start), interval_values(val),
55
interval_max((val == UINT64_MAX) ? val : start + val * incr),
59
interval_min(0), interval_values(0),
60
interval_max(0), next(NULL)
62
uint64_t minimum() const { return interval_min; };
63
uint64_t values() const { return interval_values; };
64
uint64_t maximum() const { return interval_max; };
66
If appending [3,5] to [1,2], we merge both in [1,5] (they should have the
67
same increment for that, user of the class has to ensure that). That is
68
just a space optimization. Returns 0 if merge succeeded.
70
bool merge_if_contiguous(uint64_t start, uint64_t val, uint64_t incr)
72
if (interval_max == start)
74
if (val == UINT64_MAX)
76
interval_values= interval_max= val;
80
interval_values+= val;
81
interval_max= start + val * incr;
91
/* List of Discrete_interval objects */
92
class Discrete_intervals_list {
94
Discrete_interval *head;
95
Discrete_interval *tail;
97
When many intervals are provided at the beginning of the execution of a
98
statement (in a replication slave or SET INSERT_ID), "current" points to
99
the interval being consumed by the thread now (so "current" goes from
100
"head" to "tail" then to NULL).
102
Discrete_interval *current;
103
uint32_t elements; // number of elements
105
/* helper function for copy construct and assignment operator */
106
void copy_(const Discrete_intervals_list& from)
108
for (Discrete_interval *i= from.head; i; i= i->next)
110
Discrete_interval j= *i;
115
Discrete_intervals_list() :
116
head(NULL), tail(NULL),
117
current(NULL), elements(0) {};
118
Discrete_intervals_list(const Discrete_intervals_list& from) :
119
head(NULL), tail(NULL),
120
current(NULL), elements(0)
124
Discrete_intervals_list& operator=(const Discrete_intervals_list& from)
137
for (Discrete_interval *i= head; i;)
139
Discrete_interval *next= i->next;
146
const Discrete_interval* get_next()
148
Discrete_interval *tmp= current;
150
current= current->next;
153
~Discrete_intervals_list() { empty(); };
154
uint64_t minimum() const { return (head ? head->minimum() : 0); };
155
uint64_t maximum() const { return (head ? tail->maximum() : 0); };
156
uint32_t nb_elements() const { return elements; }
158
bool append(uint64_t start, uint64_t val, uint64_t incr)
160
/* first, see if this can be merged with previous */
161
if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
163
/* it cannot, so need to add a new interval */
164
Discrete_interval *new_interval= new Discrete_interval(start, val, incr);
165
return(append(new_interval));
170
bool append(Discrete_interval *new_interval)
172
if (unlikely(new_interval == NULL))
175
head= current= new_interval;
177
tail->next= new_interval;
185
} /* namespace drizzled */
187
#endif /* DRIZZLED_DISCRETE_INTERVAL_H */