]> git.donarmstrong.com Git - bamtools.git/blob - src/api/internal/BamMultiMerger_p.h
Minor cleanup
[bamtools.git] / src / api / internal / BamMultiMerger_p.h
1 // ***************************************************************************
2 // BamMultiMerger_p.h (c) 2010 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 9 September 2011 (DB)
6 // ---------------------------------------------------------------------------
7 // Provides merging functionality for BamMultiReader.  At this point, supports
8 // sorting results by (refId, position) or by read name.
9 // ***************************************************************************
10
11 #ifndef BAMMULTIMERGER_P_H
12 #define BAMMULTIMERGER_P_H
13
14 //  -------------
15 //  W A R N I N G
16 //  -------------
17 //
18 // This file is not part of the BamTools API.  It exists purely as an
19 // implementation detail. This header file may change from version to version
20 // without notice, or even be removed.
21 //
22 // We mean it.
23
24 #include <api/BamAlignment.h>
25 #include <api/BamReader.h>
26 #include <map>
27 #include <queue>
28 #include <string>
29 #include <utility>
30
31 namespace BamTools {
32 namespace Internal {
33
34 typedef std::pair<BamReader*, BamAlignment*> ReaderAlignment;
35
36 // generic MultiMerger interface
37 class IBamMultiMerger {
38
39     public:
40         IBamMultiMerger(void) { }
41         virtual ~IBamMultiMerger(void) { }
42
43     public:
44         virtual void Add(ReaderAlignment value) =0;
45         virtual void Clear(void) =0;
46         virtual const ReaderAlignment& First(void) const =0;
47         virtual bool IsEmpty(void) const =0;
48         virtual void Remove(BamReader* reader) =0;
49         virtual int Size(void) const =0;
50         virtual ReaderAlignment TakeFirst(void) =0;
51 };
52
53 // IBamMultiMerger implementation - sorted on BamAlignment: (RefId, Position)
54 class PositionMultiMerger : public IBamMultiMerger {
55
56     public:
57         PositionMultiMerger(void) : IBamMultiMerger() { }
58         ~PositionMultiMerger(void) { }
59
60     public:
61         void Add(ReaderAlignment value);
62         void Clear(void);
63         const ReaderAlignment& First(void) const;
64         bool IsEmpty(void) const;
65         void Remove(BamReader* reader);
66         int Size(void) const;
67         ReaderAlignment TakeFirst(void);
68
69     private:
70         typedef std::pair<int, int>           KeyType;
71         typedef ReaderAlignment               ValueType;
72         typedef std::pair<KeyType, ValueType> ElementType;
73
74         typedef std::multimap<KeyType, ValueType> ContainerType;
75         typedef ContainerType::iterator           DataIterator;
76         typedef ContainerType::const_iterator     DataConstIterator;
77
78         ContainerType m_data;
79 };
80
81 // IBamMultiMerger implementation - sorted on BamAlignment: Name
82 class ReadNameMultiMerger : public IBamMultiMerger {
83
84     public:
85         ReadNameMultiMerger(void) : IBamMultiMerger() { }
86         ~ReadNameMultiMerger(void) { }
87
88     public:
89         void Add(ReaderAlignment value);
90         void Clear(void);
91         const ReaderAlignment& First(void) const;
92         bool IsEmpty(void) const;
93         void Remove(BamReader* reader);
94         int Size(void) const;
95         ReaderAlignment TakeFirst(void);
96
97     private:
98         typedef std::string                   KeyType;
99         typedef ReaderAlignment               ValueType;
100         typedef std::pair<KeyType, ValueType> ElementType;
101
102         typedef std::multimap<KeyType, ValueType> ContainerType;
103         typedef ContainerType::iterator           DataIterator;
104         typedef ContainerType::const_iterator     DataConstIterator;
105
106         ContainerType m_data;
107 };
108
109 // IBamMultiMerger implementation - unsorted BAM file(s)
110 class UnsortedMultiMerger : public IBamMultiMerger {
111
112     public:
113         UnsortedMultiMerger(void) : IBamMultiMerger() { }
114         ~UnsortedMultiMerger(void) { }
115
116     public:
117         void Add(ReaderAlignment value);
118         void Clear(void);
119         const ReaderAlignment& First(void) const;
120         bool IsEmpty(void) const;
121         void Remove(BamReader* reader);
122         int Size(void) const;
123         ReaderAlignment TakeFirst(void);
124
125     private:
126         typedef ReaderAlignment ElementType;
127         typedef std::vector<ReaderAlignment>  ContainerType;
128         typedef ContainerType::iterator       DataIterator;
129         typedef ContainerType::const_iterator DataConstIterator;
130
131         ContainerType m_data;
132 };
133
134 // ------------------------------------------
135 // PositionMultiMerger implementation
136
137 inline void PositionMultiMerger::Add(ReaderAlignment value) {
138     const KeyType key( value.second->RefID, value.second->Position );
139     m_data.insert( ElementType(key, value) );
140 }
141
142 inline void PositionMultiMerger::Clear(void) {
143     m_data.clear();
144 }
145
146 inline const ReaderAlignment& PositionMultiMerger::First(void) const {
147     const ElementType& entry = (*m_data.begin());
148     return entry.second;
149 }
150
151 inline bool PositionMultiMerger::IsEmpty(void) const {
152     return m_data.empty();
153 }
154
155 inline void PositionMultiMerger::Remove(BamReader* reader) {
156
157     if ( reader == 0 ) return;
158     const std::string filenameToRemove = reader->GetFilename();
159
160     // iterate over readers in cache
161     DataIterator dataIter = m_data.begin();
162     DataIterator dataEnd  = m_data.end();
163     for ( ; dataIter != dataEnd; ++dataIter ) {
164         const ValueType& entry = (*dataIter).second;
165         const BamReader* entryReader = entry.first;
166         if ( entryReader == 0 ) continue;
167
168         // remove iterator on match
169         if ( entryReader->GetFilename() == filenameToRemove ) {
170             m_data.erase(dataIter);
171             return;
172         }
173     }
174 }
175
176 inline int PositionMultiMerger::Size(void) const {
177     return m_data.size();
178 }
179
180 inline ReaderAlignment PositionMultiMerger::TakeFirst(void) {
181     DataIterator first = m_data.begin();
182     ReaderAlignment next = (*first).second;
183     m_data.erase(first);
184     return next;
185 }
186
187 // ------------------------------------------
188 // ReadNameMultiMerger implementation
189
190 inline void ReadNameMultiMerger::Add(ReaderAlignment value) {
191     BamAlignment* al = value.second;
192     if ( al->BuildCharData() ) {
193         const KeyType key(al->Name);
194         m_data.insert( ElementType(key, value) );
195     }
196 }
197
198 inline void ReadNameMultiMerger::Clear(void) {
199     m_data.clear();
200 }
201
202 inline const ReaderAlignment& ReadNameMultiMerger::First(void) const {
203     const ElementType& entry = (*m_data.begin());
204     return entry.second;
205 }
206
207 inline bool ReadNameMultiMerger::IsEmpty(void) const {
208     return m_data.empty();
209 }
210
211 inline void ReadNameMultiMerger::Remove(BamReader* reader) {
212
213     if ( reader == 0 ) return;
214     const std::string filenameToRemove = reader->GetFilename();
215
216     // iterate over readers in cache
217     DataIterator dataIter = m_data.begin();
218     DataIterator dataEnd  = m_data.end();
219     for ( ; dataIter != dataEnd; ++dataIter ) {
220         const ValueType& entry = (*dataIter).second;
221         const BamReader* entryReader = entry.first;
222         if ( entryReader == 0 ) continue;
223
224         // remove iterator on match
225         if ( entryReader->GetFilename() == filenameToRemove ) {
226             m_data.erase(dataIter);
227             return;
228         }
229     }
230
231 }
232
233 inline int ReadNameMultiMerger::Size(void) const {
234     return m_data.size();
235 }
236
237 inline ReaderAlignment ReadNameMultiMerger::TakeFirst(void) {
238     DataIterator first = m_data.begin();
239     ReaderAlignment next = (*first).second;
240     m_data.erase(first);
241     return next;
242 }
243
244 // ------------------------------------------
245 // UnsortedMultiMerger implementation
246
247 inline void UnsortedMultiMerger::Add(ReaderAlignment value) {
248     m_data.push_back(value);
249 }
250
251 inline void UnsortedMultiMerger::Clear(void) {
252     for (size_t i = 0; i < m_data.size(); ++i )
253         m_data.pop_back();
254 }
255
256 inline const ReaderAlignment& UnsortedMultiMerger::First(void) const {
257     return m_data.front();
258 }
259
260 inline bool UnsortedMultiMerger::IsEmpty(void) const {
261     return m_data.empty();
262 }
263
264 inline void UnsortedMultiMerger::Remove(BamReader* reader) {
265
266     if ( reader == 0 ) return;
267     const std::string filenameToRemove = reader->GetFilename();
268
269     // iterate over readers in cache
270     DataIterator dataIter = m_data.begin();
271     DataIterator dataEnd  = m_data.end();
272     for ( ; dataIter != dataEnd; ++dataIter ) {
273         const BamReader* entryReader = (*dataIter).first;
274         if ( entryReader == 0 ) continue;
275
276         // remove iterator on match
277         if ( entryReader->GetFilename() == filenameToRemove ) {
278             m_data.erase(dataIter);
279             return;
280         }
281     }
282 }
283
284 inline int UnsortedMultiMerger::Size(void) const {
285     return m_data.size();
286 }
287
288 inline ReaderAlignment UnsortedMultiMerger::TakeFirst(void) {
289     ReaderAlignment first = m_data.front();
290     m_data.erase( m_data.begin() );
291     return first;
292 }
293
294 } // namespace Internal
295 } // namespace BamTools
296
297 #endif // BAMMULTIMERGER_P_H