CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
226 lines
7.7 KiB
C++
226 lines
7.7 KiB
C++
/*
|
|
* See the dyninst/COPYRIGHT file for copyright information.
|
|
*
|
|
* We provide the Paradyn Tools (below described as "Paradyn")
|
|
* on an AS IS basis, and do not warrant its validity or performance.
|
|
* We reserve the right to update, modify, or discontinue this
|
|
* software at any time. We shall have no obligation to supply such
|
|
* updates or modifications or any other form of support to you.
|
|
*
|
|
* By your use of Paradyn, you understand and agree that we (or any
|
|
* other person or entity with proprietary rights in Paradyn) are
|
|
* under no obligation to provide either maintenance services,
|
|
* update services, notices of latent defects, or correction of
|
|
* defects for Paradyn.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#if !defined(IBSTREE_FAST_H)
|
|
#define IBSTREE_FAST_H
|
|
#include "IBSTree.h"
|
|
#include <assert.h>
|
|
#include <set>
|
|
#include <iostream>
|
|
|
|
namespace Dyninst
|
|
{
|
|
|
|
template <typename ITYPE >
|
|
class IBSTree_fast {
|
|
private:
|
|
// reader-writer lock to coordinate concurrent operations
|
|
mutable dyn_rwlock rwlock;
|
|
|
|
public:
|
|
typedef typename ITYPE::type interval_type;
|
|
|
|
struct interval_by_high {
|
|
using is_transparent = void;
|
|
|
|
bool operator()(const ITYPE* lhs, const ITYPE* rhs) const
|
|
{
|
|
if (lhs->high() != rhs->high()) return lhs->high() < rhs->high();
|
|
if (lhs->low() != rhs->low()) return lhs->low() < rhs->low();
|
|
return lhs < rhs;
|
|
}
|
|
|
|
bool operator()(const ITYPE* lhs, interval_type rhs) const { return lhs->high() < rhs; }
|
|
bool operator()(interval_type lhs, const ITYPE* rhs) const { return lhs < rhs->high(); }
|
|
};
|
|
|
|
IBSTree<ITYPE> overlapping_intervals;
|
|
typedef std::set<ITYPE*, interval_by_high> interval_set;
|
|
interval_set unique_intervals;
|
|
|
|
IBSTree_fast()
|
|
{
|
|
}
|
|
~IBSTree_fast()
|
|
{
|
|
//std::cerr << "Fast interval tree had " << unique_intervals.size() << " unique intervals and " << overlapping_intervals.size() << " overlapping" << std::endl;
|
|
}
|
|
int size() const
|
|
{
|
|
dyn_rwlock::shared_lock l(rwlock);
|
|
return overlapping_intervals.size() + unique_intervals.size();
|
|
}
|
|
bool empty() const
|
|
{
|
|
dyn_rwlock::shared_lock l(rwlock);
|
|
return unique_intervals.empty() && overlapping_intervals.empty();
|
|
}
|
|
void insert(ITYPE*);
|
|
void remove(ITYPE*);
|
|
int find(interval_type, std::set<ITYPE*> &) const;
|
|
int find(ITYPE* I, std::set<ITYPE*>&) const;
|
|
void successor(interval_type X, std::set<ITYPE*>& ) const;
|
|
ITYPE* successor(interval_type X) const;
|
|
void clear();
|
|
friend std::ostream& operator<<(std::ostream& stream, const IBSTree_fast<ITYPE>& tree)
|
|
{
|
|
dyn_rwlock::shared_lock l(tree.rwlock);
|
|
std::copy(tree.unique_intervals.begin(), tree.unique_intervals.end(),
|
|
std::ostream_iterator<typename Dyninst::IBSTree_fast<ITYPE>::interval_set::value_type>(stream, "\n"));
|
|
stream << tree.overlapping_intervals;
|
|
return stream;
|
|
}
|
|
|
|
};
|
|
|
|
template <class ITYPE>
|
|
void IBSTree_fast<ITYPE>::insert(ITYPE* entry)
|
|
{
|
|
dyn_rwlock::unique_lock l(rwlock);
|
|
|
|
// find in overlapping first
|
|
std::set<ITYPE*> dummy;
|
|
if(overlapping_intervals.find(entry, dummy))
|
|
{
|
|
overlapping_intervals.insert(entry);
|
|
} else {
|
|
typename interval_set::iterator lower =
|
|
unique_intervals.upper_bound(entry->low());
|
|
// lower.high first >= entry.low
|
|
if (lower != unique_intervals.end() && (**lower == *entry)) return;
|
|
typename interval_set::iterator upper = lower;
|
|
while(upper != unique_intervals.end() &&
|
|
(*upper)->low() <= entry->high())
|
|
{
|
|
overlapping_intervals.insert(*upper);
|
|
++upper;
|
|
}
|
|
if(upper != lower)
|
|
{
|
|
unique_intervals.erase(lower, upper);
|
|
overlapping_intervals.insert(entry);
|
|
}
|
|
else
|
|
{
|
|
unique_intervals.insert(entry);
|
|
}
|
|
}
|
|
}
|
|
template <class ITYPE>
|
|
void IBSTree_fast<ITYPE>::remove(ITYPE* entry)
|
|
{
|
|
dyn_rwlock::unique_lock l(rwlock);
|
|
|
|
overlapping_intervals.remove(entry);
|
|
auto found = unique_intervals.lower_bound(entry->high());
|
|
while (found != unique_intervals.end() && (*found)->high() == entry->high()) {
|
|
if (*found == entry) {
|
|
unique_intervals.erase(found);
|
|
break;
|
|
}
|
|
++found;
|
|
}
|
|
}
|
|
template<class ITYPE>
|
|
int IBSTree_fast<ITYPE>::find(interval_type X, std::set<ITYPE*> &results) const
|
|
{
|
|
dyn_rwlock::shared_lock l(rwlock);
|
|
int num_old_results = results.size();
|
|
|
|
int num_overlapping = overlapping_intervals.find(X, results);
|
|
if(num_overlapping > 0) return num_overlapping;
|
|
|
|
typename interval_set::const_iterator found_unique = unique_intervals.upper_bound(X);
|
|
if(found_unique != unique_intervals.end())
|
|
{
|
|
if((*found_unique)->low() > X) return 0;
|
|
results.insert(*found_unique);
|
|
}
|
|
return results.size() - num_old_results;
|
|
}
|
|
template <typename ITYPE>
|
|
int IBSTree_fast<ITYPE>::find(ITYPE* I, std::set<ITYPE*>&results) const
|
|
{
|
|
dyn_rwlock::shared_lock l(rwlock);
|
|
int num_old_results = results.size();
|
|
int num_overlapping = overlapping_intervals.find(I, results);
|
|
if(num_overlapping) return num_overlapping;
|
|
typename interval_set::const_iterator lb = unique_intervals.upper_bound(I->low());
|
|
typename interval_set::const_iterator ub = lb;
|
|
while(ub != unique_intervals.end() && (*ub)->low() < I->high())
|
|
{
|
|
results.insert(*ub);
|
|
++ub;
|
|
}
|
|
int result = results.size() - num_old_results;
|
|
return result;
|
|
}
|
|
template<typename ITYPE>
|
|
void IBSTree_fast<ITYPE>::successor(interval_type X, std::set<ITYPE*>& results) const
|
|
{
|
|
dyn_rwlock::shared_lock l(rwlock);
|
|
ITYPE* overlapping_ub = overlapping_intervals.successor(X);
|
|
|
|
typename interval_set::const_iterator unique_ub = unique_intervals.upper_bound(X);
|
|
if(overlapping_ub && (unique_ub != unique_intervals.end()))
|
|
{
|
|
results.insert(overlapping_ub->low() < (*unique_ub)->low() ? overlapping_ub : *unique_ub);
|
|
}
|
|
else if(overlapping_ub)
|
|
{
|
|
results.insert(overlapping_ub);
|
|
}
|
|
else if(unique_ub != unique_intervals.end())
|
|
{
|
|
results.insert(*unique_ub);
|
|
}
|
|
}
|
|
template <typename ITYPE>
|
|
ITYPE* IBSTree_fast<ITYPE>::successor(interval_type X) const
|
|
{
|
|
std::set<ITYPE*> tmp;
|
|
successor(X, tmp);
|
|
assert(tmp.size() <= 1);
|
|
if(tmp.empty()) return NULL;
|
|
return *tmp.begin();
|
|
}
|
|
template <typename ITYPE>
|
|
void IBSTree_fast<ITYPE>::clear()
|
|
{
|
|
dyn_rwlock::unique_lock l(rwlock);
|
|
overlapping_intervals.clear();
|
|
unique_intervals.clear();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
#endif
|