Class: SwissHash::Hash

Inherits:
Object
  • Object
show all
Defined in:
lib/swiss_hash.rb,
ext/swiss_hash/swiss_hash.c

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object



740
741
742
743
744
745
746
747
748
749
750
751
# File 'ext/swiss_hash/swiss_hash.c', line 740

static VALUE swiss_hash_initialize(int argc, VALUE *argv, VALUE self) {
    VALUE capacity_val;
    rb_scan_args(argc, argv, "01", &capacity_val);

    SwissHash *sh;
    TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);

    size_t capacity = NIL_P(capacity_val) ? 16 : NUM2SIZET(capacity_val);
    swiss_init(sh, capacity);

    return self;
}

Instance Method Details

#[](key) ⇒ Object



761
762
763
764
765
# File 'ext/swiss_hash/swiss_hash.c', line 761

static VALUE swiss_hash_aref(VALUE self, VALUE key) {
    SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
    VALUE *val = swiss_lookup(sh, key);
    return val ? *val : Qnil;
}

#[]=(key, value) ⇒ Object



753
754
755
756
757
758
759
# File 'ext/swiss_hash/swiss_hash.c', line 753

static VALUE swiss_hash_aset(VALUE self, VALUE key, VALUE value) {
    SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
    if (RB_UNLIKELY(!(FIXNUM_P(key) || SYMBOL_P(key)))) {
        key = prepare_key(key);
    }
    return swiss_insert(sh, key, value);
}

#clearObject



784
785
786
787
788
789
790
791
792
793
794
795
# File 'ext/swiss_hash/swiss_hash.c', line 784

static VALUE swiss_hash_clear(VALUE self) {
    SwissHash *sh;
    TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);

    memset(sh->ctrl, CTRL_EMPTY, sh->capacity);
    memset(sh->slots, 0, sh->capacity * sizeof(Slot));
    sh->size = 0;
    sh->growth_left = sh->capacity * MAX_LOAD_NUM / MAX_LOAD_DEN;
    sh->tombstone_count = 0;

    return self;
}

#compact!Object



847
848
849
850
851
852
853
854
855
856
# File 'ext/swiss_hash/swiss_hash.c', line 847

static VALUE swiss_hash_compact_bang(VALUE self) {
    SwissHash *sh;
    TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);

    if (sh->tombstone_count > 0) {
        swiss_compact(sh);
    }

    return self;
}

#delete(key) ⇒ Object



767
768
769
770
# File 'ext/swiss_hash/swiss_hash.c', line 767

static VALUE swiss_hash_delete(VALUE self, VALUE key) {
    SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
    return swiss_delete(sh, key);
}

#eachObject



797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
# File 'ext/swiss_hash/swiss_hash.c', line 797

static VALUE swiss_hash_each(VALUE self) {
    SwissHash *sh;
    TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);

    RETURN_ENUMERATOR(self, 0, 0);

    for (size_t i = 0; i < sh->capacity; i++) {
        uint8_t c = sh->ctrl[i];
        if (c != CTRL_EMPTY && c != CTRL_DELETED) {
            rb_yield_values(2, sh->slots[i].key, sh->slots[i].value);
        }
    }

    return self;
}

#empty?Boolean

Returns:

  • (Boolean)


778
779
780
781
782
# File 'ext/swiss_hash/swiss_hash.c', line 778

static VALUE swiss_hash_empty_p(VALUE self) {
    SwissHash *sh;
    TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
    return sh->size == 0 ? Qtrue : Qfalse;
}

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


841
842
843
844
845
# File 'ext/swiss_hash/swiss_hash.c', line 841

static VALUE swiss_hash_key_p(VALUE self, VALUE key) {
    SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
    VALUE *val = swiss_lookup(sh, key);
    return val ? Qtrue : Qfalse;
}

#include?(key) ⇒ Boolean

Returns:

  • (Boolean)


841
842
843
844
845
# File 'ext/swiss_hash/swiss_hash.c', line 841

static VALUE swiss_hash_key_p(VALUE self, VALUE key) {
    SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
    VALUE *val = swiss_lookup(sh, key);
    return val ? Qtrue : Qfalse;
}

#inspectObject Also known as: to_s



22
23
24
25
# File 'lib/swiss_hash.rb', line 22

def inspect
  s = stats
  "#<SwissHash::Hash size=#{s[:size]} capacity=#{s[:capacity]} load=#{(s[:load_factor] * 100).round(1)}%>"
end

#key?(key) ⇒ Boolean

Returns:

  • (Boolean)


