1 // ***************************************************************************
2 // BamMultiMerger_p.h (c) 2010 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 10 October 2011 (DB)
6 // ---------------------------------------------------------------------------
7 // Provides merging functionality for BamMultiReader. At this point, supports
8 // sorting results by (refId, position) or by read name.
9 // ***************************************************************************
11 #ifndef BAMMULTIMERGER_P_H
12 #define BAMMULTIMERGER_P_H
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.
24 #include "api/BamAlignment.h"
25 #include "api/BamReader.h"
26 #include "api/algorithms/Sort.h"
39 BamAlignment* Alignment;
42 MergeItem(BamReader* reader = 0,
43 BamAlignment* alignment = 0)
45 , Alignment(alignment)
48 MergeItem(const MergeItem& other)
49 : Reader(other.Reader)
50 , Alignment(other.Alignment)
56 template<typename Compare>
57 struct MergeItemSorter : public std::binary_function<MergeItem, MergeItem, bool> {
60 MergeItemSorter(const Compare& comp = Compare())
64 bool operator()(const MergeItem& lhs, const MergeItem& rhs) {
65 const BamAlignment& l = *lhs.Alignment;
66 const BamAlignment& r = *rhs.Alignment;
74 // pure ABC so we can just work polymorphically with any specific merger implementation
78 IMultiMerger(void) { }
79 virtual ~IMultiMerger(void) { }
81 virtual void Add(MergeItem item) =0;
82 virtual void Clear(void) =0;
83 virtual const MergeItem& First(void) const =0;
84 virtual bool IsEmpty(void) const =0;
85 virtual void Remove(BamReader* reader) =0;
86 virtual int Size(void) const =0;
87 virtual MergeItem TakeFirst(void) =0;
91 template<typename Compare>
92 class MultiMerger : public IMultiMerger {
95 typedef Compare CompareType;
96 typedef MergeItemSorter<CompareType> MergeType;
99 explicit MultiMerger(const Compare& comp = Compare())
101 , m_data( MergeType(comp) )
103 ~MultiMerger(void) { }
106 void Add(MergeItem item);
108 const MergeItem& First(void) const;
109 bool IsEmpty(void) const;
110 void Remove(BamReader* reader);
111 int Size(void) const;
112 MergeItem TakeFirst(void);
115 typedef MergeItem ValueType;
116 typedef std::multiset<ValueType, MergeType> ContainerType;
117 typedef typename ContainerType::iterator DataIterator;
118 typedef typename ContainerType::const_iterator DataConstIterator;
119 ContainerType m_data;
122 template <typename Compare>
123 inline void MultiMerger<Compare>::Add(MergeItem item) {
125 // N.B. - any future custom Compare types must define this method
126 // see algorithms/Sort.h
128 if ( CompareType::UsesCharData() )
129 item.Alignment->BuildCharData();
133 template <typename Compare>
134 inline void MultiMerger<Compare>::Clear(void) {
138 template <typename Compare>
139 inline const MergeItem& MultiMerger<Compare>::First(void) const {
140 const ValueType& entry = (*m_data.begin());
144 template <typename Compare>
145 inline bool MultiMerger<Compare>::IsEmpty(void) const {
146 return m_data.empty();
148 template <typename Compare>
149 inline void MultiMerger<Compare>::Remove(BamReader* reader) {
151 if ( reader == 0 ) return;
152 const std::string& filenameToRemove = reader->GetFilename();
154 // iterate over readers in cache
155 DataIterator dataIter = m_data.begin();
156 DataIterator dataEnd = m_data.end();
157 for ( ; dataIter != dataEnd; ++dataIter ) {
158 const MergeItem& item = (*dataIter);
159 const BamReader* itemReader = item.Reader;
160 if ( itemReader == 0 ) continue;
162 // remove iterator on match
163 if ( itemReader->GetFilename() == filenameToRemove ) {
164 m_data.erase(dataIter);
169 template <typename Compare>
170 inline int MultiMerger<Compare>::Size(void) const {
171 return m_data.size();
174 template <typename Compare>
175 inline MergeItem MultiMerger<Compare>::TakeFirst(void) {
176 DataIterator firstIter = m_data.begin();
177 MergeItem firstItem = (*firstIter);
178 m_data.erase(firstIter);
184 class MultiMerger<Algorithms::Sort::Unsorted> : public IMultiMerger {
187 explicit MultiMerger(const Algorithms::Sort::Unsorted& comp = Algorithms::Sort::Unsorted())
190 ~MultiMerger(void) { }
193 void Add(MergeItem item);
195 const MergeItem& First(void) const;
196 bool IsEmpty(void) const;
197 void Remove(BamReader* reader);
198 int Size(void) const;
199 MergeItem TakeFirst(void);
202 typedef MergeItem ValueType;
203 typedef std::deque<ValueType> ContainerType;
204 typedef ContainerType::iterator DataIterator;
205 typedef ContainerType::const_iterator DataConstIterator;
206 ContainerType m_data;
210 void MultiMerger<Algorithms::Sort::Unsorted>::Add(MergeItem item) {
211 m_data.push_back(item);
215 void MultiMerger<Algorithms::Sort::Unsorted>::Clear(void) {
220 const MergeItem& MultiMerger<Algorithms::Sort::Unsorted>::First(void) const {
221 return m_data.front();
225 bool MultiMerger<Algorithms::Sort::Unsorted>::IsEmpty(void) const {
226 return m_data.empty();
230 void MultiMerger<Algorithms::Sort::Unsorted>::Remove(BamReader* reader) {
232 if ( reader == 0 ) return;
233 const std::string filenameToRemove = reader->GetFilename();
235 // iterate over readers in cache
236 DataIterator dataIter = m_data.begin();
237 DataIterator dataEnd = m_data.end();
238 for ( ; dataIter != dataEnd; ++dataIter ) {
239 const MergeItem& item = (*dataIter);
240 const BamReader* itemReader = item.Reader;
241 if ( itemReader == 0 ) continue;
243 // remove iterator on match
244 if ( itemReader->GetFilename() == filenameToRemove ) {
245 m_data.erase(dataIter);
252 int MultiMerger<Algorithms::Sort::Unsorted>::Size(void) const {
253 return m_data.size();
257 MergeItem MultiMerger<Algorithms::Sort::Unsorted>::TakeFirst(void) {
258 MergeItem firstItem = m_data.front();
263 } // namespace Internal
264 } // namespace BamTools
266 #endif // BAMMULTIMERGER_P_H