~ubuntu-branches/ubuntu/precise/ncbi-tools6/precise

« back to all changes in this revision

Viewing changes to api/objmgr.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2005-03-27 12:00:15 UTC
  • mfrom: (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050327120015-embhesp32nj73p9r
Tags: 6.1.20041020-3
* Fix FTBFS under GCC 4.0 caused by inconsistent use of "static" on
  functions.  (Closes: #295110.)
* Add a watch file, now that we can.  (Upstream's layout needs version=3.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
*   
30
30
* Version Creation Date: 9/94
31
31
*
32
 
* $Revision: 6.43 $
 
32
* $Revision: 6.57 $
33
33
*
34
34
* File Description:  Manager for Bioseqs and BioseqSets
35
35
*
36
36
* Modifications:  
37
37
* --------------------------------------------------------------------------
38
 
* Date     Name        Description of modification
39
 
* -------  ----------  -----------------------------------------------------
40
 
*
41
 
*
42
38
* $Log: objmgr.c,v $
 
39
* Revision 6.57  2004/10/15 19:08:36  bollin
 
40
* when removing an object, make sure to also deselect it
 
41
*
 
42
* Revision 6.56  2004/09/07 14:08:27  kans
 
43
* post errors on failure of ObjMgrNextAvailEntityID and ObjMgrRecycleEntityID
 
44
*
 
45
* Revision 6.55  2004/06/09 01:56:43  kans
 
46
* initialize assigned id array from all functions that use it
 
47
*
 
48
* Revision 6.54  2004/06/08 20:48:09  kans
 
49
* changed entityID recycling from small array of integers to bit array of all possible values
 
50
*
 
51
* Revision 6.53  2004/06/08 18:19:01  kans
 
52
* ObjMgrFreeCacheFunc frees all TL_CACHED, and frees TL_LOADED if type == 0
 
53
*
 
54
* Revision 6.52  2004/04/21 19:40:51  kans
 
55
* ObjMgrReap calculate tempcnt based on temp loaded records, but excluded locked ones - more work still to do in other functions to completely avoid unnecessary thrashing
 
56
*
 
57
* Revision 6.51  2004/04/01 13:43:05  lavr
 
58
* Spell "occurred", "occurrence", and "occurring"
 
59
*
 
60
* Revision 6.50  2003/12/22 15:29:28  kans
 
61
* ObjMgrSendMsg calls SeqMgrClearFeatureIndexes on OM_MSG_DEL as well as OM_MSG_UPDATE
 
62
*
 
63
* Revision 6.49  2002/07/30 14:41:45  kans
 
64
* removed omdp->rearranged
 
65
*
 
66
* Revision 6.48  2002/07/29 21:30:17  kans
 
67
* added rearranged flag to omdp
 
68
*
 
69
* Revision 6.47  2002/07/01 14:29:02  kans
 
70
* changed totobj, currobj to Uint4
 
71
*
 
72
* Revision 6.46  2002/06/07 21:24:57  kans
 
73
* update entityID/omdp index in BioseqReloadFunc, ObjMgrConnectFunc, ObjMgrDetachFunc
 
74
*
 
75
* Revision 6.45  2002/06/01 05:52:00  vakatov
 
76
* Fix to R6.44 -- add LIBCALL and NLM_EXTERN modifiers to match the func proto
 
77
*
 
78
* Revision 6.44  2002/05/31 21:53:26  yaschenk
 
79
* changing lookup by EntityID to array[][]
 
80
*
43
81
* Revision 6.43  2001/12/13 13:59:14  kans
44
82
* ObjMgrSendMsg clears feature indexes if OM_MSG_UPDATE
45
83
*
293
331
#define DEBUG_OBJMGR
294
332
***/
295
333
 
 
334
#define OBJMGR_MAX UINT4_MAX
 
335
 
296
336
 
297
337
/*****************************************************************************
298
338
*
453
493
                topOMDPs [topIDStackPt] = omdp;
454
494
                topIDStackPt++;
455
495
        }
 
496
        ObjMgrAddIndexOnEntityID(NULL,entityID,omdp);
456
497
}
457
498
 
458
499
static ObjMgrDataPtr NEAR ObjMgrFindByEntityID (ObjMgrPtr omp, Uint2 entityID, ObjMgrDataPtr PNTR prev)
462
503
        Int4 i, imax;
463
504
 
464
505
        /* check cache first to avoid linear search through all objects */
 
506
        if((omdp=ObjMgrLookupIndexOnEntityID(omp,entityID)) != NULL) return omdp;
465
507
 
466
508
        for (i = 0; i < topIDStackPt; i++) {
467
509
                if (entityID == topEntityIDs [i]) {
518
560
        return NULL;
519
561
}
520
562
 
521
 
#define ENTITY_ID_STACK_SIZE  100
522
 
 
523
 
static Uint2 recycledEntityIDs [ENTITY_ID_STACK_SIZE];
524
 
static Int4  recycledIDStackPt = 0;
 
563
static Uint4    assignedIDsArray [2050];
 
564
static Int2     assignedIDStackPt = 0;
 
565
static Boolean  assignedIDsInited = FALSE;
 
566
 
 
567
static Uint4    assignedIDsBitIdx [32];
 
568
 
 
569
static Uint2 ObjMgrInitAssignedIDArray (void)
 
570
 
 
571
{
 
572
  Uint4  bit;
 
573
  Int2   jdx;
 
574
 
 
575
  if (! assignedIDsInited) {
 
576
    MemSet ((Pointer) &assignedIDsArray, 0, sizeof assignedIDsArray);
 
577
    MemSet ((Pointer) &assignedIDsBitIdx, 0, sizeof (assignedIDsBitIdx));
 
578
  
 
579
    /* initialize bit index array */
 
580
 
 
581
    bit = 1;
 
582
    for (jdx = 0; jdx < 32; jdx++) {
 
583
      assignedIDsBitIdx [jdx] = bit;
 
584
      bit = bit << 1;
 
585
    }
 
586
  
 
587
    /* entityID 0 is not available for use */
 
588
 
 
589
    assignedIDsArray [0] = assignedIDsBitIdx [0];
 
590
 
 
591
    assignedIDStackPt = 0;
 
592
    assignedIDsInited = TRUE;
 
593
  }
 
594
}
 
595
 
 
596
static Uint2 ObjMgrNextAvailEntityID (ObjMgrPtr omp)
 
597
 
 
598
{
 
599
  Uint2  entityID;
 
600
  Int2   idx, jdx;
 
601
  Uint4  val;
 
602
 
 
603
  if (! assignedIDsInited) {
 
604
    ObjMgrInitAssignedIDArray ();
 
605
  }
 
606
 
 
607
  /* find first 32 bit word with an available entityID */
 
608
 
 
609
  idx = assignedIDStackPt;
 
610
  while (idx < 2048 && assignedIDsArray [idx] == 0xFFFFFFFF) {
 
611
    idx++;
 
612
  }
 
613
  if (idx >= 2048) {
 
614
    ErrPostEx (SEV_ERROR, 0, 0, "ObjMgrNextAvailEntityID failed with idx %d", (int) idx);
 
615
    return 0;
 
616
  }
 
617
 
 
618
  /* reset starting point, everything below should be in use */
 
619
 
 
620
  assignedIDStackPt = idx;
 
621
 
 
622
  /* find first empty bit in array element */
 
623
 
 
624
  val = assignedIDsArray [idx];
 
625
  jdx = 0;
 
626
  while (jdx < 32 && (val & assignedIDsBitIdx [jdx]) != 0) {
 
627
    jdx++;
 
628
  }
 
629
  if (jdx >= 32) {
 
630
    ErrPostEx (SEV_ERROR, 0, 0, "ObjMgrNextAvailEntityID failed with jdx %d", (int) jdx);
 
631
    return 0;
 
632
  }
 
633
 
 
634
  /* set bit to mark new entityID as in use */
 
635
 
 
636
  assignedIDsArray [idx] |= assignedIDsBitIdx [jdx];
 
637
 
 
638
  /* calculate entityID */
 
639
 
 
640
  entityID = (Uint2) ((Int4) idx) * 32L + (Int4) jdx;
 
641
 
 
642
  if (omp != NULL && omp->HighestEntityID < entityID) {
 
643
    omp->HighestEntityID = entityID;
 
644
  }
 
645
 
 
646
  return entityID;
 
647
}
 
648
 
 
649
static void ObjMgrRecycleEntityID (Uint2 entityID, ObjMgrPtr omp)
 
650
 
 
651
{
 
652
  Int2   idx, jdx;
 
653
 
 
654
  if (! assignedIDsInited) {
 
655
    ObjMgrInitAssignedIDArray ();
 
656
  }
 
657
 
 
658
  if (entityID < 1) return;
 
659
 
 
660
  idx = (Int2) (entityID / 32);
 
661
  jdx = (Int2) (entityID % 32);
 
662
 
 
663
  if (idx >= 2048 || idx < 0) {
 
664
    ErrPostEx (SEV_ERROR, 0, 0, "ObjMgrRecycleEntityID failed with idx %d", (int) idx);
 
665
    return;
 
666
  }
 
667
  if (jdx >= 32 || jdx < 0) {
 
668
    ErrPostEx (SEV_ERROR, 0, 0, "ObjMgrRecycleEntityID failed with jdx %d", (int) jdx);
 
669
    return;
 
670
  }
 
671
 
 
672
  /* clear bit to mark old entityID as available */
 
673
 
 
674
  assignedIDsArray [idx] ^= assignedIDsBitIdx [jdx];
 
675
 
 
676
  /* reset starting point, everything below should be in use */
 
677
 
 
678
  if (idx < assignedIDStackPt) {
 
679
    assignedIDStackPt = idx;
 
680
  }
 
681
}
525
682
 
526
683
extern void ObjMgrRemoveEntityIDFromRecycle (Uint2 entityID, ObjMgrPtr omp);
527
684
extern void ObjMgrRemoveEntityIDFromRecycle (Uint2 entityID, ObjMgrPtr omp)
528
685
 
529
686
{
530
 
        Int4  i;
531
 
 
532
 
        if (entityID < 1) return;
533
 
        if (omp != NULL) {
534
 
                for (i = 0; i < recycledIDStackPt; i++) {
535
 
                        if (entityID == recycledEntityIDs [i]) {
536
 
                                recycledEntityIDs [i] = 0; /* remove from recycle list */
537
 
                                if (recycledIDStackPt > i + 1) {
538
 
                                        recycledIDStackPt--;
539
 
                                        recycledEntityIDs [i] = recycledEntityIDs [recycledIDStackPt];
540
 
                                } else {
541
 
                                        recycledIDStackPt--;
542
 
                                }
543
 
                        }
544
 
                }
545
 
        }
546
 
}
547
 
 
548
 
static Uint2 ObjMgrNextAvailEntityID (ObjMgrPtr omp)
549
 
 
550
 
{
551
 
        Uint2      entityID = 0;
552
 
        if (omp != NULL) {
553
 
                if (recycledIDStackPt > 0) {
554
 
                        recycledIDStackPt--;
555
 
                        entityID = recycledEntityIDs [recycledIDStackPt];
556
 
                } else {
557
 
                        entityID = ++(omp->HighestEntityID);
558
 
                }
559
 
        }
560
 
        return entityID;
561
 
}
562
 
 
563
 
static void ObjMgrRecycleEntityID (Uint2 entityID, ObjMgrPtr omp)
564
 
 
565
 
{
566
 
 
567
 
        Int4  i;
568
 
 
569
 
        if (entityID < 1) return;
570
 
        if (omp != NULL) {
571
 
                /* check to see if entity is already on stack (e.g., entity 1), abort if so */
572
 
                for (i = 0; i < recycledIDStackPt; i++) {
573
 
                        if (entityID == recycledEntityIDs [i]) return;
574
 
                }
575
 
                if (recycledIDStackPt < ENTITY_ID_STACK_SIZE) {
576
 
                        recycledEntityIDs [recycledIDStackPt] = entityID;
577
 
                        recycledIDStackPt++;
578
 
                }
579
 
        }
 
687
  Int2   idx, jdx;
 
688
 
 
689
  if (! assignedIDsInited) {
 
690
    ObjMgrInitAssignedIDArray ();
 
691
  }
 
692
 
 
693
  if (entityID < 1) return;
 
694
 
 
695
  idx = (Int2) (entityID / 32);
 
696
  jdx = (Int2) (entityID % 32);
 
697
 
 
698
  if (idx >= 2048 || idx < 0) return;
 
699
  if (jdx >= 32 || jdx < 0) return;
 
700
 
 
701
  /* set bit to restore old entityID status to in use */
 
702
 
 
703
  assignedIDsArray [idx] |= assignedIDsBitIdx [jdx];
580
704
}
581
705
 
582
706
NLM_EXTERN Uint2 LIBCALL ObjMgrAddEntityID (ObjMgrPtr omp, ObjMgrDataPtr omdp)
1037
1161
 
1038
1162
        omp = ObjMgrWriteLock();
1039
1163
 
1040
 
        if (omp->hold < UINT2_MAX)
 
1164
        if (omp->hold < OBJMGR_MAX)
1041
1165
                omp->hold++;
1042
1166
        else
1043
 
                ErrPostEx(SEV_ERROR,0,0, "ObjMgrSetHold: hold > UINT2_MAX");
 
1167
                ErrPostEx(SEV_ERROR,0,0, "ObjMgrSetHold: hold > OBJMGR_MAX");
1044
1168
        ObjMgrUnlock();
1045
1169
        return omp->hold;
1046
1170
}
1135
1259
        for (i = 0; i < NUM_OMD; i++, j++)
1136
1260
                tmp[j] = &(omdp->data[i]);
1137
1261
 
1138
 
        if (omp->totobj < UINT2_MAX - NUM_OMD)
 
1262
        if (omp->totobj < OBJMGR_MAX - NUM_OMD)
1139
1263
                omp->totobj += NUM_OMD;
1140
1264
        else
1141
 
                ErrPostEx(SEV_ERROR, 0,0, "ObjMgrExtend: incrementing totobj above UINT2_MAX");
 
1265
                ErrPostEx(SEV_ERROR, 0,0, "ObjMgrExtend: incrementing totobj above OBJMGR_MAX");
1142
1266
        omp->datalist = tmp;
1143
1267
 
1144
1268
        result = TRUE;
1245
1369
        }
1246
1370
 
1247
1371
        omdpp[i] = omdp;    /* put in the pointer in order */
1248
 
        if (omp->currobj < UINT2_MAX)
 
1372
        if (omp->currobj < OBJMGR_MAX)
1249
1373
                omp->currobj++;     /* got one more */
1250
1374
        else
1251
 
                ErrPostEx(SEV_ERROR, 0,0, "ObjMgrAddFunc: incrementing currobj above UINT2_MAX");
 
1375
                ErrPostEx(SEV_ERROR, 0,0, "ObjMgrAddFunc: incrementing currobj above OBJMGR_MAX");
1252
1376
 
1253
1377
        omdp->dataptr = data;  /* fill in the values */
1254
1378
        omdp->datatype = type;
1676
1800
        if (omdp->EntityID != 0)
1677
1801
                ObjMgrRecycleEntityID (omdp->EntityID, omp);
1678
1802
 
 
1803
        ObjMgrDeleteIndexOnEntityID(omp,omdp->EntityID);
 
1804
 
1679
1805
        if (omdp->extradata != NULL && omdp->freeextra != NULL) {
1680
1806
                omdp->freeextra ((Pointer) omdp);
1681
1807
        }
1952
2078
                        (omp->HighestEntityID)--;
1953
2079
                } */
1954
2080
                ObjMgrRecycleEntityID (omdp->EntityID, omp);
 
2081
                ObjMgrDeleteIndexOnEntityID (omp, omdp->EntityID);
1955
2082
                omdp->EntityID = 0;   /* reset.. now has a parent */
1956
2083
        }
