1 // ***************************************************************************
2 // BamMultiMerger_p.h (c) 2010 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 9 September 2011 (DB)
7 // ---------------------------------------------------------------------------
8 // Provides merging functionality for BamMultiReader. At this point, supports
9 // sorting results by (refId, position) or by read name.
10 // ***************************************************************************
12 #ifndef BAMMULTIMERGER_P_H
13 #define BAMMULTIMERGER_P_H
19 // This file is not part of the BamTools API. It exists purely as an
20 // implementation detail. This header file may change from version to version
21 // without notice, or even be removed.
25 #include <api/BamAlignment.h>
26 #include <api/BamReader.h>
35 typedef std::pair<BamReader*, BamAlignment*> ReaderAlignment;
37 // generic MultiMerger interface
38 class IBamMultiMerger {
41 IBamMultiMerger(void) { }
42 virtual ~IBamMultiMerger(void) { }
45 virtual void Add(ReaderAlignment value) =0;
46 virtual void Clear(void) =0;
47 virtual const ReaderAlignment& First(void) const =0;
48 virtual bool IsEmpty(void) const =0;
49 virtual void Remove(BamReader* reader) =0;
50 virtual int Size(void) const =0;
51 virtual ReaderAlignment TakeFirst(void) =0;
54 // IBamMultiMerger implementation - sorted on BamAlignment: (RefId, Position)
55 class PositionMultiMerger : public IBamMultiMerger {
58 PositionMultiMerger(void) : IBamMultiMerger() { }
59 ~PositionMultiMerger(void) { }
62 void Add(ReaderAlignment value);
64 const ReaderAlignment& First(void) const;
65 bool IsEmpty(void) const;
66 void Remove(BamReader* reader);
68 ReaderAlignment TakeFirst(void);
71 typedef std::pair<int, int> KeyType;
72 typedef ReaderAlignment ValueType;
73 typedef std::pair<KeyType, ValueType> ElementType;
75 typedef std::multimap<KeyType, ValueType> ContainerType;
76 typedef ContainerType::iterator DataIterator;
77 typedef ContainerType::const_iterator DataConstIterator;
82 // IBamMultiMerger implementation - sorted on BamAlignment: Name
83 class ReadNameMultiMerger : public IBamMultiMerger {
86 ReadNameMultiMerger(void) : IBamMultiMerger() { }
87 ~ReadNameMultiMerger(void) { }
90 void Add(ReaderAlignment value);
92 const ReaderAlignment& First(void) const;
93 bool IsEmpty(void) const;
94 void Remove(BamReader* reader);
96 ReaderAlignment TakeFirst(void);
99 typedef std::string KeyType;
100 typedef ReaderAlignment ValueType;
101 typedef std::pair<KeyType, ValueType> ElementType;
103 typedef std::multimap<KeyType, ValueType> ContainerType;
104 typedef ContainerType::iterator DataIterator;
105 typedef ContainerType::const_iterator DataConstIterator;
107 ContainerType m_data;
110 // IBamMultiMerger implementation - unsorted BAM file(s)
111 class UnsortedMultiMerger : public IBamMultiMerger {
114 UnsortedMultiMerger(void) : IBamMultiMerger() { }
115 ~UnsortedMultiMerger(void) { }
118 void Add(ReaderAlignment value);
120 const ReaderAlignment& First(void) const;
121 bool IsEmpty(void) const;
122 void Remove(BamReader* reader);
123 int Size(void) const;
124 ReaderAlignment TakeFirst(void);
127 typedef ReaderAlignment ElementType;
128 typedef std::vector<ReaderAlignment> ContainerType;
129 typedef ContainerType::iterator DataIterator;
130 typedef ContainerType::const_iterator DataConstIterator;
132 ContainerType m_data;
135 // ------------------------------------------
136 // PositionMultiMerger implementation
138 inline void PositionMultiMerger::Add(ReaderAlignment value) {
139 const KeyType key( value.second->RefID, value.second->Position );
140 m_data.insert( ElementType(key, value) );
143 inline void PositionMultiMerger::Clear(void) {
147 inline const ReaderAlignment& PositionMultiMerger::First(void) const {
148 const ElementType& entry = (*m_data.begin());
152 inline bool PositionMultiMerger::IsEmpty(void) const {
153 return m_data.empty();
156 inline void PositionMultiMerger::Remove(BamReader* reader) {
158 if ( reader == 0 ) return;
159 const std::string filenameToRemove = reader->GetFilename();
161 // iterate over readers in cache
162 DataIterator dataIter = m_data.begin();
163 DataIterator dataEnd = m_data.end();
164 for ( ; dataIter != dataEnd; ++dataIter ) {
165 const ValueType& entry = (*dataIter).second;
166 const BamReader* entryReader = entry.first;
167 if ( entryReader == 0 ) continue;
169 // remove iterator on match
170 if ( entryReader->GetFilename() == filenameToRemove ) {
171 m_data.erase(dataIter);
177 inline int PositionMultiMerger::Size(void) const {
178 return m_data.size();
181 inline ReaderAlignment PositionMultiMerger::TakeFirst(void) {
182 DataIterator first = m_data.begin();
183 ReaderAlignment next = (*first).second;
188 // ------------------------------------------
189 // ReadNameMultiMerger implementation
191 inline void ReadNameMultiMerger::Add(ReaderAlignment value) {
192 BamAlignment* al = value.second;
193 if ( al->BuildCharData() ) {
194 const KeyType key(al->Name);
195 m_data.insert( ElementType(key, value) );
199 inline void ReadNameMultiMerger::Clear(void) {
203 inline const ReaderAlignment& ReadNameMultiMerger::First(void) const {
204 const ElementType& entry = (*m_data.begin());
208 inline bool ReadNameMultiMerger::IsEmpty(void) const {
209 return m_data.empty();
212 inline void ReadNameMultiMerger::Remove(BamReader* reader) {
214 if ( reader == 0 ) return;
215 const std::string filenameToRemove = reader->GetFilename();
217 // iterate over readers in cache
218 DataIterator dataIter = m_data.begin();
219 DataIterator dataEnd = m_data.end();
220 for ( ; dataIter != dataEnd; ++dataIter ) {
221 const ValueType& entry = (*dataIter).second;
222 const BamReader* entryReader = entry.first;
223 if ( entryReader == 0 ) continue;
225 // remove iterator on match
226 if ( entryReader->GetFilename() == filenameToRemove ) {
227 m_data.erase(dataIter);
234 inline int ReadNameMultiMerger::Size(void) const {
235 return m_data.size();
238 inline ReaderAlignment ReadNameMultiMerger::TakeFirst(void) {
239 DataIterator first = m_data.begin();
240 ReaderAlignment next = (*first).second;
245 // ------------------------------------------
246 // UnsortedMultiMerger implementation
248 inline void UnsortedMultiMerger::Add(ReaderAlignment value) {
249 m_data.push_back(value);
252 inline void UnsortedMultiMerger::Clear(void) {
253 for (size_t i = 0; i < m_data.size(); ++i )
257 inline const ReaderAlignment& UnsortedMultiMerger::First(void) const {
258 return m_data.front();
261 inline bool UnsortedMultiMerger::IsEmpty(void) const {
262 return m_data.empty();
265 inline void UnsortedMultiMerger::Remove(BamReader* reader) {
267 if ( reader == 0 ) return;
268 const std::string filenameToRemove = reader->GetFilename();
270 // iterate over readers in cache
271 DataIterator dataIter = m_data.begin();
272 DataIterator dataEnd = m_data.end();
273 for ( ; dataIter != dataEnd; ++dataIter ) {
274 const BamReader* entryReader = (*dataIter).first;
275 if ( entryReader == 0 ) continue;
277 // remove iterator on match
278 if ( entryReader->GetFilename() == filenameToRemove ) {
279 m_data.erase(dataIter);
285 inline int UnsortedMultiMerger::Size(void) const {
286 return m_data.size();
289 inline ReaderAlignment UnsortedMultiMerger::TakeFirst(void) {
290 ReaderAlignment first = m_data.front();
291 m_data.erase( m_data.begin() );
295 } // namespace Internal
296 } // namespace BamTools
298 #endif // BAMMULTIMERGER_P_H