Drizzled Public API Documentation

discrete_interval.h
1 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 Sun Microsystems, Inc.
5  *
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.
9  *
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.
14  *
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
18  */
19 
20 
21 #pragma once
22 
23 #include <cstdlib>
24 
25 #include <drizzled/definitions.h>
26 
27 namespace drizzled
28 {
29 
30 /*
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.
38 */
40 private:
41  uint64_t interval_min;
42  uint64_t interval_values;
43  uint64_t interval_max; // excluded bound. Redundant.
44 public:
45  Discrete_interval *next; // used when linked into Discrete_intervals_list
46  void replace(uint64_t start, uint64_t val, uint64_t incr)
47  {
48  interval_min= start;
49  interval_values= val;
50  interval_max= (val == UINT64_MAX) ? val : start + val * incr;
51  }
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),
55  next(NULL)
56  {}
58  interval_min(0), interval_values(0),
59  interval_max(0), next(NULL)
60  {}
61  uint64_t minimum() const { return interval_min; }
62  uint64_t values() const { return interval_values; }
63  uint64_t maximum() const { return interval_max; }
64  /*
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.
68  */
69  bool merge_if_contiguous(uint64_t start, uint64_t val, uint64_t incr)
70  {
71  if (interval_max == start)
72  {
73  if (val == UINT64_MAX)
74  {
75  interval_values= interval_max= val;
76  }
77  else
78  {
79  interval_values+= val;
80  interval_max= start + val * incr;
81  }
82  return 0;
83  }
84  return 1;
85  }
86 };
87 
88 
89 
90 /* List of Discrete_interval objects */
92 private:
93  Discrete_interval *head;
94  Discrete_interval *tail;
95  /*
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).
100  */
101  Discrete_interval *current;
102  uint32_t elements; // number of elements
103 
104  /* helper function for copy construct and assignment operator */
105  void copy_(const Discrete_intervals_list& from)
106  {
107  for (Discrete_interval *i= from.head; i; i= i->next)
108  {
109  Discrete_interval j= *i;
110  append(&j);
111  }
112  }
113 public:
115  head(NULL), tail(NULL),
116  current(NULL), elements(0) {}
118  head(NULL), tail(NULL),
119  current(NULL), elements(0)
120  {
121  copy_(from);
122  }
123  Discrete_intervals_list& operator=(const Discrete_intervals_list& from)
124  {
125  empty();
126  copy_(from);
127  return *this;
128  }
129  void empty_no_free()
130  {
131  head= current= NULL;
132  elements= 0;
133  }
134  void empty()
135  {
136  for (Discrete_interval *i= head; i;)
137  {
138  Discrete_interval *next= i->next;
139  delete i;
140  i= next;
141  }
142  empty_no_free();
143  }
144 
145  const Discrete_interval* get_next()
146  {
147  Discrete_interval *tmp= current;
148  if (current != NULL)
149  current= current->next;
150  return tmp;
151  }
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; }
156 
157  bool append(uint64_t start, uint64_t val, uint64_t incr)
158  {
159  /* first, see if this can be merged with previous */
160  if ((head == NULL) || tail->merge_if_contiguous(start, val, incr))
161  {
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));
165  }
166  return 0;
167  }
168 
169  bool append(Discrete_interval *new_interval)
170  {
171  if (unlikely(new_interval == NULL))
172  return 1;
173  if (head == NULL)
174  head= current= new_interval;
175  else
176  tail->next= new_interval;
177  tail= new_interval;
178  elements++;
179  return 0;
180  }
181 
182 };
183 
184 } /* namespace drizzled */
185 
TODO: Rename this file - func.h is stupid.