Class: SwissHash::Hash
- Inherits:
-
Object
- Object
- SwissHash::Hash
- Includes:
- Enumerable
- Defined in:
- lib/swiss_hash.rb,
ext/swiss_hash/swiss_hash.c
Instance Method Summary collapse
- #==(other) ⇒ Object
- #[](key) ⇒ Object
- #[]=(key, value) ⇒ Object
- #__compact_storage! ⇒ Object
- #assoc(object) ⇒ Object
- #clear ⇒ Object
- #compact ⇒ Object
- #compact! ⇒ Object
- #compact_storage! ⇒ Object
- #count(*args, &block) ⇒ Object
- #delete(key) ⇒ Object
- #delete_if ⇒ Object
- #dig(key, *rest) ⇒ Object
- #each ⇒ Object
- #each_key ⇒ Object
- #each_pair ⇒ Object
- #each_value ⇒ Object
- #empty? ⇒ Boolean
- #eql?(other) ⇒ Boolean
- #except(*args) ⇒ Object
- #fetch(*args) ⇒ Object
- #fetch_values(*args) ⇒ Object
- #filter ⇒ Object
- #filter! ⇒ Object
- #flatten(level = 1) ⇒ Object
- #has_key?(key) ⇒ Boolean
- #has_value?(value) ⇒ Boolean
- #hash ⇒ Object
- #include?(key) ⇒ Boolean
- #initialize(*args) ⇒ Object constructor
- #initialize_copy(original) ⇒ Object
- #inspect ⇒ Object (also: #to_s)
- #invert ⇒ Object
- #keep_if ⇒ Object
- #key(value) ⇒ Object
- #key?(key) ⇒ Boolean
- #keys ⇒ Object
- #length ⇒ Object
- #member?(key) ⇒ Boolean
- #merge(*args) ⇒ Object
- #merge!(*args) ⇒ Object
- #rassoc(object) ⇒ Object
- #reject ⇒ Object
- #reject! ⇒ Object
- #replace(other) ⇒ Object
- #select ⇒ Object
- #select! ⇒ Object
- #shift ⇒ Object
- #size ⇒ Object
- #slice(*args) ⇒ Object
- #stats ⇒ Object
- #store(key, value) ⇒ Object
- #to_a ⇒ Object
- #to_h ⇒ Object
- #to_sh ⇒ Object
- #transform_keys ⇒ Object
- #transform_keys! ⇒ Object
- #transform_values ⇒ Object
- #transform_values! ⇒ Object
- #update(*args) ⇒ Object
- #value?(value) ⇒ Boolean
- #values ⇒ Object
- #values_at(*args) ⇒ Object
Constructor Details
#initialize(*args) ⇒ Object
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 |
# File 'ext/swiss_hash/swiss_hash.c', line 1015
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
#==(other) ⇒ Object
36 37 38 39 |
# File 'lib/swiss_hash.rb', line 36 def ==(other) other = other.to_h if other.is_a?(self.class) to_h == other end |
#[](key) ⇒ Object
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 |
# File 'ext/swiss_hash/swiss_hash.c', line 1069
static VALUE swiss_hash_aref(VALUE self, VALUE key) {
SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
VALUE *val;
if (FIXNUM_P(key)) {
val = swiss_lookup_hashed(sh, key, hash_fixnum(key), 1);
} else {
val = swiss_lookup(sh, key);
}
return val ? *val : Qnil;
}
|
#[]=(key, value) ⇒ Object
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 |
# File 'ext/swiss_hash/swiss_hash.c', line 1058
static VALUE swiss_hash_aset(VALUE self, VALUE key, VALUE value) {
SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
if (FIXNUM_P(key)) {
return swiss_insert_fixnum(sh, key, value);
}
if (RB_UNLIKELY(!SYMBOL_P(key))) {
key = prepare_key(key);
}
return swiss_insert(sh, key, value);
}
|
#__compact_storage! ⇒ Object
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 |
# File 'ext/swiss_hash/swiss_hash.c', line 1691
static VALUE swiss_hash_compact_storage_bang(VALUE self) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
if (sh->tombstone_count > 0) {
swiss_compact(sh);
}
return self;
}
|
#assoc(object) ⇒ Object
1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 |
# File 'ext/swiss_hash/swiss_hash.c', line 1444
static VALUE swiss_hash_assoc(VALUE self, VALUE object) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
if (RTEST(rb_equal(sh->slots[i].key, object))) {
VALUE ary = rb_ary_new_capa(2);
rb_ary_push(ary, sh->slots[i].key);
rb_ary_push(ary, sh->slots[i].value);
return ary;
}
}
}
return Qnil;
}
|
#clear ⇒ Object
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 |
# File 'ext/swiss_hash/swiss_hash.c', line 1097
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
1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 |
# File 'ext/swiss_hash/swiss_hash.c', line 1607
static VALUE swiss_hash_compact(VALUE self) {
SwissHash *src;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, src);
VALUE result = swiss_hash_new_like(self, src->size);
SwissHash *dst = (SwissHash *)RTYPEDDATA_DATA(result);
for (size_t i = 0; i < src->capacity; i++) {
uint8_t c = src->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED && !NIL_P(src->slots[i].value)) {
swiss_hash_store_prepared(dst, src->slots[i].key, src->slots[i].value);
}
}
return result;
}
|
#compact! ⇒ Object
1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 |
# File 'ext/swiss_hash/swiss_hash.c', line 1623
static VALUE swiss_hash_compact_bang(VALUE self) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
size_t old_size = sh->size;
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED && NIL_P(sh->slots[i].value)) {
VALUE key = sh->slots[i].key;
swiss_delete(sh, key);
}
}
return sh->size == old_size ? Qnil : self;
}
|
#compact_storage! ⇒ Object
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 |
# File 'ext/swiss_hash/swiss_hash.c', line 1691
static VALUE swiss_hash_compact_storage_bang(VALUE self) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
if (sh->tombstone_count > 0) {
swiss_compact(sh);
}
return self;
}
|
#count(*args, &block) ⇒ Object
10 11 12 13 14 |
# File 'lib/swiss_hash.rb', line 10 def count(*args, &block) return size if args.empty? && !block each.count(*args, &block) end |
#delete(key) ⇒ Object
1080 1081 1082 1083 |
# File 'ext/swiss_hash/swiss_hash.c', line 1080
static VALUE swiss_hash_delete(VALUE self, VALUE key) {
SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
return swiss_delete(sh, key);
}
|
#delete_if ⇒ Object
1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 |
# File 'ext/swiss_hash/swiss_hash.c', line 1507
static VALUE swiss_hash_delete_if(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
VALUE key = sh->slots[i].key;
VALUE value = sh->slots[i].value;
if (RTEST(rb_yield_values(2, key, value))) {
swiss_delete(sh, key);
}
}
}
return self;
}
|
#dig(key, *rest) ⇒ Object
16 17 18 19 20 21 |
# File 'lib/swiss_hash.rb', line 16 def dig(key, *rest) value = self[key] return value if rest.empty? || value.nil? value.dig(*rest) end |
#each ⇒ Object
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 |
# File 'ext/swiss_hash/swiss_hash.c', line 1110
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;
}
|
#each_key ⇒ Object
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 |
# File 'ext/swiss_hash/swiss_hash.c', line 1154
static VALUE swiss_hash_each_key(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(sh->slots[i].key);
}
}
return self;
}
|
#each_pair ⇒ Object
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 |
# File 'ext/swiss_hash/swiss_hash.c', line 1110
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;
}
|
#each_value ⇒ Object
1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 |
# File 'ext/swiss_hash/swiss_hash.c', line 1170
static VALUE swiss_hash_each_value(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(sh->slots[i].value);
}
}
return self;
}
|
#empty? ⇒ Boolean
1091 1092 1093 1094 1095 |
# File 'ext/swiss_hash/swiss_hash.c', line 1091
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;
}
|
#eql?(other) ⇒ Boolean
41 42 43 44 |
# File 'lib/swiss_hash.rb', line 41 def eql?(other) other = other.to_h if other.is_a?(self.class) to_h.eql?(other) end |
#except(*args) ⇒ Object
1420 1421 1422 1423 1424 1425 1426 |
# File 'ext/swiss_hash/swiss_hash.c', line 1420
static VALUE swiss_hash_except(int argc, VALUE *argv, VALUE self) {
VALUE result = rb_obj_dup(self);
for (int i = 0; i < argc; i++) {
swiss_hash_delete(result, argv[i]);
}
return result;
}
|
#fetch(*args) ⇒ Object
1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 |
# File 'ext/swiss_hash/swiss_hash.c', line 1219
static VALUE swiss_hash_fetch(int argc, VALUE *argv, VALUE self) {
VALUE key;
VALUE default_value;
rb_scan_args(argc, argv, "11", &key, &default_value);
SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
VALUE *val = swiss_lookup(sh, key);
if (val) {
return *val;
}
if (rb_block_given_p()) {
if (argc == 2) {
rb_warn("block supersedes default value argument");
}
return rb_yield(key);
}
if (argc == 2) {
return default_value;
}
VALUE inspected = rb_inspect(key);
VALUE message = rb_str_plus(rb_str_new_cstr("key not found: "), inspected);
rb_exc_raise(rb_exc_new_str(rb_eKeyError, message));
return Qnil;
}
|
#fetch_values(*args) ⇒ Object
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 |
# File 'ext/swiss_hash/swiss_hash.c', line 1385
static VALUE swiss_hash_fetch_values(int argc, VALUE *argv, VALUE self) {
SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
VALUE ary = rb_ary_new_capa((long)argc);
int has_block = rb_block_given_p();
for (int i = 0; i < argc; i++) {
VALUE *val = swiss_lookup(sh, argv[i]);
if (val) {
rb_ary_push(ary, *val);
} else if (has_block) {
rb_ary_push(ary, rb_yield(argv[i]));
} else {
VALUE key_argv[1] = {argv[i]};
rb_ary_push(ary, swiss_hash_fetch(1, key_argv, self));
}
}
return ary;
}
|
#filter ⇒ Object
1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 |
# File 'ext/swiss_hash/swiss_hash.c', line 1547
static VALUE swiss_hash_select(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
SwissHash *src;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, src);
VALUE result = swiss_hash_new_like(self, src->size);
SwissHash *dst = (SwissHash *)RTYPEDDATA_DATA(result);
for (size_t i = 0; i < src->capacity; i++) {
uint8_t c = src->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
VALUE key = src->slots[i].key;
VALUE value = src->slots[i].value;
if (RTEST(rb_yield_values(2, key, value))) {
swiss_hash_store_prepared(dst, key, value);
}
}
}
return result;
}
|
#filter! ⇒ Object
1591 1592 1593 1594 1595 1596 1597 |
# File 'ext/swiss_hash/swiss_hash.c', line 1591
static VALUE swiss_hash_select_bang(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
size_t old_size = ((SwissHash *)RTYPEDDATA_DATA(self))->size;
swiss_hash_keep_if(self);
return ((SwissHash *)RTYPEDDATA_DATA(self))->size == old_size ? Qnil : self;
}
|
#flatten(level = 1) ⇒ Object
32 33 34 |
# File 'lib/swiss_hash.rb', line 32 def flatten(level = 1) to_a.flatten(level) end |
#has_key?(key) ⇒ Boolean
1292 1293 1294 1295 1296 |
# File 'ext/swiss_hash/swiss_hash.c', line 1292
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;
}
|
#has_value?(value) ⇒ Boolean
1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 |
# File 'ext/swiss_hash/swiss_hash.c', line 1260
static VALUE swiss_hash_value_p(VALUE self, VALUE value) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
if (RTEST(rb_equal(sh->slots[i].value, value))) {
return Qtrue;
}
}
}
return Qfalse;
}
|
#hash ⇒ Object
46 47 48 |
# File 'lib/swiss_hash.rb', line 46 def hash to_h.hash end |
#include?(key) ⇒ Boolean
1292 1293 1294 1295 1296 |
# File 'ext/swiss_hash/swiss_hash.c', line 1292
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;
}
|
#initialize_copy(original) ⇒ Object
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 |
# File 'ext/swiss_hash/swiss_hash.c', line 1028
static VALUE swiss_hash_initialize_copy(VALUE self, VALUE original) {
if (self == original) {
return self;
}
SwissHash *src;
SwissHash *dst;
TypedData_Get_Struct(original, SwissHash, &swiss_hash_type, src);
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, dst);
if (dst->ctrl || dst->slots) {
swiss_free_arrays(dst);
}
if (!src->ctrl || !src->slots) {
swiss_init(dst, 16);
return self;
}
swiss_init(dst, src->capacity);
memcpy(dst->ctrl, src->ctrl, src->capacity * sizeof(uint8_t));
memcpy(dst->slots, src->slots, src->capacity * sizeof(Slot));
dst->size = src->size;
dst->growth_left = src->growth_left;
dst->tombstone_count = src->tombstone_count;
dst->mutating = 0;
return self;
}
|
#inspect ⇒ Object Also known as: to_s
50 51 52 53 |
# File 'lib/swiss_hash.rb', line 50 def inspect s = stats "#<SwissHash::Hash size=#{s[:size]} capacity=#{s[:capacity]} load=#{(s[:load_factor] * 100).round(1)}%>" end |
#invert ⇒ Object
1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 |
# File 'ext/swiss_hash/swiss_hash.c', line 1428
static VALUE swiss_hash_invert(VALUE self) {
SwissHash *src;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, src);
VALUE result = swiss_hash_new_like(self, src->size);
SwissHash *dst = (SwissHash *)RTYPEDDATA_DATA(result);
for (size_t i = 0; i < src->capacity; i++) {
uint8_t c = src->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
swiss_hash_store_prepared(dst, src->slots[i].value, src->slots[i].key);
}
}
return result;
}
|
#keep_if ⇒ Object
1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 |
# File 'ext/swiss_hash/swiss_hash.c', line 1527
static VALUE swiss_hash_keep_if(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
VALUE key = sh->slots[i].key;
VALUE value = sh->slots[i].value;
if (!RTEST(rb_yield_values(2, key, value))) {
swiss_delete(sh, key);
}
}
}
return self;
}
|
#key(value) ⇒ Object
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 |
# File 'ext/swiss_hash/swiss_hash.c', line 1276
static VALUE swiss_hash_key_for_value(VALUE self, VALUE value) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
if (RTEST(rb_equal(sh->slots[i].value, value))) {
return sh->slots[i].key;
}
}
}
return Qnil;
}
|
#key?(key) ⇒ Boolean
1292 1293 1294 1295 1296 |
# File 'ext/swiss_hash/swiss_hash.c', line 1292
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;
}
|
#keys ⇒ Object
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 |
# File 'ext/swiss_hash/swiss_hash.c', line 1126
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;
}
|
#length ⇒ Object
1085 1086 1087 1088 1089 |
# File 'ext/swiss_hash/swiss_hash.c', line 1085
static VALUE swiss_hash_size(VALUE self) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
return SIZET2NUM(sh->size);
}
|
#member?(key) ⇒ Boolean
1292 1293 1294 1295 1296 |
# File 'ext/swiss_hash/swiss_hash.c', line 1292
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;
}
|
#merge(*args) ⇒ Object
1368 1369 1370 1371 1372 |
# File 'ext/swiss_hash/swiss_hash.c', line 1368
static VALUE swiss_hash_merge(int argc, VALUE *argv, VALUE self) {
VALUE copy = rb_obj_dup(self);
swiss_hash_merge_bang(argc, argv, copy);
return copy;
}
|
#merge!(*args) ⇒ Object
1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 |
# File 'ext/swiss_hash/swiss_hash.c', line 1357
static VALUE swiss_hash_merge_bang(int argc, VALUE *argv, VALUE self) {
SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
MergeCtx ctx = {self, sh, rb_block_given_p()};
for (int i = 0; i < argc; i++) {
swiss_hash_merge_one(&ctx, argv[i]);
}
return self;
}
|
#rassoc(object) ⇒ Object
1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 |
# File 'ext/swiss_hash/swiss_hash.c', line 1463
static VALUE swiss_hash_rassoc(VALUE self, VALUE object) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
if (RTEST(rb_equal(sh->slots[i].value, object))) {
VALUE ary = rb_ary_new_capa(2);
rb_ary_push(ary, sh->slots[i].key);
rb_ary_push(ary, sh->slots[i].value);
return ary;
}
}
}
return Qnil;
}
|
#reject ⇒ Object
1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 |
# File 'ext/swiss_hash/swiss_hash.c', line 1569
static VALUE swiss_hash_reject(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
SwissHash *src;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, src);
VALUE result = swiss_hash_new_like(self, src->size);
SwissHash *dst = (SwissHash *)RTYPEDDATA_DATA(result);
for (size_t i = 0; i < src->capacity; i++) {
uint8_t c = src->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
VALUE key = src->slots[i].key;
VALUE value = src->slots[i].value;
if (!RTEST(rb_yield_values(2, key, value))) {
swiss_hash_store_prepared(dst, key, value);
}
}
}
return result;
}
|
#reject! ⇒ Object
1599 1600 1601 1602 1603 1604 1605 |
# File 'ext/swiss_hash/swiss_hash.c', line 1599
static VALUE swiss_hash_reject_bang(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
size_t old_size = ((SwissHash *)RTYPEDDATA_DATA(self))->size;
swiss_hash_delete_if(self);
return ((SwissHash *)RTYPEDDATA_DATA(self))->size == old_size ? Qnil : self;
}
|
#replace(other) ⇒ Object
1374 1375 1376 1377 1378 1379 |
# File 'ext/swiss_hash/swiss_hash.c', line 1374
static VALUE swiss_hash_replace(VALUE self, VALUE other) {
swiss_hash_clear(self);
VALUE argv[1] = {other};
swiss_hash_merge_bang(1, argv, self);
return self;
}
|
#select ⇒ Object
1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 |
# File 'ext/swiss_hash/swiss_hash.c', line 1547
static VALUE swiss_hash_select(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
SwissHash *src;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, src);
VALUE result = swiss_hash_new_like(self, src->size);
SwissHash *dst = (SwissHash *)RTYPEDDATA_DATA(result);
for (size_t i = 0; i < src->capacity; i++) {
uint8_t c = src->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
VALUE key = src->slots[i].key;
VALUE value = src->slots[i].value;
if (RTEST(rb_yield_values(2, key, value))) {
swiss_hash_store_prepared(dst, key, value);
}
}
}
return result;
}
|
#select! ⇒ Object
1591 1592 1593 1594 1595 1596 1597 |
# File 'ext/swiss_hash/swiss_hash.c', line 1591
static VALUE swiss_hash_select_bang(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
size_t old_size = ((SwissHash *)RTYPEDDATA_DATA(self))->size;
swiss_hash_keep_if(self);
return ((SwissHash *)RTYPEDDATA_DATA(self))->size == old_size ? Qnil : self;
}
|
#shift ⇒ Object
1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 |
# File 'ext/swiss_hash/swiss_hash.c', line 1482
static VALUE swiss_hash_shift(VALUE self) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
VALUE key = sh->slots[i].key;
VALUE value = sh->slots[i].value;
sh->ctrl[i] = CTRL_DELETED;
sh->slots[i].key = Qnil;
sh->slots[i].value = Qnil;
sh->size--;
sh->tombstone_count++;
VALUE ary = rb_ary_new_capa(2);
rb_ary_push(ary, key);
rb_ary_push(ary, value);
return ary;
}
}
return Qnil;
}
|
#size ⇒ Object
1085 1086 1087 1088 1089 |
# File 'ext/swiss_hash/swiss_hash.c', line 1085
static VALUE swiss_hash_size(VALUE self) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
return SIZET2NUM(sh->size);
}
|
#slice(*args) ⇒ Object
1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 |
# File 'ext/swiss_hash/swiss_hash.c', line 1405
static VALUE swiss_hash_slice(int argc, VALUE *argv, VALUE self) {
SwissHash *src = (SwissHash *)RTYPEDDATA_DATA(self);
VALUE result = swiss_hash_new_like(self, (size_t)argc);
SwissHash *dst = (SwissHash *)RTYPEDDATA_DATA(result);
for (int i = 0; i < argc; i++) {
VALUE *val = swiss_lookup(src, argv[i]);
if (val) {
swiss_hash_store_prepared(dst, argv[i], *val);
}
}
return result;
}
|
#stats ⇒ Object
1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 |
# File 'ext/swiss_hash/swiss_hash.c', line 1702
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("SWAR"));
#endif
rb_hash_aset(hash, ID2SYM(rb_intern("layout")), rb_str_new_cstr("hybrid"));
return hash;
}
|
#store(key, value) ⇒ Object
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 |
# File 'ext/swiss_hash/swiss_hash.c', line 1058
static VALUE swiss_hash_aset(VALUE self, VALUE key, VALUE value) {
SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
if (FIXNUM_P(key)) {
return swiss_insert_fixnum(sh, key, value);
}
if (RB_UNLIKELY(!SYMBOL_P(key))) {
key = prepare_key(key);
}
return swiss_insert(sh, key, value);
}
|
#to_a ⇒ Object
1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 |
# File 'ext/swiss_hash/swiss_hash.c', line 1201
static VALUE swiss_hash_to_a(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) {
VALUE pair = rb_ary_new_capa(2);
rb_ary_push(pair, sh->slots[i].key);
rb_ary_push(pair, sh->slots[i].value);
rb_ary_push(ary, pair);
}
}
return ary;
}
|
#to_h ⇒ Object
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 |
# File 'ext/swiss_hash/swiss_hash.c', line 1186
static VALUE swiss_hash_to_h(VALUE self) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
VALUE hash = rb_hash_new();
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
rb_hash_aset(hash, sh->slots[i].key, sh->slots[i].value);
}
}
return hash;
}
|
#to_sh ⇒ Object
1381 1382 1383 |
# File 'ext/swiss_hash/swiss_hash.c', line 1381 static VALUE swiss_hash_to_sh(VALUE self) { return rb_obj_dup(self); } |
#transform_keys ⇒ Object
1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 |
# File 'ext/swiss_hash/swiss_hash.c', line 1673
static VALUE swiss_hash_transform_keys(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
SwissHash *src;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, src);
VALUE result = swiss_hash_new_like(self, src->size);
SwissHash *dst = (SwissHash *)RTYPEDDATA_DATA(result);
for (size_t i = 0; i < src->capacity; i++) {
uint8_t c = src->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
swiss_hash_store_prepared(dst, rb_yield(src->slots[i].key), src->slots[i].value);
}
}
return result;
}
|
#transform_keys! ⇒ Object
23 24 25 26 27 28 29 30 |
# File 'lib/swiss_hash.rb', line 23 def transform_keys! return enum_for(:transform_keys!) unless block_given? pairs = to_a clear pairs.each { |key, value| self[yield(key)] = value } self end |
#transform_values ⇒ Object
1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 |
# File 'ext/swiss_hash/swiss_hash.c', line 1639
static VALUE swiss_hash_transform_values(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
SwissHash *src;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, src);
VALUE result = swiss_hash_new_like(self, src->size);
SwissHash *dst = (SwissHash *)RTYPEDDATA_DATA(result);
for (size_t i = 0; i < src->capacity; i++) {
uint8_t c = src->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
swiss_hash_store_prepared(dst, src->slots[i].key, rb_yield(src->slots[i].value));
}
}
return result;
}
|
#transform_values! ⇒ Object
1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 |
# File 'ext/swiss_hash/swiss_hash.c', line 1657
static VALUE swiss_hash_transform_values_bang(VALUE self) {
RETURN_ENUMERATOR(self, 0, 0);
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
sh->slots[i].value = rb_yield(sh->slots[i].value);
}
}
return self;
}
|
#update(*args) ⇒ Object
1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 |
# File 'ext/swiss_hash/swiss_hash.c', line 1357
static VALUE swiss_hash_merge_bang(int argc, VALUE *argv, VALUE self) {
SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
MergeCtx ctx = {self, sh, rb_block_given_p()};
for (int i = 0; i < argc; i++) {
swiss_hash_merge_one(&ctx, argv[i]);
}
return self;
}
|
#value?(value) ⇒ Boolean
1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 |
# File 'ext/swiss_hash/swiss_hash.c', line 1260
static VALUE swiss_hash_value_p(VALUE self, VALUE value) {
SwissHash *sh;
TypedData_Get_Struct(self, SwissHash, &swiss_hash_type, sh);
for (size_t i = 0; i < sh->capacity; i++) {
uint8_t c = sh->ctrl[i];
if (c != CTRL_EMPTY && c != CTRL_DELETED) {
if (RTEST(rb_equal(sh->slots[i].value, value))) {
return Qtrue;
}
}
}
return Qfalse;
}
|
#values ⇒ Object
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 |
# File 'ext/swiss_hash/swiss_hash.c', line 1140
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;
}
|
#values_at(*args) ⇒ Object
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 |
# File 'ext/swiss_hash/swiss_hash.c', line 1248
static VALUE swiss_hash_values_at(int argc, VALUE *argv, VALUE self) {
SwissHash *sh = (SwissHash *)RTYPEDDATA_DATA(self);
VALUE ary = rb_ary_new_capa((long)argc);
for (int i = 0; i < argc; i++) {
VALUE *val = swiss_lookup(sh, argv[i]);
rb_ary_push(ary, val ? *val : Qnil);
}
return ary;
}
|