Пример #1
0
void
sarray_at_put_safe (struct sarray *array, sidx index, void *element)
{
  if (soffset_decode (index) >= array->capacity)
    sarray_realloc (array, soffset_decode (index) + 1);
  sarray_at_put (array, index, element);
}
Пример #2
0
static __inline__ void *
sarray_get_safe (struct sarray *array, sidx indx)
{
  if (soffset_decode (indx) < array->capacity)
    return (void *)sarray_get (array, indx);
}
Пример #3
0
/* sarray_at_put : copies data in such a way as to be thread reader safe. */
void
sarray_at_put (struct sarray *array, sidx index, void *element)
{
#ifdef OBJC_SPARSE3
  struct sindex **the_index;
  struct sindex *new_index;
#endif
  struct sbucket **the_bucket;
  struct sbucket *new_bucket;
#ifdef OBJC_SPARSE3
  size_t ioffset;
#endif
  size_t boffset;
  size_t eoffset;
#ifdef PRECOMPUTE_SELECTORS
  union sofftype xx; 
  xx.idx = index;
#ifdef OBJC_SPARSE3
  ioffset = xx.off.ioffset;
#endif
  boffset = xx.off.boffset;
  eoffset = xx.off.eoffset;
#else /* not PRECOMPUTE_SELECTORS */
#ifdef OBJC_SPARSE3
  ioffset = index/INDEX_CAPACITY;
  boffset = (index/BUCKET_SIZE)%INDEX_SIZE;
  eoffset = index%BUCKET_SIZE;
#else
  boffset = index/BUCKET_SIZE;
  eoffset = index%BUCKET_SIZE;
#endif
#endif /* not PRECOMPUTE_SELECTORS */

  assert (soffset_decode (index) < array->capacity); /* Range check */

#ifdef OBJC_SPARSE3
  the_index = &(array->indices[ioffset]);
  the_bucket = &((*the_index)->buckets[boffset]);
#else
  the_bucket = &(array->buckets[boffset]);
#endif
  
  if ((*the_bucket)->elems[eoffset] == element)
    return;		/* great! we just avoided a lazy copy */

#ifdef OBJC_SPARSE3

  /* First, perform lazy copy/allocation of index if needed */

  if ((*the_index) == array->empty_index) {

    /* The index was previously empty, allocate a new */
    new_index = (struct sindex *) objc_malloc (sizeof (struct sindex));
    memcpy (new_index, array->empty_index, sizeof (struct sindex));
    new_index->version.version = array->version.version;
    *the_index = new_index;                     /* Prepared for install. */
    the_bucket = &((*the_index)->buckets[boffset]);
    
    nindices += 1;
  } else if ((*the_index)->version.version != array->version.version) {

    /* This index must be lazy copied */
    struct sindex *old_index = *the_index;
    new_index = (struct sindex *) objc_malloc (sizeof (struct sindex));
    memcpy (new_index, old_index, sizeof (struct sindex));
    new_index->version.version = array->version.version;
    *the_index = new_index;                     /* Prepared for install. */
    the_bucket = &((*the_index)->buckets[boffset]);
    
    nindices += 1;
  }

#endif /* OBJC_SPARSE3 */

  /* next, perform lazy allocation/copy of the bucket if needed */

  if ((*the_bucket) == array->empty_bucket) {

    /* The bucket was previously empty (or something like that), */
    /* allocate a new.  This is the effect of `lazy' allocation */  
    new_bucket = (struct sbucket *) objc_malloc (sizeof (struct sbucket));
    memcpy ((void *) new_bucket, (const void *) array->empty_bucket, 
	    sizeof (struct sbucket));
    new_bucket->version.version = array->version.version;
    *the_bucket = new_bucket;                   /* Prepared for install. */
    
    nbuckets += 1;

  } else if ((*the_bucket)->version.version != array->version.version) {

    /* Perform lazy copy. */
    struct sbucket *old_bucket = *the_bucket;
    new_bucket = (struct sbucket *) objc_malloc (sizeof (struct sbucket));
    memcpy (new_bucket, old_bucket, sizeof (struct sbucket));
    new_bucket->version.version = array->version.version;
    *the_bucket = new_bucket;                   /* Prepared for install. */
    
    nbuckets += 1;

  }
  (*the_bucket)->elems[eoffset] = element;
}