1957
2084
        omdp->parenttype = parenttype;
2023
2150
 
2024
2151
        omdp->parenttype = 0;
2025
2152
        omdp->parentptr = NULL;
 
2153
        ObjMgrDeleteIndexOnEntityID (omp, omdp->EntityID);
2026
2154
        omdp->EntityID = 0;   /* reset.. now has a parent */
2027
2155
 
2028
2156
        retval = TRUE;
2171
2299
*       Frees all cached objects of type and subtypes of type
2172
2300
*               based on ObjMgrMatch()
2173
2301
*       if type == 0, frees all cached objects
2174
 
*       returns TRUE if no errors occured
 
2302
*       returns TRUE if no errors occurred
2175
2303
*
2176
2304
*****************************************************************************/
2177
2305
NLM_EXTERN Boolean LIBCALL ObjMgrFreeCache (Uint2 type)
2237
2365
    {
2238
2366
                omdp = omdpp[i];
2239
2367
                if ((omdp->parentptr == NULL) &&     /* top level */
2240
 
                        (omdp->tempload == TL_CACHED))   /* cached */
 
2368
                        (omdp->tempload == TL_CACHED ||   /* cached or */
 
2369
                        (type == 0 && omdp->tempload == TL_LOADED)))   /* unlocked but not cached out */
