NCBI C Toolkit Cross Reference

C/algo/blast/api/hspfilter_queue.c


  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 
239 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.