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