2241
2370
                {
2242
2371
                        if ((! type) ||
2243
2372
                                (ObjMgrMatch(type, omdp->datatype)) ||
2589
2718
{
2590
2719
        Uint4 lowest;
2591
2720
        Int4 num, j;
 
2721
        Uint2 tempcnt;
2592
2722
        ObjMgrDataPtr tmp, ditch, PNTR omdpp;
2593
2723
        Boolean is_write_locked, did_one = FALSE;
2594
2724
 
2598
2728
        if (omp->reaping)   /* protect against recursion caused by ObjMgrSendMsg */
2599
2729
                return FALSE;
2600
2730
 
2601
 
        while (omp->tempcnt > omp->maxtemp)   /* time to reap */
 
2731
    tempcnt = 0;
 
2732
        num = omp->currobj;
 
2733
        omdpp = omp->datalist;
 
2734
        for (j = 0; j < num; j++, omdpp++)
 
2735
        {
 
2736
                tmp = *omdpp;
 
2737
                if ((tmp->tempload == TL_LOADED) && (! tmp->lockcnt))
 
2738
                {
 
2739
                        tempcnt++;
 
2740
                }
 
2741
        }
 
2742
 
 
2743
        while (/* omp-> */ tempcnt > omp->maxtemp)   /* time to reap */
2602
2744
        {
2603
2745
                lowest = UINT4_MAX;
2604
 
                
 
2746
 
 
2747
        tempcnt = 0;
2605
2748
                num = omp->currobj;
2606
2749
                omdpp = omp->datalist;
2607
2750
                ditch = NULL;
2610
2753
                        tmp = *omdpp;
2611
2754
                        if ((tmp->tempload == TL_LOADED) && (! tmp->lockcnt))
2612
2755
                        {
 
2756
                            tempcnt++;
2613
2757
                                if (lowest > tmp->touch)
2614
2758
                                {
2615
2759
                                        lowest = tmp->touch;
2624
2768
                ditch->tempload = TL_CACHED;
2625
2769
                ObjMgrSendMsgFunc(omp, ditch, OM_MSG_CACHED, ditch->EntityID, 0, 0, 0, 0, 0, NULL);
2626
2770
                omp->tempcnt--;
 
2771
                tempcnt--;
2627
2772
                is_write_locked = omp->is_write_locked;
2628
2773
 
2629
2774
                /* null out feature pointers in seqmgr feature indices via reap function */
4394
4539
 
4395
4540
        if (msg == OM_MSG_UPDATE) {
4396
4541
                SeqMgrClearFeatureIndexes (entityID, NULL);
 
4542
        } else if (msg == OM_MSG_DEL) {
 
4543
                SeqMgrClearFeatureIndexes (entityID, NULL);
 
4544
          ObjMgrDeSelect (entityID, itemID, itemtype, 0, NULL);
4397
4545
        }
4398
4546
        omp = ObjMgrReadLock();
4399
4547
        omdp = ObjMgrFindByEntityID(omp, entityID, NULL);
4790
4938
  FileClose (fp);
4791
4939
}
4792
4940
 
 
4941
 
 
4942
NLM_EXTERN void LIBCALL
 
4943
ObjMgrAddIndexOnEntityID(ObjMgrPtr omp,Uint2 entityID,ObjMgrDataPtr omdp)
 
4944
{
 
4945
        Uint1   h,l;
 
4946
 
 
4947
        h=entityID >> 8;
 
4948
        l=entityID & 0xff;
 
4949
        if(omp==NULL) omp=ObjMgrGet();
 
4950
        if(omp){
 
4951
                if(!omp->entityID_index){
 
4952
                        omp->entityID_index=MemNew(256*sizeof(*omp->entityID_index));
 
4953
                }
 
4954
                if(!omp->entityID_index[h]){
 
4955
                        omp->entityID_index[h]=MemNew(256*sizeof(**omp->entityID_index));
 
4956
                }
 
4957
                omp->entityID_index[h][l]=omdp;
 
4958
        }
 
4959
}
 
4960
 
 
4961
 
 
4962
NLM_EXTERN void LIBCALL
 
4963
ObjMgrDeleteIndexOnEntityID(ObjMgrPtr omp,Uint2 entityID)
 
4964
{
 
4965
        Uint1   h,l;
 
4966
 
 
4967
        h=entityID >> 8;
 
4968
        l=entityID & 0xff;
 
4969
        if(omp==NULL) omp=ObjMgrGet();
 
4970
        if(omp && omp->entityID_index && omp->entityID_index[h]){
 
4971
                omp->entityID_index[h][l]=NULL;
 
4972
        }
 
4973
 
 
4974
}
 
4975
 
 
4976
 
 
4977
NLM_EXTERN ObjMgrDataPtr LIBCALL
 
4978
ObjMgrLookupIndexOnEntityID(ObjMgrPtr omp,Uint2 entityID)
 
4979
{
 
4980
        Uint1   h,l;
 
4981
 
 
4982
        h=entityID >> 8;
 
4983
        l=entityID & 0xff;
 
4984
        if(omp==NULL) omp=ObjMgrGet();
 
4985
        if(omp && omp->entityID_index && omp->entityID_index[h]){
 
4986
                return omp->entityID_index[h][l];
 
4987
        } else {
 
4988
                return NULL;
 
4989
        }
 
4990
}