eXpress “1.5”
|
00001 // 00002 // bundles.cpp 00003 // express 00004 // 00005 // Created by Adam Roberts on 9/6/11. 00006 // Copyright 2011 Adam Roberts. All rights reserved. 00007 // 00008 00009 #include "bundles.h" 00010 00011 #include "main.h" 00012 #include "targets.h" 00013 00014 using namespace std; 00015 00016 void CovarTable::increment(TargID targ1, TargID targ2, double incr_amt) { 00017 size_t pair_id = size()*min(targ1, targ2)+max(targ1, targ2); 00018 if (_covar_map.count(pair_id)) { 00019 _covar_map[pair_id] = log_add(_covar_map[pair_id], incr_amt); 00020 } else { 00021 _covar_map[pair_id] = incr_amt; 00022 } 00023 } 00024 00025 double CovarTable::get(TargID targ1, TargID targ2) { 00026 size_t pair_id = size()*min(targ1, targ2)+max(targ1, targ2); 00027 if (_covar_map.count(pair_id)) { 00028 return _covar_map[pair_id]; 00029 } else { 00030 return LOG_0; 00031 } 00032 } 00033 00034 Bundle::Bundle(Target* targ) 00035 : _counts(targ->tot_counts()), 00036 _mass(targ->mass(true)), 00037 _merged_into(NULL) { 00038 _targets.push_back(targ); 00039 } 00040 00041 size_t Bundle::size() const { 00042 boost::unique_lock<boost::mutex>(_mut); 00043 if (_merged_into) { 00044 return _targets.size() + _merged_into->size(); 00045 } 00046 return _targets.size(); 00047 } 00048 00049 void Bundle::incr_counts(size_t incr_amt) { 00050 boost::unique_lock<boost::mutex>(_mut); 00051 if (_merged_into) { 00052 _merged_into->incr_counts(incr_amt); 00053 } else { 00054 _counts += incr_amt; 00055 } 00056 } 00057 00058 void Bundle::incr_mass(double incr_amt) { 00059 boost::unique_lock<boost::mutex>(_mut); 00060 if (_merged_into) { 00061 _merged_into->incr_mass(incr_amt); 00062 } else { 00063 _mass = log_add(_mass, incr_amt); 00064 } 00065 } 00066 00067 void Bundle::reset_mass() { 00068 boost::unique_lock<boost::mutex>(_mut); 00069 _mass = LOG_0; 00070 } 00071 00072 size_t Bundle::counts() const { 00073 boost::unique_lock<boost::mutex>(_mut); 00074 if (_merged_into) { 00075 return _merged_into->counts(); 00076 } 00077 return _counts; 00078 } 00079 00080 double Bundle::mass() const { 00081 boost::unique_lock<boost::mutex>(_mut); 00082 if (_merged_into) { 00083 return _merged_into->mass(); 00084 } 00085 return _mass; 00086 } 00087 00088 00089 BundleTable::BundleTable() : _threadsafe_mode(false) {} 00090 00091 BundleTable::~BundleTable() { 00092 foreach(Bundle* bundle, _bundles) { 00093 delete bundle; 00094 } 00095 } 00096 00097 Bundle* BundleTable::get_rep(Bundle* b) { 00098 if (b->_merged_into) { 00099 return get_rep(b->_merged_into); 00100 } 00101 return b; 00102 } 00103 00104 Bundle* BundleTable::create_bundle(Target* targ) { 00105 Bundle* b = new Bundle(targ); 00106 _bundles.insert(b); 00107 return b; 00108 } 00109 00110 Bundle* BundleTable::merge(Bundle* b1, Bundle* b2) { 00111 // Lock so that only one merge can happen at a time... 00112 boost::unique_lock<boost::mutex>(_mut); 00113 00114 b1 = get_rep(b1); 00115 b2 = get_rep(b2); 00116 if (b1==b2) { 00117 return b1; 00118 } 00119 00120 if (b1->size() < b2->size()) { 00121 swap(b1, b2); 00122 } 00123 00124 if (_threadsafe_mode) { 00125 // Lock b1 and b2 00126 boost::unique_lock<boost::mutex>(b1->_mut); 00127 boost::unique_lock<boost::mutex>(b2->_mut); 00128 b1->_counts += b2->_counts; 00129 b1->_mass = log_add(b1->_mass, b2->_mass); 00130 b2->_counts = 0; 00131 b2->_mass = LOG_0; 00132 b2->_merged_into = b1; 00133 } else { 00134 foreach(Target* targ, b2->_targets) { 00135 targ->bundle(b1); 00136 b1->_targets.push_back(targ); 00137 } 00138 00139 b1->incr_counts(b2->counts()); 00140 b1->incr_mass(b2->mass()); 00141 _bundles.erase(b2); 00142 delete b2; 00143 } 00144 00145 return b1; 00146 } 00147 00148 void BundleTable::collapse() { 00149 // Lock 00150 boost::unique_lock<boost::mutex>(_mut); 00151 00152 BundleSet to_delete; 00153 foreach(Bundle* b, _bundles) { 00154 Bundle* rep = get_rep(b); 00155 if (rep != b) { 00156 foreach(Target* targ, b->_targets) { 00157 targ->bundle(rep); 00158 rep->_targets.push_back(targ); 00159 } 00160 to_delete.insert(b); 00161 } 00162 } 00163 00164 foreach(Bundle* b, to_delete) { 00165 _bundles.erase(b); 00166 delete b; 00167 } 00168 00169 }