Zero  0.1.0
lsn.h
Go to the documentation of this file.
1 /* -*- mode:C++; c-basic-offset:4 -*-
2  Shore-MT -- Multi-threaded port of the SHORE storage manager
3 
4  Copyright (c) 2007-2009
5  Data Intensive Applications and Systems Labaratory (DIAS)
6  Ecole Polytechnique Federale de Lausanne
7 
8  All Rights Reserved.
9 
10  Permission to use, copy, modify and distribute this software and
11  its documentation is hereby granted, provided that both the
12  copyright notice and this permission notice appear in all copies of
13  the software, derivative works or modified versions, and any
14  portions thereof, and that both notices appear in supporting
15  documentation.
16 
17  This code is distributed in the hope that it will be useful, but
18  WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
20  DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
21  RESULTING FROM THE USE OF THIS SOFTWARE.
22 */
23 
24 /*<std-header orig-src='shore' incl-file-exclusion='SM_S_H'>
25 
26  $Id: lsn.h,v 1.5 2010/12/08 17:37:34 nhall Exp $
27 
28 SHORE -- Scalable Heterogeneous Object REpository
29 
30 Copyright (c) 1994-99 Computer Sciences Department, University of
31  Wisconsin -- Madison
32 All Rights Reserved.
33 
34 Permission to use, copy, modify and distribute this software and its
35 documentation is hereby granted, provided that both the copyright
36 notice and this permission notice appear in all copies of the
37 software, derivative works or modified versions, and any portions
38 thereof, and that both notices appear in supporting documentation.
39 
40 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
41 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
42 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
43 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
44 
45 This software was developed with support by the Advanced Research
46 Project Agency, ARPA order number 018 (formerly 8230), monitored by
47 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
48 Further funding for this work was provided by DARPA through
49 Rome Research Laboratory Contract No. F30602-97-2-0247.
50 
51 */
52 
53 #ifndef __LSN_H
54 #define __LSN_H
55 
56 #include <iostream>
57 
58 #include "w_defines.h"
59 #include "w_base.h"
60 
61 /* FRJ: Major changes to lsn_t
62  * Once the database runs long enough we will run out of
63  * partition numbers (only 64k possible).
64  * Fortunately, this is a log, so lsn_t don't last forever.
65  * Eventually things become durable and the log partition
66  * file gets reclaimed (deleted).
67  * As long as the first partition is gone before
68  * the last one fills, we can simply wrap and change the
69  * sense of lsn_t comparisions.
70  * as follows:
71  *
72  Suppose we use unsigned 8 bit partition numbers. If the current
73  global lsn has pnum >= 128 (MSB set), any lsn we encounter with
74  pnum < 128 (MSB clear) must be older:
75 
76  0 1 ... 126 127 128 129 ... 254 255
77 
78 
79  On the other hand, if the current global lsn has pnum < 128
80  (MSB clear), any lsn we encounter with pnum >= 128 (MSB set)
81  must be *older* (ie, the pnum recently wrapped from 255 back to
82  0):
83 
84  128 129 ... 254 255 0 1 ... 126 127
85 
86  The first situation is easy: regular comparisons provide the
87  ordering we want; The second is trickier due to the wrapping of
88  partition numbers. Fortunately, there's an easy way around the
89  problem! Since the MSB of the pnum is also the MSB of the
90  64-bit value holding the lsn, if comparisons interpret the
91  64-bit value as signed we get the proper ordering:
92 
93  -128 -127 ... -2 -1 0 1 ... 126 127
94 
95  We assume there are enough lsn_t that less than half are in use at
96  a time. So, we divide the universe of lsn's into four regions,
97  marked by the most significant two bits of the file.
98 
99  00+01 - don't care
100  01+10 - unsigned comparisons
101  10+11 - unsigned comparisons
102  11+00 - signed comparisons
103 
104  For now, though, we'll just assume overflow doesn't happen ;)
105 */
106 
107 typedef int64_t sm_diskaddr_t;
108 
181 typedef uint64_t lsndata_t;
182 
184 
185 const lsndata_t lsndata_max = 0xFFFFFFFFFFFFFFFF;
186 
243 class lsn_t {
244  enum {
245  file_hwm = 0xffff
246  };
247 public:
248  enum {
250  };
251  enum {
253  };
254 
255  static uint64_t mask() {
256  static uint64_t const ONE = 1;
257  return (ONE << PARTITION_SHIFT) - 1;
258  }
259 
260  lsn_t() : _data(0) {}
261 
262  lsn_t(lsndata_t data) : _data(data) {}
263 
264  lsn_t(uint32_t f, sm_diskaddr_t r) :
265  _data(from_file(f) | from_rba(r)) {}
266 
267  // copy operator
268  // lsn_t(const lsn_t & other) : _data(other._data) { }
269 
270  lsndata_t data() const {
271  return _data;
272  }
273 
274  void set(lsndata_t data) {
275  _data = data;
276  }
277 
278  bool valid() const {
279  // valid is essentially iff file != 0
280 #if W_DEBUG_LEVEL > 1
281  uint64_t copy_of_data = _data;
282  uint64_t m = mask();
283  bool first = copy_of_data > m;
284  uint64_t f =
285  to_file(copy_of_data);
286  bool second = (f != 0);
287  w_assert2(first == second);
288 #endif
289  return (_data > mask());
290  }
291 
292  uint32_t hi() const {
293  return file();
294  }
295 
296  uint32_t file() const {
297  return to_file(_data);
298  }
299 
300  sm_diskaddr_t lo() const {
301  return rba();
302  }
303 
304  sm_diskaddr_t rba() const {
305  return to_rba(_data);
306  }
307 
308  // WARNING: non-atomic read-modify-write operations!
309  void copy_rba(const lsn_t& other) {
310  _data = get_file(_data) | get_rba(other._data);
311  }
312 
313  void set_rba(sm_diskaddr_t& other) {
314  _data = get_file(_data) | get_rba(other);
315  }
316 
317  // WARNING: non-atomic read-modify-write operations!
318  lsn_t& advance(int amt) {
319  _data += amt;
320  return *this;
321  }
322 
323  lsn_t& operator+=(long delta) {
324  return advance(delta);
325  }
326 
327  lsn_t operator+(long delta) const {
328  return lsn_t(*this).advance(delta);
329  }
330 
331  bool operator>(const lsn_t& l) const {
332  return l < *this;
333  }
334 
335  bool operator<(const lsn_t& l) const {
336  return _data < l._data;
337  }
338 
339  bool operator>=(const lsn_t& l) const {
340  return !(*this < l);
341  }
342 
343  bool operator<=(const lsn_t& l) const {
344  return !(*this > l);
345  }
346 
347  bool operator==(const lsn_t& l) const {
348  return _data == l._data;
349  }
350 
351  bool operator!=(const lsn_t& l) const {
352  return !(*this == l);
353  }
354 
355  std::string str();
356 
357  bool is_null() const {
358  return _data == 0;
359  }
360 
361 /*
362  * This is the SM's idea of on-disk and in-structure
363  * things that reflect the size of a "disk". It
364  * is different from fileoff_t because the two are
365  * orthogonal. A system may be constructed that
366  * has big addresses, but is only running on
367  * a "small file" environment.
368  */
369  static const int sm_diskaddr_max;
370 
371  static const lsn_t null;
372 
373  static const lsn_t max;
374 
375  friend std::ostream& operator<<(std::ostream&, const lsn_t&);
376 
377 private:
379 
380  static uint32_t to_file(uint64_t f) {
381  return (uint32_t)(f >> PARTITION_SHIFT);
382  }
383 
384  static uint64_t get_file(uint64_t data) {
385  return data & ~mask();
386  }
387 
388  static uint64_t from_file(uint32_t data) {
389  return ((uint64_t)data) << PARTITION_SHIFT;
390  }
391 
392  static sm_diskaddr_t to_rba(uint64_t r) {
393  return (sm_diskaddr_t)(r & mask());
394  }
395 
396  static uint64_t get_rba(uint64_t data) {
397  return to_rba(data);
398  }
399 
400  static uint64_t from_rba(sm_diskaddr_t data) {
401  return to_rba(data);
402  }
403 };
404 
405 inline std::ostream& operator<<(std::ostream& o, const lsn_t& l) {
406  return o << l.file() << '.' << l.rba();
407 }
408 
409 inline std::istream& operator>>(std::istream& i, lsn_t& l) {
410  sm_diskaddr_t d;
411  char c;
412  uint64_t f;
413  i >> f >> c >> d;
414  l = lsn_t(f, d);
415  return i;
416 }
417 
418 namespace std {
421  template<>
422  struct hash<lsn_t> {
424  using result_type = std::size_t;
425 
427  return std::hash<lsndata_t>()(a.data());
428  }
429  };
430 }
431 
432 #endif // __LSN_H
bool valid() const
Definition: lsn.h:278
lsn_t operator+(long delta) const
Definition: lsn.h:327
static sm_diskaddr_t to_rba(uint64_t r)
Definition: lsn.h:392
Definition: lsn.h:245
bool operator<=(const lsn_t &l) const
Definition: lsn.h:343
lsn_t & advance(int amt)
Definition: lsn.h:318
Definition: lsn.h:249
bool operator>(const lsn_t &l) const
Definition: lsn.h:331
bool operator<(const lsn_t &l) const
Definition: lsn.h:335
lsn_t()
Definition: lsn.h:260
STL namespace.
#define w_assert2(x)
Level 2 adds some time.
Definition: w_base.h:206
static const lsn_t null
Definition: lsn.h:371
Definition: lsn.h:252
lsndata_t data() const
Definition: lsn.h:270
lsn_t(uint32_t f, sm_diskaddr_t r)
Definition: lsn.h:264
uint64_t lsndata_t
Definition: lsn.h:181
int64_t sm_diskaddr_t
Definition: lsn.h:107
Log Sequence Number. See Log Sequence Numbers (LSN).
Definition: lsn.h:243
std::istream & operator>>(std::istream &i, lsn_t &l)
Definition: lsn.h:409
std::size_t result_type
Definition: lsn.h:424
lsn_t(lsndata_t data)
Definition: lsn.h:262
void set_rba(sm_diskaddr_t &other)
Definition: lsn.h:313
static const lsn_t max
Definition: lsn.h:373
const lsndata_t lsndata_max
Definition: lsn.h:185
uint32_t file() const
Definition: lsn.h:296
void copy_rba(const lsn_t &other)
Definition: lsn.h:309
lsndata_t _data
Definition: lsn.h:378
static const int sm_diskaddr_max
Definition: lsn.h:369
bool operator!=(const lsn_t &l) const
Definition: lsn.h:351
uint32_t hi() const
Definition: lsn.h:292
static uint64_t from_rba(sm_diskaddr_t data)
Definition: lsn.h:400
bool operator==(const lsn_t &l) const
Definition: lsn.h:347
bool is_null() const
Definition: lsn.h:357
bool operator>=(const lsn_t &l) const
Definition: lsn.h:339
sm_diskaddr_t rba() const
Definition: lsn.h:304
static uint64_t get_rba(uint64_t data)
Definition: lsn.h:396
const lsndata_t lsndata_null
Definition: lsn.h:183
result_type operator()(argument_type const &a) const
Definition: lsn.h:426
friend std::ostream & operator<<(std::ostream &, const lsn_t &)
Definition: lsn.h:405
static uint64_t from_file(uint32_t data)
Definition: lsn.h:388
sm_diskaddr_t lo() const
Definition: lsn.h:300
std::string str()
Definition: lsn.cpp:63
static uint64_t mask()
Definition: lsn.h:255
static uint64_t get_file(uint64_t data)
Definition: lsn.h:384
static uint32_t to_file(uint64_t f)
Definition: lsn.h:380
lsn_t & operator+=(long delta)
Definition: lsn.h:323