841
842
843
844
845
# File 'ext/swiss_hash/swiss_hash.c', line 841

static VALUE swiss_hash_key_p(VALUE self, VALUE key) {
    SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
    VALUE *val = swiss_lookup(sh, key);
    return val ? Qtrue : Qfalse;
}

#keysObject



813
814
815
816
817
818
819
820
821
822
823
824
825
# File 'ext/swiss_hash/swiss_hash.c', line 813

static VALUE swiss_hash_keys(VALUE self) {
    SwissHash *sh;
    TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
    VALUE ary = rb_ary_new_capa(sh->size);

    for (size_t i = 0; i < sh->capacity; i++) {
        uint8_t c = sh->ctrl[i];
        if (c != CTRL_EMPTY && c != CTRL_DELETED) {
            rb_ary_push(ary, sh->slots[i].key);
        }
    }
    return ary;
}

#lengthObject



772
773
774
775
776
# File 'ext/swiss_hash/swiss_hash.c', line 772

static VALUE swiss_hash_size(VALUE self) {
    SwissHash *sh;
    TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
    return SIZET2NUM(sh->size);
}

#merge!(other) ⇒ Object Also known as: update



10
11
12
13
# File 'lib/swiss_hash.rb', line 10

def merge!(other)
  other.each { |k, v| self[k] = v }
  self
end

#sizeObject Also known as: count



772
773
774
775
776
# File 'ext/swiss_hash/swiss_hash.c', line 772

static VALUE swiss_hash_size(VALUE self) {
    SwissHash *sh;
    TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
    return SIZET2NUM(sh->size);
}

#statsObject



858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
# File 'ext/swiss_hash/swiss_hash.c', line 858

static VALUE swiss_hash_stats(VALUE self) {
    SwissHash *sh;
    TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);

    double load = sh->capacity > 0 ? (double)sh->size / sh->capacity : 0.0;

    VALUE hash = rb_hash_new();
    rb_hash_aset(hash, ID2SYM(rb_intern("capacity")), SIZET2NUM(sh->capacity));
    rb_hash_aset(hash, ID2SYM(rb_intern("size")), SIZET2NUM(sh->size));
    rb_hash_aset(hash, ID2SYM(rb_intern("num_groups")), SIZET2NUM(sh->num_groups));
    rb_hash_aset(hash, ID2SYM(rb_intern("load_factor")), DBL2NUM(load));
    rb_hash_aset(hash, ID2SYM(rb_intern("memory_bytes")), SIZET2NUM(swiss_hash_memsize(sh)));
    rb_hash_aset(hash, ID2SYM(rb_intern("growth_left")), SIZET2NUM(sh->growth_left));
    rb_hash_aset(hash, ID2SYM(rb_intern("tombstones")), SIZET2NUM(sh->tombstone_count));

#ifdef SWISS_USE_SSE2
    rb_hash_aset(hash, ID2SYM(rb_intern("simd")), rb_str_new_cstr("SSE2"));
#elif defined(SWISS_USE_NEON)
    rb_hash_aset(hash, ID2SYM(rb_intern("simd")), rb_str_new_cstr("NEON"));
#else
    rb_hash_aset(hash, ID2SYM(rb_intern("simd")), rb_str_new_cstr("portable/SWAR"));
#endif
    rb_hash_aset(hash, ID2SYM(rb_intern("layout")), rb_str_new_cstr("hybrid"));

    return hash;
}

#store(key, value) ⇒ Object



753
754
755
756
757
758
759
# File 'ext/swiss_hash/swiss_hash.c', line 753

static VALUE swiss_hash_aset(VALUE self, VALUE key, VALUE value) {
    SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
    if (RB_UNLIKELY(!(FIXNUM_P(key) || SYMBOL_P(key)))) {
        key = prepare_key(key);
    }
    return swiss_insert(sh, key, value);
}

#to_hObject



16
17
18
19
20
# File 'lib/swiss_hash.rb', line 16

def to_h
  hash = {}
  each { |k, v| hash[k] = v }
  hash
end

#valuesObject



827
828
829
830
831
832
833
834
835
836
837
838
839
# File 'ext/swiss_hash/swiss_hash.c', line 827

static VALUE swiss_hash_values(VALUE self) {
    SwissHash *sh;
    TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
    VALUE ary = rb_ary_new_capa(sh->size);

    for (size_t i = 0; i < sh->capacity; i++) {
        uint8_t c = sh->ctrl[i];
        if (c != CTRL_EMPTY && c != CTRL_DELETED) {
            rb_ary_push(ary, sh->slots[i].value);
        }
    }
    return ary;
}