NCBI C++ ToolKit
hspstream_unit_test.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: hspstream_unit_test.cpp 73100 2016-06-20 15:45:40Z boratyng $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Tom Madden
27 *
28 * File Description:
29 * Unit test module for checking implementations of the BlastHSPStream API
30 *
31 * ===========================================================================
32 */
33 
34 // force include of C++ toolkit; necessary for Mac OS X build
35 // to prevent duplicate Handle typedef
36 #include <ncbi_pch.hpp>
37 #include <corelib/test_boost.hpp>
38 
41 
42 #include "test_objmgr.hpp"
43 #include "hspstream_test_util.hpp"
44 // For C++ mutex locking
46 
47 using namespace std;
48 using namespace ncbi;
49 using namespace ncbi::objects;
50 using namespace ncbi::blast;
51 
52 BOOST_AUTO_TEST_SUITE(hspstream)
53 
54 typedef enum EHSPStreamType {
58 
59 void testHSPStream(EHSPStreamType stream_type) {
60  const int kNumQueries = 10;
61  const int kNumThreads = 40;
62  int num_hsp_lists = 1000;
63  BlastHSPList* hsp_list = NULL;
64  int num_reads=0, num_hsps=0;
65  int status, write_status=0;
66  int index;
67 
68  const EBlastProgramType kProgram = eBlastTypeBlastp;
69  const bool kIsGapped = true;
70 
71  BlastExtensionOptions* ext_options = NULL;
72  BlastExtensionOptionsNew(kProgram, &ext_options, kIsGapped);
73  BlastHitSavingOptions* hit_options = NULL;
74  BlastHitSavingOptionsNew(kProgram, &hit_options, kIsGapped);
75 
76  MT_LOCK lock = Blast_CMT_LOCKInit();
77 
78  BlastScoringOptions* scoring_options = NULL;
79  BlastScoringOptionsNew(kProgram, &scoring_options);
80 
82  hit_options, ext_options->compositionBasedStats,
83  scoring_options->gapped_calculation);
84 
85  BlastHSPWriterInfo * writer_info = BlastHSPCollectorInfoNew(col_params);
86 
87  BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL, NULL);
88  BOOST_REQUIRE(writer_info == NULL);
89 
90  BlastHSPStream* hsp_stream = BlastHSPStreamNew(kProgram, ext_options, TRUE,
91  kNumQueries, writer);
92 
93  BlastHSPStreamRegisterMTLock(hsp_stream, lock);
94 
95  scoring_options = BlastScoringOptionsFree(scoring_options);
96  BOOST_REQUIRE(scoring_options == NULL);
97  ext_options = BlastExtensionOptionsFree(ext_options);
98  BOOST_REQUIRE(ext_options == NULL);
99  /* One written HSP list will be split into one per query. */
100  num_reads = kNumQueries;
101  num_hsps = 1;
102  write_status = kBlastHSPStream_Error;
103 
104  // Writing a NULL does not cause error.
105  status = BlastHSPStreamWrite(hsp_stream, &hsp_list);
106  BOOST_REQUIRE_EQUAL(kBlastHSPStream_Success, status);
107 
108  // Writing an empty HSP list does causes neither error, nor a memory
109  // leak, but nothing gets written to the stream.
110  hsp_list = Blast_HSPListNew(0);
111  status = BlastHSPStreamWrite(hsp_stream, &hsp_list);
112  BOOST_REQUIRE_EQUAL(kBlastHSPStream_Success, status);
113 
114  vector<CRef<CHspStreamWriteThread> > write_thread_v;
115  write_thread_v.reserve(kNumThreads);
116 
117  // Create threads to write HSP lists to stream
118  for (index = 0; index < kNumThreads; ++index) {
119  CRef<CHspStreamWriteThread> write_thread(
120  new CHspStreamWriteThread(hsp_stream, index, kNumThreads,
121  num_hsp_lists, kNumQueries));
122  write_thread_v.push_back(write_thread);
123  write_thread->Run();
124  }
125 
126  for (index = 0; index < kNumThreads; ++index) {
127  write_thread_v[index]->Join();
128  }
129  num_hsp_lists = MIN(num_hsp_lists, col_params->prelim_hitlist_size);
130 
131  // For the collector-type stream, HSP lists should
132  // be read out of the HSPStream in order of increasing
133  // subject OID
134  Int4 last_oid = -1;
135 
136  for (index = 0; index < num_hsp_lists*num_reads; ++index) {
137  status = BlastHSPStreamRead(hsp_stream, &hsp_list);
138  BOOST_REQUIRE_EQUAL(kBlastHSPStream_Success, status);
139  BOOST_REQUIRE(hsp_list->oid >= last_oid);
140  last_oid = hsp_list->oid;
141  BOOST_REQUIRE_EQUAL(num_hsps, hsp_list->hspcnt);
142  hsp_list = Blast_HSPListFree(hsp_list);
143  BOOST_REQUIRE(hsp_list == NULL);
144  }
145 
146  /* Check whether we can write more results. */
147  hsp_list = setupHSPList(0, 1, 0);
148  status = BlastHSPStreamWrite(hsp_stream, &hsp_list);
149  BOOST_REQUIRE_EQUAL(write_status, status);
150  /* For the case of the queue, read the just written HSP list */
151  if (status == kBlastHSPStream_Success) {
152  status = BlastHSPStreamRead(hsp_stream, &hsp_list);
153  }
154  hsp_list = Blast_HSPListFree(hsp_list);
155  BOOST_REQUIRE(hsp_list == NULL);
156 
157  /* Close the stream for writing. Do it here, to imitate the situation
158  when reading starts before the stream is explicitly closed for
159  writing. In the collector case, the first Read() call closes the
160  stream anyway, but repeated call to Close() does not hurt.*/
161  BlastHSPStreamClose(hsp_stream);
162 
163  /* Now the HSPList collector should be empty */
164  status = BlastHSPStreamRead(hsp_stream, &hsp_list);
165  BOOST_REQUIRE_EQUAL(kBlastHSPStream_Eof, status);
166  BOOST_REQUIRE(hsp_list == NULL);
167  hsp_stream = BlastHSPStreamFree(hsp_stream);
168  BOOST_REQUIRE(hsp_stream == NULL);
169  hit_options = BlastHitSavingOptionsFree(hit_options);
170  BOOST_REQUIRE(hit_options == NULL);
171 }
172 
173 BOOST_AUTO_TEST_CASE(testCollectorHSPStream) {
175 }
176 
177 BOOST_AUTO_TEST_CASE(testQueueHSPStream) {
179 }
180 
181 BOOST_AUTO_TEST_CASE(testMultiSeqHSPCollector) {
182  const int kNumSubjects = 10;
183  const EBlastProgramType kProgram = eBlastTypeBlastp;
184 
185  BlastExtensionOptions* ext_options = NULL;
186  BlastExtensionOptionsNew(kProgram, &ext_options, true);
187 
188  BlastScoringOptions* scoring_options = NULL;
189  BlastScoringOptionsNew(kProgram, &scoring_options);
190 
191  BlastHitSavingOptions* hit_options = NULL;
192  BlastHitSavingOptionsNew(kProgram, &hit_options,
193  scoring_options->gapped_calculation);
194 
197  hit_options, ext_options->compositionBasedStats,
198  scoring_options->gapped_calculation));
199 
200  BlastHSPWriter* writer = BlastHSPWriterNew(&writer_info, NULL, NULL);
201  BOOST_REQUIRE(writer_info == NULL);
202 
203  BlastHSPStream* hsp_stream = BlastHSPStreamNew(
204  kProgram, ext_options, FALSE, 1, writer);
205 
206  scoring_options = BlastScoringOptionsFree(scoring_options);
207  BOOST_REQUIRE(scoring_options == NULL);
208  ext_options = BlastExtensionOptionsFree(ext_options);
209  BOOST_REQUIRE(ext_options == NULL);
210 
211  BlastHSPList* hsp_list = NULL;
212  // Create HSPLists for all odd subjects
213  int index, status;
214  for (index = 1; index < kNumSubjects; index += 2) {
215  hsp_list = setupHSPList(index, 1, index);
216  status = BlastHSPStreamWrite(hsp_stream, &hsp_list);
217  BOOST_REQUIRE_EQUAL(kBlastHSPStream_Success, status);
218  }
219  // Read them back and put in a BlastHSPResults structure
220  BlastHSPResults* results = Blast_HSPResultsNew(1);
221  for (index = 1; index < kNumSubjects; index += 2) {
222  status = BlastHSPStreamRead(hsp_stream, &hsp_list);
223  BOOST_REQUIRE_EQUAL(kBlastHSPStream_Success, status);
224  Blast_HSPResultsInsertHSPList(results, hsp_list, kNumSubjects);
225  /* Check that HSPLists are returned in correct order of
226  ordinal ids. */
227  BOOST_REQUIRE_EQUAL(index, (int)hsp_list->oid);
228  }
229  /* Now the HSPList collector should be empty */
230  status = BlastHSPStreamRead(hsp_stream, &hsp_list);
231  BOOST_REQUIRE_EQUAL(kBlastHSPStream_Eof, status);
232  BOOST_REQUIRE(hsp_list == NULL);
233  hsp_stream = BlastHSPStreamFree(hsp_stream);
234  BOOST_REQUIRE(hsp_stream == NULL);
235  Blast_HSPResultsFree(results);
236  hit_options = BlastHitSavingOptionsFree(hit_options);
237  BOOST_REQUIRE(hit_options == NULL);
238 }
BlastHSPResults * Blast_HSPResultsFree(BlastHSPResults *results)
Deallocate memory for BLAST results.
Definition: blast_hits.c:3358
Int2 Blast_HSPResultsInsertHSPList(BlastHSPResults *results, BlastHSPList *hsp_list, Int4 hitlist_size)
Blast_HSPResultsInsertHSPList Insert an HSP list to the appropriate place in the results structure.
Definition: blast_hits.c:3546
BlastHSPList * Blast_HSPListNew(Int4 hsp_max)
Creates HSP list structure with a default size HSP array.
Definition: blast_hits.c:1558
BlastHSPResults * Blast_HSPResultsNew(Int4 num_queries)
Initialize the results structure.
Definition: blast_hits.c:3338
BlastHSPList * Blast_HSPListFree(BlastHSPList *hsp_list)
Deallocate memory for an HSP list structure as well as all it's components.
Definition: blast_hits.c:1542
BlastHSPWriter * BlastHSPWriterNew(BlastHSPWriterInfo **writer_info, BlastQueryInfo *query_info, BLAST_SequenceBlk *query)
A generic function to create writer.
Declaration of ADT to save and retrieve lists of HSPs in the BLAST engine.
void BlastHSPStreamClose(BlastHSPStream *hsp_stream)
Closes the BlastHSPStream structure for writing.
int BlastHSPStreamWrite(BlastHSPStream *hsp_stream, BlastHSPList **hsp_list)
Invokes the user-specified write function for this BlastHSPStream implementation.
BlastHSPStream * BlastHSPStreamFree(BlastHSPStream *hsp_stream)
Frees the BlastHSPStream structure by invoking the destructor function set by the user-defined constr...
BlastHSPStream * BlastHSPStreamNew(EBlastProgramType program, const BlastExtensionOptions *extn_opts, Boolean sort_on_read, Int4 num_queries, BlastHSPWriter *writer)
Initialize the HSP stream.
const int kBlastHSPStream_Eof
Return value when the end of the stream is reached (applicable to read method only)
int BlastHSPStreamRegisterMTLock(BlastHSPStream *hsp_stream, MT_LOCK lock)
Attach a mutex lock to a stream to protect multiple access during writing.
const int kBlastHSPStream_Success
Standard success return value for BlastHSPStream methods.
int BlastHSPStreamRead(BlastHSPStream *hsp_stream, BlastHSPList **hsp_list)
Invokes the user-specified read function for this BlastHSPStream implementation.
const int kBlastHSPStream_Error
Standard error return value for BlastHSPStream methods.
C++ version of the initialization for the mutex locking interface.
BlastHitSavingOptions * BlastHitSavingOptionsFree(BlastHitSavingOptions *options)
Deallocate memory for BlastHitSavingOptions.
Int2 BlastScoringOptionsNew(EBlastProgramType program, BlastScoringOptions **options)
Allocate memory for BlastScoringOptions and fill with default values.
BlastExtensionOptions * BlastExtensionOptionsFree(BlastExtensionOptions *options)
Deallocate memory for BlastExtensionOptions.
Int2 BlastHitSavingOptionsNew(EBlastProgramType program, BlastHitSavingOptions **options, Boolean gapped_calculation)
Allocate memory for BlastHitSavingOptions.
BlastScoringOptions * BlastScoringOptionsFree(BlastScoringOptions *options)
Deallocate memory for BlastScoringOptions.
Int2 BlastExtensionOptionsNew(EBlastProgramType program, BlastExtensionOptions **options, Boolean gapped)
Allocate memory for BlastExtensionOptions and fill with default values.
EBlastProgramType
Defines the engine's notion of the different applications of the BLAST algorithm.
Definition: blast_program.h:72
@ eBlastTypeBlastp
Definition: blast_program.h:73
void setupHSPList(BlastHSPList **hsp_list_ptr, int chunk)
BOOST_AUTO_TEST_SUITE_END() static int s_GetSegmentFlags(const CBioseq &bioseq)
CRef –.
Definition: ncbiobj.hpp:618
MT_LOCK Blast_CMT_LOCKInit(void)
Initialize a mutex locking mechanism for BLAST.
#define NULL
Definition: ncbistd.hpp:225
int32_t Int4
4-byte (32-bit) signed integer
Definition: ncbitype.h:102
Implementation of a number of BlastHSPWriters to save hits from a BLAST search, and subsequently retu...
BlastHSPCollectorParams * BlastHSPCollectorParamsNew(const BlastHitSavingOptions *hit_options, Int4 compositionBasedStats, Boolean gapped_calculation)
Sets up parameter set for use by collector.
BlastHSPWriterInfo * BlastHSPCollectorInfoNew(BlastHSPCollectorParams *params)
WriterInfo to create a default writer: the collecter.
Auxiliary utilities needed for testing HSP stream interface.
BOOST_AUTO_TEST_CASE(testCollectorHSPStream)
void testHSPStream(EHSPStreamType stream_type)
@ eHSPListCollector
@ eHSPListQueue
Magic spell ;-) needed for some weird compilers... very empiric.
#define MIN(a, b)
returns smaller of a and b.
Definition: ncbi_std.h:112
#define TRUE
bool replacment for C indicating true.
Definition: ncbi_std.h:97
#define FALSE
bool replacment for C indicating false.
Definition: ncbi_std.h:101
BOOST_AUTO_TEST_SUITE(psiblast_iteration)
Options used for gapped extension These include: a.
Int4 compositionBasedStats
mode of compositional adjustment to use; if zero then compositional adjustment is not used
Keeps prelim_hitlist_size and HitSavingOptions together.
Int4 prelim_hitlist_size
number of hits saved during preliminary part of search.
The structure to hold all HSPs for a given sequence after the gapped alignment.
Definition: blast_hits.h:153
Int4 oid
The ordinal id of the subject sequence this HSP list is for.
Definition: blast_hits.h:154
Int4 hspcnt
Number of HSPs saved.
Definition: blast_hits.h:158
The structure to contain all BLAST results, for multiple queries.
Definition: blast_hits.h:183
Default implementation of BlastHSPStream.
A wrap of data structure used to create a writer.
ADT definition of BlastHSPWriter.
Options used when evaluating and saving hits These include: a.
Scoring options block Used to produce the BlastScoreBlk structure This structure may be needed for lo...
Boolean gapped_calculation
gap-free search if FALSE
Utility stuff for more convenient using of Boost.Test library.
Modified on Tue May 21 11:00:22 2024 by modify_doxy.py rev. 669887