Module: ImmutableSetExt

Defined in:
ext/immutable_set/immutable_set.c

Class Method Summary collapse

Class Method Details

.difference(set_a, set_b) ⇒ Object

Returns a new set that includes any member of either passed set.



288
289
290
291
# File 'ext/immutable_set/immutable_set.c', line 288

static VALUE
method_difference(VALUE self, VALUE set_a, VALUE set_b) {
  return parallel_build(set_a, set_b, add_nonb_members_to_hash);
}

.exclusion(set_a, set_b) ⇒ Object

Returns a new set that is a XOR result of SET_A and SET_B.



331
332
333
334
# File 'ext/immutable_set/immutable_set.c', line 331

static VALUE
method_exclusion(VALUE self, VALUE set_a, VALUE set_b) {
  return parallel_build(set_a, set_b, add_xor_members_to_hash);
}

.fill_with_fixnums(hash, range) ⇒ Object

Fills HASH will all Fixnums in RANGE.



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'ext/immutable_set/immutable_set.c', line 349

static VALUE
method_fill_with_fixnums(VALUE self, VALUE hash, VALUE range) {
  VALUE from_id, upto_id;
  st_table *tbl;

  GET_RANGE_FIXNUM_IDS(range, from_id, upto_id);
  tbl = RHASH_TBL(hash);

  while (from_id <= upto_id) {
    st_insert(tbl, from_id, Qtrue);
    INCR_FIXNUM_ID(from_id);
  }

  return upto_id;
}

.intersect?(set_a, set_b) ⇒ Boolean

Returns Qtrue if SET_A intersects with SET_B, else Qfalse.

Returns:

  • (Boolean)


152
153
154
155
# File 'ext/immutable_set/immutable_set.c', line 152

static VALUE
method_intersect_p(VALUE self, VALUE set_a, VALUE set_b) {
  return parallel_compare(set_a, set_b, check_if_intersect, Qfalse);
}

.intersection(set_a, set_b) ⇒ Object

Returns a new set containing all members shared by SET_A and SET_B.



210
211
212
213
# File 'ext/immutable_set/immutable_set.c', line 210

static VALUE
method_intersection(VALUE self, VALUE set_a, VALUE set_b) {
  return parallel_build(set_a, set_b, add_shared_to_hash);
}

.invert_fixnum_set(set, range, ucp) ⇒ Object

Returns a new set that is a XOR result of SET and the given RANGE.



373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
# File 'ext/immutable_set/immutable_set.c', line 373

static VALUE
method_invert_fixnum_set(VALUE self, VALUE set, VALUE range, VALUE ucp) {
  VALUE fixnum_id, upto_id, new_hash, new_set, entry;
  st_index_t size, i;
  int ucp_only;
  st_table *new_tbl;
  struct LOC_st_stable_entry *entries;

  GET_RANGE_FIXNUM_IDS(range, fixnum_id, upto_id);
  ucp_only = ucp != Qfalse && ucp != Qnil && ucp != Qundef;

  // get set members
  entries = set_entries_ptr(set, &size);

  // prepare new Set
  new_set = rb_class_new_instance(0, 0, RBASIC(set)->klass);
  new_hash = rb_hash_new();
  new_tbl = RHASH_TBL(new_hash);
  rb_iv_set(new_set, "@hash", new_hash);

  if (size) {
    i = 0;
    entry = entries[i].key;

    // here is the optimization: skipping unneeded comparisons with lower values
    for (;;) {
      if (fixnum_id == entry) {
        // fixnum_id is in set, compare next fixnum with next set member
        entry = entries[++i].key;
        INCR_FIXNUM_ID(fixnum_id);
        if (i == size || fixnum_id > upto_id) break;
      }
      else if (fixnum_id < entry) {
        // fixnum_id is not in set, include in inversion
        insert_fixnum_id(new_tbl, fixnum_id, ucp_only);
        INCR_FIXNUM_ID(fixnum_id);
        if (fixnum_id > upto_id) break;
      }
      else /* if (fixnum_id > entry) */ {
        // gap; fixnum_id might be in set, check next set member
        entry = entries[++i].key;
        if (i == size) break;
      }
    }
  }

  // include all fixnums beyond the range of the set
  while (fixnum_id <= upto_id) {
    insert_fixnum_id(new_tbl, fixnum_id, ucp_only);
    INCR_FIXNUM_ID(fixnum_id);
  }

  set_max_ivar_for_set(new_set);
  rb_obj_freeze(new_hash);

  return new_set;
}

.subset?(set_a, set_b) ⇒ Boolean

Returns Qtrue if SET_A is a subset (proper or not) of SET_B, else Qfalse.

Returns:

  • (Boolean)


127
128
129
130
# File 'ext/immutable_set/immutable_set.c', line 127

static VALUE
method_subset_p(VALUE self, VALUE set_a, VALUE set_b) {
  return parallel_compare(set_a, set_b, check_first_subset_of_second, Qfalse);
}

.superset?(set_a, set_b) ⇒ Boolean

Returns Qtrue if SET_A is a superset (proper or not) of SET_B, else Qfalse.

Returns:

  • (Boolean)


133
134
135
136
# File 'ext/immutable_set/immutable_set.c', line 133

static VALUE
method_superset_p(VALUE self, VALUE set_a, VALUE set_b) {
  return parallel_compare(set_b, set_a, check_first_subset_of_second, Qfalse);
}

.union(set_a, set_b) ⇒ Object

Returns a new set that includes all members of SET_A and/or SET_B.



252
253
254
255
# File 'ext/immutable_set/immutable_set.c', line 252

static VALUE
method_union(VALUE self, VALUE set_a, VALUE set_b) {
  return parallel_build(set_a, set_b, add_any_members_to_hash);
}