HPCToolkit
intervals.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //*****************************************************************************
48 // system includes
49 //*****************************************************************************
50 
51 #include <iostream>
52 
53 
54 
55 //*****************************************************************************
56 // local includes
57 //*****************************************************************************
58 #include "intervals.h"
59 
60 using namespace std;
61 
62 
63 //*****************************************************************************
64 // interface operations
65 //*****************************************************************************
66 
67 
68 //-----------------------------------------------------------------------------
69 // Method insert:
70 //
71 // insert [start,end) into the interval set. merge with overlapping in the
72 // set to maintain the invariant that no point is contained in more
73 // than one interval.
74 //-----------------------------------------------------------------------------
75 void
76 intervals::insert(void * start, void * end)
77 {
78  if (start >= end) return;
79 
80  map<void *, void *>::iterator lb;
81  map<void *, void *>::iterator ub;
82 
83  lb = mymap.upper_bound(start);
84  ub = mymap.upper_bound(end);
85 
86  // inserted interval spans or overlaps one or more intervals if
87  // iterators are not equal
88  bool overlaps = (lb != ub);
89 
90  if (lb != mymap.begin()) {
91  lb--; // move back one interval to see if it contains start
92  if (start <= (*lb).second) {
93  // start is within existing interval; adjust lower bound of union interval
94  start = (*lb).first;
95  overlaps = true;
96  } else lb++; // lb doesn't contain start; thus, erasure shouldn't include lb
97  }
98 
99  if (ub != mymap.begin()) {
100  ub--; // move back one interval to see if it contains end
101  if (end <= (*ub).second) {
102  // end is within existing interval; adjust upper bound of union interval
103  end = (*ub).second;
104  overlaps = true;
105  }
106  ub++; // increment ub because erase will only remove up to but not ub
107  }
108 
109  if (overlaps) {
110  // remove any intervals that overlap the range being inserted. erase will
111  // remove intervals starting at lb up to but not including ub.
112  mymap.erase(lb,ub);
113  }
114 
115  // insert the refined interval
116  mymap[start] = end;
117 
118  return;
119 }
120 
121 
122 //-----------------------------------------------------------------------------
123 // Method contains:
124 // if any interval contains the query point i, return it.
125 // otherwise, return NULL
126 //-----------------------------------------------------------------------------
127 pair<void *const, void *> *
129 {
130  map<void *, void *>::iterator up;
131  up = mymap.upper_bound(i);
132  if (up != mymap.begin()) {
133  --up;
134  if (i >= (*up).first && i < (*up).second) return &(*up);
135  }
136  return NULL;
137 }
138 
139 
140 //-----------------------------------------------------------------------------
141 // Method clear:
142 // reset the map to empty
143 //-----------------------------------------------------------------------------
144 void
146 {
147  mymap.clear();
148 }
149 
150 
151 //-----------------------------------------------------------------------------
152 // Method dump:
153 // print all of the intervals in the set to stdout
154 //-----------------------------------------------------------------------------
155 void
157 {
158  map<void *, void *>::iterator it;
159  cout << "intervals: ";
160  for (it = mymap.begin(); it != mymap.end(); it++)
161  cout << "[" << (*it).first << "," << (*it).second << ") ";
162  cout << endl;
163 }
164 
165 
166 
167 //*****************************************************************************
168 // private operations
169 //*****************************************************************************
170 // #define UNIT_TEST
171 #ifdef UNIT_TEST
172 intervals ranges;
173 
174 void
175 test_interval_set_insert(unsigned long start, unsigned long end)
176 {
177  void *vstart = (void *) start;
178  void *vend = (void *) end;
179  cout << "inserting [" << vstart << "," << vend << ")" << endl;
180  ranges.insert(vstart, vend);
181  ranges.dump();
182 }
183 
184 
185 void
186 test_interval_set_contains(unsigned long i)
187 {
188  pair<void *const, void *> *result = ranges.contains((void *) i);
189  cout << "search for " << i << ": ";
190  if (result)
191  cout << "found interval [" << result->first << ","<< result->second << ")";
192  else cout << "no interval found";
193  cout << endl;
194 }
195 
196 
197 main()
198 {
199  test_interval_set_insert(10,20);
200 
201  // disjoint insertion
202  test_interval_set_insert(5,7);
203 
204  // disjoint insertion
205  test_interval_set_insert(30,32);
206 
207  // endpoints equal
208  test_interval_set_insert(20,28);
209 
210  // disjoint insertion
211  test_interval_set_insert(60,89);
212 
213  // start within interval
214  test_interval_set_insert(27,45);
215 
216  // end within interval
217  test_interval_set_insert(57,61);
218 
219  // joining intervals
220  test_interval_set_insert(41,58);
221 
222  // subsuming intervals
223  test_interval_set_insert(1,90);
224 
225  // disjoint insertion
226  test_interval_set_insert(94,99);
227 
228  // disjoint insertion
229  test_interval_set_insert(100,110);
230 
231  // disjoint insertion
232  test_interval_set_insert(115,120);
233 
234  // disjoint insertion
235  test_interval_set_insert(140,145);
236 
237  // disjoint insertion
238  test_interval_set_insert(155,165);
239 
240  // linking and subsumption
241  test_interval_set_insert(95,142);
242 
243  // linking and subsumption
244  test_interval_set_insert(93,186);
245 
246  // subsumption
247  test_interval_set_insert(92,187);
248 
249  test_interval_set_contains(72);
250  test_interval_set_contains(21);
251  test_interval_set_contains(33);
252  test_interval_set_contains(12);
253  test_interval_set_contains(96);
254  test_interval_set_contains(8);
255  test_interval_set_contains(0);
256  test_interval_set_contains(200);
257  test_interval_set_contains(91);
258 }
259 #endif // UNIT_TEST
void dump()
Definition: intervals.cpp:156
void insert(void *start, void *end)
Definition: intervals.cpp:76
int main(int argc, char *argv[])
Definition: main.cpp:125
void clear()
Definition: intervals.cpp:145
#define NULL
Definition: ElfHelper.cpp:85
std::pair< void *const, void * > * contains(void *i)
Definition: intervals.cpp:128