Fréchet View  1.6.0
A Tool for Exploring Fréchet Distance Algorithms
interval.cpp
Go to the documentation of this file.
1 
2 #include <interval.h>
3 #include <iostream>
4 
5 #ifdef _MSC_VER
6 #include <intrin.h>
7 #pragma intrinsic(_InterlockedCompareExchange64)
8 #endif
9 
10 using namespace frechet;
11 using namespace data;
12 
13 const Interval Interval::UNIT (0.0,1.0);
15 
20 {
21  // Q: do the member variables have to be 'volatile'
22  // do we have to use atomic<double> instead ?
23  assign_min_lf(&_lower, that._lower);
24  assign_max_lf(&_upper, that._upper);
25  return *this;
26 }
27 
28 void Interval::assign_min_lf(volatile double *value, double update_value)
29 {
30  double old_value = *value; // when reading this value, do we need a memory barrier?
31  while (update_value < old_value)
32  {
33  int64_t prev_ivalue = compare_and_swap(
34  (volatile int64_t*)value,
35  *(int64_t*)&old_value,
36  *(int64_t*)&update_value);
37 
38  double prev_value = *(double*)&prev_ivalue;
39  if (prev_value == old_value)
40  return;
41  else
42  old_value = prev_value;
43  }
44 }
45 
46 void Interval::assign_max_lf(volatile double *value, double update_value)
47 {
48  double old_value = *value; // when reading this value, do we need a memory barrier?
49  while (update_value > old_value)
50  {
51  int64_t prev_ivalue = compare_and_swap(
52  (volatile int64_t*)value,
53  *(int64_t*)&old_value,
54  *(int64_t*)&update_value);
55 
56  double prev_value = *(double*)&prev_ivalue;
57  if (prev_value == old_value)
58  return;
59  else
60  old_value = prev_value;
61  }
62 }
63 
64 int64_t Interval::compare_and_swap(volatile int64_t* value, int64_t old_value, int64_t update_value)
65 {
66 #if defined __GNUC__
67  return __sync_val_compare_and_swap (value, old_value, update_value);
68 #elif defined _MSC_VER
69  // Destination = value
70  // Comparand = old_value
71  // Exchange = new value
72  // returns actual value of *Destination
73  return _InterlockedCompareExchange64(value,update_value,old_value);
74 #else
75 # error
76 #endif
77 }
78 
79 std::ostream& frechet::data::operator <<(std::ostream &stream, const frechet::data::Interval &ival)
80 {
81  return stream << "["<<ival.lower()<<".."<<ival.upper()<<"]";
82 }
83 
84 std::ostream& frechet::data::operator <<(std::ostream &stream, const frechet::data::IntervalPair &ival)
85 {
86  return stream << ival.H << " x " << ival.V;
87 }
88 
89 QDebug operator<<(QDebug debug, const frechet::data::Interval &ival)
90 {
91  return debug << "["<<ival.lower()<<".."<<ival.upper()<<"]";
92 }
93 
94 QDebug operator<<(QDebug debug, const frechet::data::IntervalPair &ival)
95 {
96  return debug << ival.H << " x " << ival.V;
97 }
static const Interval INVALID
an invalid interval (contains NAN values)
Definition: interval.h:39
Interval H
horizontal interval
Definition: interval.h:459
global definitions for all algorithms.
Interval & union_lf(const Interval &that)
lock-free union operator; not used and not tested
Definition: interval.cpp:19
double _lower
lower and upper border of the interval
Definition: interval.h:34
a pair of horizonal / vertical intervals.
Definition: interval.h:456
double upper() const
Definition: interval.h:96
std::ostream & operator<<(std::ostream &stream, const frechet::data::Interval &ival)
operator for printing debug info to a std::ostream
Definition: interval.cpp:79
Interval V
vertical interval
Definition: interval.h:460
static void assign_max_lf(volatile double *value, double update_value)
lock-free assigment; not used and not tested
Definition: interval.cpp:46
double lower() const
Definition: interval.h:92
static void assign_min_lf(volatile double *value, double update_value)
lock-free assigment; not used and not tested
Definition: interval.cpp:28
static const Interval UNIT
the unit interval [0,1]
Definition: interval.h:37
static int64_t compare_and_swap(volatile int64_t *value, int64_t old_value, int64_t update_value)
lock-free compare-and-swap; not used and not tested
Definition: interval.cpp:64
an interval of two double values.
Definition: interval.h:31