~ubuntu-branches/ubuntu/saucy/ncbi-tools6/saucy-proposed

« back to all changes in this revision

Viewing changes to algo/blast/api/hspfilter_queue.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2009-08-11 22:03:47 UTC
  • mfrom: (1.4.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20090811220347-g4b6lzdvphvvbpiu
* New upstream release.
* debian/libncbi6.symbols: update accordingly.
* debian/control: clean up obsolete or redundant relationship declarations.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  $Id: hspfilter_queue.c,v 1.1 2009/06/01 13:54:56 maning Exp $
 
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:  Ning Ma
 
27
 *
 
28
 */
 
29
 
 
30
/** @file hspfilter_queue.c
 
31
 * Default implementation of the BlastHSPWriter interface to save hits from
 
32
 * a BLAST search, and subsequently return them in sorted order.
 
33
 */
 
34
 
 
35
#ifndef SKIP_DOXYGEN_PROCESSING
 
36
static char const rcsid[] = 
 
37
    "$Id: hspfilter_queue.c,v 1.1 2009/06/01 13:54:56 maning Exp $";
 
38
#endif /* SKIP_DOXYGEN_PROCESSING */
 
39
 
 
40
 
 
41
#include <ncbithr.h>
 
42
#include <algo/blast/core/blast_hspstream.h>
 
43
#include <algo/blast/api/hspfilter_queue.h>
 
44
//#include <algo/blast/core/blast_util.h>
 
45
 
 
46
/** Data structure used by the writer */
 
47
typedef struct BlastHSPQueueData {
 
48
   ListNode * start;      /**< First element of the queue */
 
49
   ListNode * end;        /**< First element of the queue */
 
50
   Boolean    writeDone;  /**< Has writing to this stream been finished? */
 
51
   TNlmMutex  lock;       /**< reading/writing lock */
 
52
   TNlmSemaphore sema;    /**< Semaphore for reading */
 
53
} BlastHSPQueueData;
 
54
 
 
55
/*************************************************************/
 
56
/** The following are implementations for BlastHSPWriter ADT */
 
57
 
 
58
/** Perform pre-run stage-specific initialization 
 
59
 * @param data The internal data structure [in][out]
 
60
 * @param results The HSP results to operate on  [in]
 
61
 */ 
 
62
static int 
 
63
s_BlastHSPQueueInit(void* data, BlastHSPResults* results)
 
64
{
 
65
   BlastHSPQueueData * q_data = data;
 
66
   return 0;
 
67
}
 
68
 
 
69
/** Perform post-run clean-ups
 
70
 * @param data The buffered data structure [in]
 
71
 * @param results The HSP results to propagate [in][out]
 
72
 */ 
 
73
static int 
 
74
s_BlastHSPQueueFinal(void* data, BlastHSPResults* results)
 
75
{
 
76
   BlastHSPQueueData * q_data = data;
 
77
 
 
78
   NlmMutexLockEx(&q_data->lock);
 
79
   q_data->writeDone = TRUE;
 
80
   NlmSemaPost(q_data->sema);
 
81
   NlmMutexUnlock(q_data->lock);
 
82
 
 
83
   return 0;
 
84
}
 
85
 
 
86
/** Perform writing task
 
87
 * ownership of the HSP list and sets the dereferenced pointer to NULL.
 
88
 * @param data To store results to [in][out]
 
89
 * @param hsp_list Pointer to the HSP list to save in the queue. [in]
 
90
 */
 
91
static int 
 
92
s_BlastHSPQueueRun(void* data, BlastHSPList* hsp_list)
 
93
{
 
94
   BlastHSPQueueData * q_data = data;
 
95
 
 
96
   if (!hsp_list)
 
97
      return 0;
 
98
 
 
99
   if (hsp_list->hspcnt == 0) {
 
100
      Blast_HSPListFree(hsp_list);
 
101
      return 0;
 
102
   }
 
103
 
 
104
   if (q_data->writeDone)
 
105
      return -1;
 
106
 
 
107
   NlmMutexLockEx(&q_data->lock);
 
108
   q_data->end = ListNodeAddPointer(&q_data->end, 0, (void *)hsp_list);
 
109
   if (!q_data->start)
 
110
      q_data->start = q_data->end;
 
111
   hsp_list = NULL;
 
112
   NlmSemaPost(q_data->sema);
 
113
   NlmMutexUnlock(q_data->lock);
 
114
 
 
115
   return 0; 
 
116
}
 
117
 
 
118
/** Free the writer 
 
119
 * @param writer The writer to free [in]
 
120
 * @return NULL.
 
121
 */
 
122
static
 
123
BlastHSPWriter*
 
124
s_BlastHSPQueueFree(BlastHSPWriter* writer) 
 
125
{
 
126
   ListNode * p;
 
127
   BlastHSPQueueData *q_data = writer->data;
 
128
 
 
129
   NlmSemaDestroy(q_data->sema);
 
130
   NlmMutexDestroy(q_data->lock);
 
131
 
 
132
   for(p = q_data->start; p; p = p->next) {
 
133
      p->ptr = (void *) Blast_HSPListFree((BlastHSPList*) p->ptr);
 
134
   }
 
135
   q_data->start = ListNodeFree(q_data->start);
 
136
   sfree(writer->data);
 
137
   sfree(writer);
 
138
   return NULL;
 
139
}
 
140
 
 
141
/** create the writer
 
142
 * @param params Pointer to the hit paramters [in]
 
143
 * @param query_info BlastQueryInfo (not used) [in]
 
144
 * @return writer
 
145
 */
 
146
static
 
147
BlastHSPWriter* 
 
148
s_BlastHSPQueueNew(void* params, BlastQueryInfo* query_info)
 
149
{
 
150
   BlastHSPWriter * writer = NULL;
 
151
   BlastHSPQueueData * data = NULL;
 
152
 
 
153
   /* allocate space for writer */
 
154
   writer = malloc(sizeof(BlastHSPWriter));
 
155
 
 
156
   /* fill up the function pointers */
 
157
   writer->InitFnPtr   = &s_BlastHSPQueueInit;
 
158
   writer->FinalFnPtr  = &s_BlastHSPQueueFinal;
 
159
   writer->FreeFnPtr   = &s_BlastHSPQueueFree;
 
160
   writer->RunFnPtr    = &s_BlastHSPQueueRun;
 
161
 
 
162
   /* allocate for data structure */
 
163
   writer->data = calloc(1,sizeof(BlastHSPQueueData));
 
164
   data = writer->data;
 
165
   data->sema = NlmSemaInit(0);
 
166
    
 
167
   return writer;
 
168
}
 
169
 
 
170
/*************************************************************/
 
171
/** The following are exported functions to be used by APP   */
 
172
 
 
173
BlastHSPQueueParams*
 
174
BlastHSPQueueParamsNew()
 
175
{
 
176
    return NULL;
 
177
}
 
178
 
 
179
BlastHSPQueueParams*
 
180
BlastHSPQueueParamsFree(BlastHSPQueueParams* opts)
 
181
{
 
182
    return NULL;
 
183
}
 
184
 
 
185
BlastHSPWriterInfo*
 
186
BlastHSPQueueInfoNew(BlastHSPQueueParams* params) {
 
187
   BlastHSPWriterInfo * writer_info =
 
188
                        malloc(sizeof(BlastHSPWriterInfo)); 
 
189
   writer_info->NewFnPtr = &s_BlastHSPQueueNew;
 
190
   writer_info->params = params;
 
191
   return writer_info;
 
192
}
 
193
 
 
194
/************************************************************/
 
195
/** The follwoing is added to support queue implementation  */
 
196
 
 
197
int BlastHSPQueueRead(void* data, BlastHSPList** hsp_list_out) 
 
198
{
 
199
   BlastHSPQueueData* q_data = (BlastHSPQueueData*) data;
 
200
   int status = kBlastHSPStream_Error;
 
201
 
 
202
   /* Lock the mutex */
 
203
   NlmMutexLockEx(&q_data->lock);
 
204
 
 
205
   if (!q_data->writeDone) {
 
206
      while (!q_data->writeDone && !q_data->start) {
 
207
         /* Decrement the semaphore count to 0, then wait for it to be 
 
208
          * incremented. Note that mutex must be locked whenever the 
 
209
          * contents of the stream are checked, but it must be unlocked
 
210
          * for the semaphore wait. */
 
211
         NlmMutexUnlock(q_data->lock);
 
212
         NlmSemaWait(q_data->sema);
 
213
         NlmMutexLockEx(&q_data->lock);
 
214
      }
 
215
   }
 
216
 
 
217
   if (!q_data->start) {
 
218
      /* Nothing in the queue, but no more writing to the queue is expected. */
 
219
      *hsp_list_out = NULL;
 
220
      status =  kBlastHSPStream_Eof;
 
221
   } else {
 
222
      ListNode* start_node = q_data->start;
 
223
 
 
224
      *hsp_list_out = (BlastHSPList*) start_node->ptr;
 
225
 
 
226
      q_data->start = start_node->next;
 
227
      start_node->next = NULL;
 
228
      ListNodeFree(start_node);
 
229
      if (!q_data->start)
 
230
         q_data->end = NULL;
 
231
      status = kBlastHSPStream_Success;
 
232
   }
 
233
 
 
234
   NlmMutexUnlock(q_data->lock);
 
235
 
 
236
   return status;
 
237
}
 
238