1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26
27 #include <sra/extern.h>
28
29 #include <klib/namelist.h>
30 #include <klib/refcount.h>
31 #include <klib/log.h>
32 #include <klib/rc.h>
33 #include <kfs/directory.h>
34 #include <kfg/config.h>
35 #include <vfs/manager.h>
36 #include <vfs/resolver.h>
37 #include <vfs/path.h>
38 #include <kdb/manager.h>
39 #include <kdb/kdb-priv.h>
40 #include <vdb/manager.h>
41 #include <vdb/schema.h>
42 #include <vdb/vdb-priv.h>
43 #include <sra/sradb.h>
44 #include <sra/sraschema.h>
45 #include <sra/srapath.h>
46 #include <sra/sradb-priv.h>
47 #include <sysalloc.h>
48 #include <atomic.h>
49
50 #include "sra-priv.h"
51
52 #include <stdlib.h>
53 #include <stdarg.h>
54 #include <string.h>
55 #include <assert.h>
56
57
58 /* Whack
59 * will not refuse request, and ignores errors
60 */
61 static
SRAMgrWhack(const SRAMgr * that)62 rc_t SRAMgrWhack ( const SRAMgr *that )
63 {
64 SRAMgr *self = ( SRAMgr* ) that;
65
66 VSchemaRelease ( self -> schema );
67 VDBManagerRelease ( self -> vmgr );
68 SRACacheWhack ( self -> cache );
69
70 /* must check here for NULL because
71 SRAPathRelease is weak-linked */
72 if ( self -> _pmgr != NULL )
73 {
74 #if OLD_SRAPATH_MGR
75 SRAPathRelease ( self -> _pmgr );
76 #else
77 VResolverRelease ( ( const VResolver* ) self -> _pmgr );
78 #endif
79 }
80
81 free ( self );
82 return 0;
83 }
84
85
86 /* Release
87 * releases reference to object
88 * obtained from MakeRead, MakeUpdate,
89 * or AddRef(see above)
90 */
SRAMgrRelease(const SRAMgr * self)91 LIB_EXPORT rc_t CC SRAMgrRelease ( const SRAMgr *self )
92 {
93 if ( self != NULL )
94 {
95 switch ( KRefcountDrop ( & self -> refcount, "SRAMgr" ) )
96 {
97 case krefWhack:
98 return SRAMgrWhack ( ( SRAMgr* ) self );
99 case krefNegative:
100 return RC ( rcSRA, rcMgr, rcReleasing, rcRange, rcExcessive );
101 }
102 }
103 return 0;
104 }
105
106
107 /* AddRef
108 * attach a new reference to an existing object
109 * ( see above)
110 */
SRAMgrAddRef(const SRAMgr * self)111 LIB_EXPORT rc_t CC SRAMgrAddRef ( const SRAMgr *self )
112 {
113 if ( self != NULL )
114 {
115 switch ( KRefcountAdd ( & self -> refcount, "SRAMgr" ) )
116 {
117 case krefLimit:
118 return RC ( rcSRA, rcMgr, rcAttaching, rcRange, rcExcessive );
119 }
120 }
121 return 0;
122 }
123
124 /* Attach
125 * Sever
126 */
SRAMgrAttach(const SRAMgr * self)127 SRAMgr *SRAMgrAttach ( const SRAMgr *self )
128 {
129 if ( self != NULL )
130 {
131 switch ( KRefcountAddDep ( & self -> refcount, "SRAMgr" ) )
132 {
133 case krefLimit:
134 return NULL;
135 }
136 }
137 return ( SRAMgr* ) self;
138 }
139
SRAMgrSever(const SRAMgr * self)140 rc_t SRAMgrSever ( const SRAMgr *self )
141 {
142 if ( self != NULL )
143 {
144 switch ( KRefcountDropDep ( & self -> refcount, "SRAMgr" ) )
145 {
146 case krefWhack:
147 return SRAMgrWhack ( ( SRAMgr* ) self );
148 case krefNegative:
149 return RC ( rcSRA, rcMgr, rcReleasing, rcRange, rcExcessive );
150 }
151 }
152 return 0;
153 }
154
155
156 /* Make
157 */
158 static
SRAMgrInitPath(SRAMgr * mgr,KConfig * kfg,const KDirectory * wd)159 rc_t SRAMgrInitPath ( SRAMgr *mgr, KConfig *kfg, const KDirectory *wd )
160 {
161 VFSManager *vfs;
162 rc_t rc = VFSManagerMake ( & vfs );
163 if ( rc == 0 )
164 {
165 rc = VFSManagerMakeResolver ( vfs, ( VResolver** ) & mgr -> _pmgr, kfg );
166 VFSManagerRelease ( vfs );
167 }
168
169 if ( rc != 0 )
170 mgr -> _pmgr = NULL;
171
172 return 0;
173 }
174
SRAMgrMake(SRAMgr ** mgrp,const VDBManager * vmgr,const KDirectory * wd)175 rc_t SRAMgrMake ( SRAMgr **mgrp,
176 const VDBManager *vmgr, const KDirectory *wd )
177 {
178 rc_t rc;
179
180 /* require sraschema object */
181 SRAMgr *mgr = malloc ( sizeof * mgr );
182 if ( mgr == NULL )
183 rc = RC ( rcSRA, rcMgr, rcConstructing, rcMemory, rcExhausted );
184 else
185 {
186 VSchema *schema;
187 rc = VDBManagerMakeSRASchema ( vmgr, & schema );
188 if ( rc == 0 )
189 {
190 KConfig* kfg;
191 rc = KConfigMake ( & kfg, wd );
192 if ( rc == 0 )
193 {
194 rc = SRAMgrInitPath ( mgr, kfg, wd );
195 if ( rc == 0 )
196 {
197 rc = SRACacheInit ( & mgr -> cache, kfg );
198 if ( rc == 0 )
199 {
200 KRefcountInit ( & mgr -> refcount, 1, "SRAMgr", "SRAMgrMake", "sramgr" );
201 mgr -> vmgr = vmgr;
202 mgr -> schema = schema;
203 mgr -> mode = kcmCreate; /* TBD - should this include parents? */
204 mgr -> read_only = true;
205 * mgrp = mgr;
206 KConfigRelease ( kfg );
207 return 0;
208 }
209 }
210 KConfigRelease ( kfg );
211 }
212
213 VSchemaRelease ( schema );
214 }
215
216 free ( mgr );
217 }
218
219 * mgrp = NULL;
220 return rc;
221 }
222
223
224 /* Writable
225 * returns 0 if table is writable
226 * rcLocked if locked, rcReadonly if read-only
227 * other code upon error
228 *
229 * "path" [ IN ] - NUL terminated table path
230 */
SRAMgrVWritable(const SRAMgr * self,const char * path,va_list args)231 LIB_EXPORT rc_t CC SRAMgrVWritable ( const SRAMgr *self,
232 const char *path, va_list args )
233 {
234 if ( self == NULL )
235 return RC ( rcSRA, rcMgr, rcAccessing, rcSelf, rcNull );
236 return VDBManagerVWritable ( self -> vmgr, path, args );
237 }
238
SRAMgrWritable(const SRAMgr * self,const char * path,...)239 LIB_EXPORT rc_t CC SRAMgrWritable ( const SRAMgr *self,
240 const char *path, ... )
241 {
242 rc_t rc;
243
244 va_list args;
245 va_start ( args, path );
246
247 rc = SRAMgrVWritable ( self, path, args );
248
249 va_end ( args );
250
251 return rc;
252 }
253
SRAMgrResolve(const SRAMgr * self,const char * acc,char * buf,size_t buf_size)254 LIB_EXPORT rc_t CC SRAMgrResolve( const SRAMgr *self, const char* acc, char* buf, size_t buf_size )
255 {
256 if ( self == NULL )
257 return RC ( rcSRA, rcMgr, rcResolving, rcSelf, rcNull );
258 if ( acc == NULL || buf == NULL)
259 return RC ( rcSRA, rcMgr, rcResolving, rcParam, rcNull );
260 else
261 {
262 VFSManager *vfs;
263 rc_t rc = VFSManagerMake ( & vfs );
264 if (rc == 0)
265 {
266 rc_t rc2;
267 VPath* path;
268 rc = VFSManagerMakePath(vfs, &path, "ncbi-acc:%s", acc);
269 if (rc == 0)
270 {
271 const VPath* resolved;
272 rc = VResolverQuery ( (const struct VResolver*)self->_pmgr, 0, path, &resolved, NULL, NULL );
273 if (rc == 0)
274 {
275 rc = VPathReadPath ( resolved, buf, buf_size, NULL );
276 rc2 = VPathRelease(resolved);
277 if (rc == 0)
278 rc = rc2;
279 }
280
281 rc2 = VPathRelease(path);
282 if (rc == 0)
283 rc = rc2;
284 }
285 rc2 = VFSManagerRelease(vfs);
286 if (rc == 0)
287 rc = rc2;
288 }
289
290 return rc;
291 }
292 }
293
SRAMgrConfigReload(const SRAMgr * cself,const KDirectory * wd)294 LIB_EXPORT rc_t CC SRAMgrConfigReload( const SRAMgr *cself, const KDirectory *wd )
295 {
296 #if OLD_SRAPATH_MGR
297 SRAMgr *self = cself;
298
299 /* create a new SRAPath object */
300 SRAPath *pnew;
301 rc_t rc = SRAPathMake ( & pnew, wd );
302 if ( rc == 0 )
303 {
304 /* swap with the old guy */
305 SRAPath *pold = self -> _pmgr;
306 if ( atomic_test_and_set_ptr ( ( void *volatile* ) & self -> _pmgr, pnew, pold ) == ( void* ) pold )
307 SRAPathRelease ( pold );
308 else
309 SRAPathRelease ( pnew );
310 }
311
312 return rc;
313 #else
314 return 0;
315 #endif
316
317 #if 0
318
319
320 /* do not reload VDBManager config for now
321 it cannot reload properly and grows in memory */
322 rc_t rc = 0;
323 /* (not thread) safely re-instanciate sra path config */
324 SRAMgr *self = (SRAMgr*)cself;
325 SRAPath* p = cself->_pmgr;
326 self->_pmgr = NULL;
327 if( (rc = SRAMgrInitPath(self, wd)) == 0 ) {
328 SRAPathRelease(p);
329 } else {
330 /* roll back */
331 self->_pmgr = p;
332 }
333 return rc;
334 #endif
335
336 }
337
338 /* GetVDBManager
339 * returns a new reference to VDBManager used by SRAMgr
340 */
SRAMgrGetVDBManagerRead(const SRAMgr * self,const VDBManager ** vmgr)341 LIB_EXPORT rc_t CC SRAMgrGetVDBManagerRead ( const SRAMgr *self, const VDBManager **vmgr )
342 {
343 rc_t rc;
344
345 if ( vmgr == NULL )
346 rc = RC ( rcSRA, rcMgr, rcAccessing, rcParam, rcNull );
347 else
348 {
349 if ( self == NULL )
350 rc = RC ( rcSRA, rcMgr, rcAccessing, rcSelf, rcNull );
351 else
352 {
353 * vmgr = self -> vmgr;
354 return VDBManagerAddRef ( * vmgr );
355 }
356
357 * vmgr = NULL;
358 }
359
360 return rc;
361 }
362
363 /* GetKDBManager
364 * returns a new reference to KDBManager used indirectly by SRAMgr
365 */
SRAMgrGetKDBManagerRead(const SRAMgr * self,struct KDBManager const ** kmgr)366 LIB_EXPORT rc_t CC SRAMgrGetKDBManagerRead ( const SRAMgr *self,
367 struct KDBManager const **kmgr )
368 {
369 rc_t rc;
370
371 if ( kmgr == NULL )
372 rc = RC ( rcSRA, rcMgr, rcAccessing, rcParam, rcNull );
373 else
374 {
375 if ( self == NULL )
376 rc = RC ( rcSRA, rcMgr, rcAccessing, rcSelf, rcNull );
377 else
378 {
379 return VDBManagerGetKDBManagerRead ( self -> vmgr, kmgr );
380 }
381
382 * kmgr = NULL;
383 }
384
385 return rc;
386 }
387
388
389 /* ModDate
390 * return a modification timestamp for table
391 */
SRAMgrVGetTableModDate(const SRAMgr * self,KTime_t * mtime,const char * spec,va_list args)392 LIB_EXPORT rc_t CC SRAMgrVGetTableModDate ( const SRAMgr *self,
393 KTime_t *mtime, const char *spec, va_list args )
394 {
395 rc_t rc;
396
397 if ( mtime == NULL )
398 rc = RC ( rcSRA, rcMgr, rcAccessing, rcParam, rcNull );
399 else
400 {
401 * mtime = 0;
402 if ( self == NULL )
403 rc = RC ( rcSRA, rcMgr, rcAccessing, rcSelf, rcNull );
404 else
405 {
406 char path[4096];
407 rc = ResolveTablePath(self, path, sizeof path, spec, args);
408 if( rc == 0 ) {
409 struct KDBManager const *kmgr;
410 rc = VDBManagerGetKDBManagerRead ( self -> vmgr, & kmgr );
411 if ( rc == 0 )
412 {
413 rc = KDBManagerGetTableModDate(kmgr, mtime, "%s", path);
414 KDBManagerRelease ( kmgr );
415 }
416 }
417 }
418 }
419
420 return rc;
421 }
422
SRAMgrGetTableModDate(const SRAMgr * self,KTime_t * mtime,const char * spec,...)423 LIB_EXPORT rc_t CC SRAMgrGetTableModDate ( const SRAMgr *self,
424 KTime_t *mtime, const char *spec, ... )
425 {
426 rc_t rc;
427
428 va_list args;
429 va_start ( args, spec );
430 rc = SRAMgrVGetTableModDate ( self, mtime, spec, args );
431 va_end ( args );
432
433 return rc;
434 }
435
SRAMgrSingleFileArchiveExt(const SRAMgr * self,const char * spec,const bool lightweight,const char ** ext)436 LIB_EXPORT rc_t CC SRAMgrSingleFileArchiveExt(const SRAMgr *self, const char* spec, const bool lightweight, const char** ext)
437 {
438 rc_t rc;
439
440 if( self == NULL || spec == NULL || ext == NULL ) {
441 rc = RC(rcSRA, rcFile, rcConstructing, rcParam, rcNull);
442 } else {
443 char buf[4096];
444 va_list args;
445
446 if( (rc = ResolveTablePath(self, buf, sizeof(buf), spec, args)) == 0 ) {
447 const KDBManager* kmgr;
448 if( (rc = SRAMgrGetKDBManagerRead(self, &kmgr)) == 0 ) {
449 int type = KDBManagerPathType(kmgr, "%s", buf) & ~kptAlias;
450 if( type == kptDatabase ) {
451 *ext = CSRA_EXT(lightweight);
452 } else if( type == kptTable ) {
453 *ext = SRA_EXT(lightweight);
454 } else {
455 rc = RC(rcSRA, rcPath, rcResolving, rcType, rcUnknown);
456 }
457 KDBManagerRelease(kmgr);
458 }
459 }
460 }
461 return rc;
462 }
463
464 /*
465 * FlushPath
466 * FlushRun
467 * RunBGTasks
468 * stubbed functions to manipulate a cache, if implemented
469 */
SRAMgrGetCacheUsage(const SRAMgr * self,struct SRACacheUsage * stats)470 LIB_EXPORT rc_t CC SRAMgrGetCacheUsage( const SRAMgr *self, struct SRACacheUsage* stats )
471 {
472 rc_t rc = 0;
473 if ( self == NULL || stats == NULL || self->cache == NULL)
474 rc = RC(rcSRA, rcMgr, rcAccessing, rcParam, rcNull);
475 else
476 rc = SRACacheGetUsage(self->cache, stats);
477 return rc;
478 }
479
SRAMgrFlush(struct SRAMgr const * self,const struct SRACacheMetrics * thr)480 LIB_EXPORT rc_t CC SRAMgrFlush ( struct SRAMgr const *self, const struct SRACacheMetrics* thr )
481 {
482 rc_t rc = 0;
483 if( self == NULL || self->cache == NULL)
484 rc = RC(rcSRA, rcFile, rcProcessing, rcSelf, rcNull);
485 else if( thr == NULL )
486 rc = RC(rcSRA, rcFile, rcProcessing, rcParam, rcNull);
487 else
488 {
489 SRACacheMetrics saved;
490 rc = SRACacheGetSoftThreshold(self->cache, &saved);
491 if (rc == 0)
492 {
493 rc = SRACacheSetSoftThreshold(self->cache, thr);
494 if (rc == 0)
495 {
496 rc_t rc2;
497 rc = SRACacheFlush(self->cache);
498 rc2 = SRACacheSetSoftThreshold(self->cache, &saved);
499 if (rc == 0)
500 rc = rc2;
501 }
502 }
503 }
504 return rc;
505 }
506
SRAMgrRunBGTasks(const SRAMgr * self)507 LIB_EXPORT rc_t CC SRAMgrRunBGTasks ( const SRAMgr *self )
508 {
509 rc_t rc;
510
511 if( self == NULL )
512 rc = RC(rcSRA, rcMgr, rcProcessing, rcSelf, rcNull);
513
514 rc = SRACacheFlush(self->cache);
515
516 return rc;
517 }
518
SRAMgrConfigureCache(const SRAMgr * self,int32_t soft_threshold,int32_t hard_threshold)519 LIB_EXPORT rc_t CC SRAMgrConfigureCache( const SRAMgr *self, int32_t soft_threshold, int32_t hard_threshold )
520 {
521 rc_t rc = 0;
522 if( self == NULL || self->cache == NULL)
523 rc = RC(rcSRA, rcFile, rcProcessing, rcSelf, rcNull);
524 else if( soft_threshold < -1 || hard_threshold < -1 )
525 rc = RC(rcSRA, rcFile, rcProcessing, rcParam, rcNull);
526 else
527 {
528 if ( soft_threshold > -1 )
529 {
530 SRACacheMetrics metrics;
531 memset(&metrics, 0, sizeof(metrics));
532 metrics.elements = soft_threshold;
533 rc = SRACacheSetSoftThreshold(self->cache, &metrics);
534 }
535 if ( rc == 0 && hard_threshold > -1 )
536 {
537 SRACacheMetrics metrics;
538 memset(&metrics, 0, sizeof(metrics));
539 metrics.elements = hard_threshold;
540 rc = SRACacheSetHardThreshold(self->cache, &metrics);
541 }
542 /* if a new threshold is low enough to cause a flush, do it right away */
543 rc = SRACacheFlush(self->cache);
544 }
545 return rc;
546 }
547
548 /*--------------------------------------------------------------------------
549 * SRANamelist
550 * redirecting functions
551 */
552
553
SRANamelistAddRef(const SRANamelist * self)554 LIB_EXPORT rc_t CC SRANamelistAddRef ( const SRANamelist *self )
555 {
556 return KNamelistAddRef ( ( const KNamelist* ) self );
557 }
558
SRANamelistRelease(const SRANamelist * self)559 LIB_EXPORT rc_t CC SRANamelistRelease ( const SRANamelist *self )
560 {
561 return KNamelistRelease ( ( const KNamelist* ) self );
562 }
563
SRANamelistCount(const SRANamelist * self,uint32_t * count)564 LIB_EXPORT rc_t CC SRANamelistCount ( const SRANamelist *self, uint32_t *count )
565 {
566 return KNamelistCount ( ( const KNamelist* ) self, count );
567 }
568
SRANamelistGet(const SRANamelist * self,uint32_t idx,const char ** name)569 LIB_EXPORT rc_t CC SRANamelistGet ( const SRANamelist *self, uint32_t idx, const char **name )
570 {
571 return KNamelistGet ( ( const KNamelist* ) self, idx, name );
572 }
573
574 /*--------------------------------------------------------------------------
575 * SRASchema - DEPRECATED
576 */
577
SRASchemaMake(struct VSchema ** schema,struct VDBManager const * mgr)578 LIB_EXPORT rc_t CC SRASchemaMake ( struct VSchema **schema, struct VDBManager const *mgr )
579 {
580 if ( schema )
581 {
582 *schema = NULL;
583 }
584 return 0;
585 }
586