Class: ObjectSpace::WeakMap

Inherits:
Object show all
Includes:
Enumerable
Defined in:
gc.c,
gc.c

Overview

An ObjectSpace::WeakMap object holds references to any objects, but those objects can get garbage collected.

This class is mostly used internally by WeakRef, please use lib/weakref.rb for the public interface.

Instance Method Summary collapse

Methods included from Enumerable

#all?, #any?, #chunk, #chunk_while, #collect, #collect_concat, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #entries, #find, #find_all, #find_index, #first, #flat_map, #grep, #grep_v, #group_by, #inject, #lazy, #map, #max, #max_by, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reduce, #reject, #reverse_each, #select, #slice_after, #slice_before, #slice_when, #sort, #sort_by, #take, #take_while, #to_a, #to_h, #zip

Instance Method Details

#[](wmap) ⇒ Object

Retrieves a weakly referenced object with the given key


8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
# File 'gc.c', line 8246

static VALUE
wmap_aref(VALUE self, VALUE wmap)
{
    st_data_t data;
    VALUE obj;
    struct weakmap *w;
    rb_objspace_t *objspace = &rb_objspace;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    if (!st_lookup(w->wmap2obj, (st_data_t)wmap, &data)) return Qnil;
    obj = (VALUE)data;
    if (!is_id_value(objspace, obj)) return Qnil;
    if (!is_live_object(objspace, obj)) return Qnil;
    return obj;
}

#[]=(wmap, orig) ⇒ Object

Creates a weak reference from the given key to the given value


8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
# File 'gc.c', line 8230

static VALUE
wmap_aset(VALUE self, VALUE wmap, VALUE orig)
{
    struct weakmap *w;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    should_be_finalizable(orig);
    should_be_finalizable(wmap);
    define_final0(orig, w->final);
    define_final0(wmap, w->final);
    st_update(w->obj2wmap, (st_data_t)orig, wmap_aset_update, wmap);
    st_insert(w->wmap2obj, (st_data_t)wmap, (st_data_t)orig);
    return nonspecial_obj_id(orig);
}

#eachObject

Iterates over keys and objects in a weakly referenced object


8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
# File 'gc.c', line 8097

static VALUE
wmap_each(VALUE self)
{
    struct weakmap *w;
    rb_objspace_t *objspace = &rb_objspace;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    st_foreach(w->wmap2obj, wmap_each_i, (st_data_t)objspace);
    return self;
}

#each_keyObject

Iterates over keys and objects in a weakly referenced object


8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
# File 'gc.c', line 8120

static VALUE
wmap_each_key(VALUE self)
{
    struct weakmap *w;
    rb_objspace_t *objspace = &rb_objspace;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    st_foreach(w->wmap2obj, wmap_each_key_i, (st_data_t)objspace);
    return self;
}

#each_pairObject

Iterates over keys and objects in a weakly referenced object


8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
# File 'gc.c', line 8097

static VALUE
wmap_each(VALUE self)
{
    struct weakmap *w;
    rb_objspace_t *objspace = &rb_objspace;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    st_foreach(w->wmap2obj, wmap_each_i, (st_data_t)objspace);
    return self;
}

#each_valueObject

Iterates over keys and objects in a weakly referenced object


8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
# File 'gc.c', line 8143

static VALUE
wmap_each_value(VALUE self)
{
    struct weakmap *w;
    rb_objspace_t *objspace = &rb_objspace;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    st_foreach(w->wmap2obj, wmap_each_value_i, (st_data_t)objspace);
    return self;
}

#finalize(objid) ⇒ Object (private)


8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
# File 'gc.c', line 8008

static VALUE
wmap_finalize(VALUE self, VALUE objid)
{
    st_data_t orig, wmap, data;
    VALUE obj, *rids, i, size;
    struct weakmap *w;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    /* Get reference from object id. */
    obj = obj_id_to_ref(objid);

    /* obj is original referenced object and/or weak reference. */
    orig = (st_data_t)obj;
    if (st_delete(w->obj2wmap, &orig, &data)) {
	rids = (VALUE *)data;
	size = *rids++;
	for (i = 0; i < size; ++i) {
	    wmap = (st_data_t)rids[i];
	    st_delete(w->wmap2obj, &wmap, NULL);
	}
	ruby_sized_xfree((VALUE *)data, (size + 1) * sizeof(VALUE));
    }

    wmap = (st_data_t)obj;
    if (st_delete(w->wmap2obj, &wmap, &orig)) {
	wmap = (st_data_t)obj;
	st_update(w->obj2wmap, orig, wmap_final_func, wmap);
    }
    return self;
}

#include?(key) ⇒ Boolean

Returns true if key is registered


8263
8264
8265
8266
8267
# File 'gc.c', line 8263

static VALUE
wmap_has_key(VALUE self, VALUE key)
{
    return NIL_P(wmap_aref(self, key)) ? Qfalse : Qtrue;
}

#inspectObject


8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
# File 'gc.c', line 8068

static VALUE
wmap_inspect(VALUE self)
{
    VALUE str;
    VALUE c = rb_class_name(CLASS_OF(self));
    struct weakmap *w;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    str = rb_sprintf("-<%"PRIsVALUE":%p", c, (void *)self);
    if (w->wmap2obj) {
	st_foreach(w->wmap2obj, wmap_inspect_i, str);
    }
    RSTRING_PTR(str)[0] = '#';
    rb_str_cat2(str, ">");
    return str;
}

#key?(key) ⇒ Boolean

Returns true if key is registered


8263
8264
8265
8266
8267
# File 'gc.c', line 8263

static VALUE
wmap_has_key(VALUE self, VALUE key)
{
    return NIL_P(wmap_aref(self, key)) ? Qfalse : Qtrue;
}

#keysObject

Iterates over keys and objects in a weakly referenced object


8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
# File 'gc.c', line 8168

static VALUE
wmap_keys(VALUE self)
{
    struct weakmap *w;
    struct wmap_iter_arg args;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    args.objspace = &rb_objspace;
    args.value = rb_ary_new();
    st_foreach(w->wmap2obj, wmap_keys_i, (st_data_t)&args);
    return args.value;
}

#lengthObject


8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
# File 'gc.c', line 8269

static VALUE
wmap_size(VALUE self)
{
    struct weakmap *w;
    st_index_t n;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    n = w->wmap2obj->num_entries;
#if SIZEOF_ST_INDEX_T <= SIZEOF_LONG
    return ULONG2NUM(n);
#else
    return ULL2NUM(n);
#endif
}

#member?(key) ⇒ Boolean

Returns true if key is registered


8263
8264
8265
8266
8267
# File 'gc.c', line 8263

static VALUE
wmap_has_key(VALUE self, VALUE key)
{
    return NIL_P(wmap_aref(self, key)) ? Qfalse : Qtrue;
}

#sizeObject


8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
# File 'gc.c', line 8269

static VALUE
wmap_size(VALUE self)
{
    struct weakmap *w;
    st_index_t n;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    n = w->wmap2obj->num_entries;
#if SIZEOF_ST_INDEX_T <= SIZEOF_LONG
    return ULONG2NUM(n);
#else
    return ULL2NUM(n);
#endif
}

#valuesObject

Iterates over values and objects in a weakly referenced object


8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
# File 'gc.c', line 8195

static VALUE
wmap_values(VALUE self)
{
    struct weakmap *w;
    struct wmap_iter_arg args;

    TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
    args.objspace = &rb_objspace;
    args.value = rb_ary_new();
    st_foreach(w->wmap2obj, wmap_values_i, (st_data_t)&args);
    return args.value;
}