1 // ***************************************************************************
2 // BamMultiMerger_p.h (c) 2010 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
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) {
124 if ( CompareType::UsesCharData() )
125 item.Alignment->BuildCharData();
129 template <typename Compare>
130 inline void MultiMerger<Compare>::Clear(void) {
134 template <typename Compare>
135 inline const MergeItem& MultiMerger<Compare>::First(void) const {
136 const ValueType& entry = (*m_data.begin());
140 template <typename Compare>
141 inline bool MultiMerger<Compare>::IsEmpty(void) const {
142 return m_data.empty();
144 template <typename Compare>
145 inline void MultiMerger<Compare>::Remove(BamReader* reader) {
147 if ( reader == 0 ) return;
148 const std::string& filenameToRemove = reader->GetFilename();
150 // iterate over readers in cache
151 DataIterator dataIter = m_data.begin();
152 DataIterator dataEnd = m_data.end();
153 for ( ; dataIter != dataEnd; ++dataIter ) {
154 const MergeItem& item = (*dataIter);
155 const BamReader* itemReader = item.Reader;
156 if ( itemReader == 0 ) continue;
158 // remove iterator on match
159 if ( itemReader->GetFilename() == filenameToRemove ) {
160 m_data.erase(dataIter);
165 template <typename Compare>
166 inline int MultiMerger<Compare>::Size(void) const {
167 return m_data.size();
170 template <typename Compare>
171 inline MergeItem MultiMerger<Compare>::TakeFirst(void) {
172 DataIterator firstIter = m_data.begin();
173 MergeItem firstItem = (*firstIter);
174 m_data.erase(firstIter);
180 class MultiMerger<Algorithms::Sort::Unsorted> : public IMultiMerger {
183 explicit MultiMerger(const Algorithms::Sort::Unsorted& comp = Algorithms::Sort::Unsorted())
186 ~MultiMerger(void) { }
189 void Add(MergeItem item);
191 const MergeItem& First(void) const;
192 bool IsEmpty(void) const;
193 void Remove(BamReader* reader);
194 int Size(void) const;
195 MergeItem TakeFirst(void);
198 typedef MergeItem ValueType;
199 typedef std::deque<ValueType> ContainerType;
200 typedef ContainerType::iterator DataIterator;
201 typedef ContainerType::const_iterator DataConstIterator;
202 ContainerType m_data;
206 void MultiMerger<Algorithms::Sort::Unsorted>::Add(MergeItem item) {
207 m_data.push_back(item);
211 void MultiMerger<Algorithms::Sort::Unsorted>::Clear(void) {
216 const MergeItem& MultiMerger<Algorithms::Sort::Unsorted>::First(void) const {
217 return m_data.front();
221 bool MultiMerger<Algorithms::Sort::Unsorted>::IsEmpty(void) const {
222 return m_data.empty();
226 void MultiMerger<Algorithms::Sort::Unsorted>::Remove(BamReader* reader) {
228 if ( reader == 0 ) return;
229 const std::string filenameToRemove = reader->GetFilename();
231 // iterate over readers in cache
232 DataIterator dataIter = m_data.begin();
233 DataIterator dataEnd = m_data.end();
234 for ( ; dataIter != dataEnd; ++dataIter ) {
235 const MergeItem& item = (*dataIter);
236 const BamReader* itemReader = item.Reader;
237 if ( itemReader == 0 ) continue;
239 // remove iterator on match
240 if ( itemReader->GetFilename() == filenameToRemove ) {
241 m_data.erase(dataIter);
248 int MultiMerger<Algorithms::Sort::Unsorted>::Size(void) const {
249 return m_data.size();
253 MergeItem MultiMerger<Algorithms::Sort::Unsorted>::TakeFirst(void) {
254 MergeItem firstItem = m_data.front();
259 } // namespace Internal
260 } // namespace BamTools
262 #endif // BAMMULTIMERGER_P_H