Skip to content

Commit 9250ece

Browse files
committed
set.c: Store set_table->bins at the end of set_table->entries
This saves one pointer in `struct set_table`, which would allow `Set` objects to still fit in 80B TypedData slots even if RTypedData goes from 32B to 40B large.
1 parent fccd96c commit 9250ece

3 files changed

Lines changed: 56 additions & 44 deletions

File tree

internal/set_table.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@ struct set_table {
1515
const struct st_hash_type *type;
1616
/* Number of entries currently in the table. */
1717
st_index_t num_entries;
18-
/* Array of bins used for access by keys. */
19-
st_index_t *bins;
18+
2019
/* Start and bound index of entries in array entries.
2120
entries_starts and entries_bound are in interval
2221
[0,allocated_entries]. */
2322
st_index_t entries_start, entries_bound;
24-
/* Array of size 2^entry_power. */
23+
24+
/**
25+
* Array of size 2^entry_power.
26+
* Followed by st_index_t *bins, Array of bins used for access by keys.
27+
*/
2528
set_table_entry *entries;
2629
};
2730

set.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ set_mark(void *ptr)
139139
static void
140140
set_free_embedded(struct set_object *sobj)
141141
{
142-
free((&sobj->table)->bins);
143142
free((&sobj->table)->entries);
144143
}
145144

st.c

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2395,18 +2395,40 @@ set_get_allocated_entries(const set_table *tab)
23952395
return ((st_index_t) 1)<<tab->entry_power;
23962396
}
23972397

2398+
static inline size_t
2399+
set_allocated_entries_size(const set_table *tab)
2400+
{
2401+
return set_get_allocated_entries(tab) * sizeof(set_table_entry);
2402+
}
2403+
23982404
/* Return size of the allocated bins of table TAB. */
23992405
static inline st_index_t
24002406
set_bins_size(const set_table *tab)
24012407
{
24022408
return features[tab->entry_power].bins_words * sizeof (st_index_t);
24032409
}
24042410

2411+
static inline bool
2412+
set_has_bins(const set_table *tab)
2413+
{
2414+
return tab->entry_power > MAX_POWER2_FOR_TABLES_WITHOUT_BINS;
2415+
}
2416+
2417+
static inline st_index_t *
2418+
set_bins_ptr(const set_table *tab)
2419+
{
2420+
if (set_has_bins(tab)) {
2421+
return (st_index_t *)(((char *)tab->entries) + set_allocated_entries_size(tab));
2422+
}
2423+
2424+
return NULL;
2425+
}
2426+
24052427
/* Mark all bins of table TAB as empty. */
24062428
static void
24072429
set_initialize_bins(set_table *tab)
24082430
{
2409-
memset(tab->bins, 0, set_bins_size(tab));
2431+
memset(set_bins_ptr(tab), 0, set_bins_size(tab));
24102432
}
24112433

24122434
/* Make table TAB empty. */
@@ -2415,7 +2437,7 @@ set_make_tab_empty(set_table *tab)
24152437
{
24162438
tab->num_entries = 0;
24172439
tab->entries_start = tab->entries_bound = 0;
2418-
if (tab->bins != NULL)
2440+
if (set_bins_ptr(tab) != NULL)
24192441
set_initialize_bins(tab);
24202442
}
24212443

@@ -2443,13 +2465,13 @@ set_init_existing_table_with_size(set_table *tab, const struct st_hash_type *typ
24432465
tab->entry_power = n;
24442466
tab->bin_power = features[n].bin_power;
24452467
tab->size_ind = features[n].size_ind;
2446-
if (n <= MAX_POWER2_FOR_TABLES_WITHOUT_BINS)
2447-
tab->bins = NULL;
2448-
else {
2449-
tab->bins = (st_index_t *) malloc(set_bins_size(tab));
2468+
2469+
size_t memsize = 0;
2470+
if (set_has_bins(tab)) {
2471+
memsize += set_bins_size(tab);
24502472
}
2451-
tab->entries = (set_table_entry *) malloc(set_get_allocated_entries(tab)
2452-
* sizeof(set_table_entry));
2473+
memsize += set_get_allocated_entries(tab) * sizeof(set_table_entry);
2474+
tab->entries = (set_table_entry *)malloc(memsize);
24532475
set_make_tab_empty(tab);
24542476
tab->rebuilds_num = 0;
24552477
return tab;
@@ -2499,7 +2521,6 @@ set_table_clear(set_table *tab)
24992521
void
25002522
set_free_table(set_table *tab)
25012523
{
2502-
free(tab->bins);
25032524
free(tab->entries);
25042525
free(tab);
25052526
}
@@ -2509,7 +2530,7 @@ size_t
25092530
set_memsize(const set_table *tab)
25102531
{
25112532
return(sizeof(set_table)
2512-
+ (tab->bins == NULL ? 0 : set_bins_size(tab))
2533+
+ (tab->entry_power <= MAX_POWER2_FOR_TABLES_WITHOUT_BINS ? 0 : set_bins_size(tab))
25132534
+ set_get_allocated_entries(tab) * sizeof(set_table_entry));
25142535
}
25152536

@@ -2542,7 +2563,7 @@ set_rebuild_table(set_table *tab)
25422563
|| tab->num_entries < (1 << MINIMAL_POWER2)) {
25432564
/* Compaction: */
25442565
tab->num_entries = 0;
2545-
if (tab->bins != NULL)
2566+
if (set_has_bins(tab))
25462567
set_initialize_bins(tab);
25472568
set_rebuild_table_with(tab, tab);
25482569
}
@@ -2572,7 +2593,7 @@ set_rebuild_table_with(set_table *const new_tab, set_table *const tab)
25722593
new_entries = new_tab->entries;
25732594

25742595
ni = 0;
2575-
bins = new_tab->bins;
2596+
bins = set_bins_ptr(new_tab);
25762597
size_ind = set_get_size_ind(new_tab);
25772598
st_index_t bound = tab->entries_bound;
25782599
set_table_entry *entries = tab->entries;
@@ -2602,8 +2623,6 @@ set_rebuild_move_table(set_table *const new_tab, set_table *const tab)
26022623
tab->entry_power = new_tab->entry_power;
26032624
tab->bin_power = new_tab->bin_power;
26042625
tab->size_ind = new_tab->size_ind;
2605-
free(tab->bins);
2606-
tab->bins = new_tab->bins;
26072626
free(tab->entries);
26082627
tab->entries = new_tab->entries;
26092628
free(new_tab);
@@ -2688,7 +2707,7 @@ set_find_table_entry_ind(set_table *tab, st_hash_t hash_value, st_data_t key)
26882707
perturb = hash_value;
26892708
#endif
26902709
for (;;) {
2691-
bin = get_bin(tab->bins, set_get_size_ind(tab), ind);
2710+
bin = get_bin(set_bins_ptr(tab), set_get_size_ind(tab), ind);
26922711
if (! EMPTY_OR_DELETED_BIN_P(bin)) {
26932712
DO_PTR_EQUAL_CHECK(tab, &entries[bin - ENTRY_BASE], hash_value, key, eq_p, rebuilt_p);
26942713
if (EXPECT(rebuilt_p, 0))
@@ -2732,7 +2751,7 @@ set_find_table_bin_ind(set_table *tab, st_hash_t hash_value, st_data_t key)
27322751
perturb = hash_value;
27332752
#endif
27342753
for (;;) {
2735-
bin = get_bin(tab->bins, set_get_size_ind(tab), ind);
2754+
bin = get_bin(set_bins_ptr(tab), set_get_size_ind(tab), ind);
27362755
if (! EMPTY_OR_DELETED_BIN_P(bin)) {
27372756
DO_PTR_EQUAL_CHECK(tab, &entries[bin - ENTRY_BASE], hash_value, key, eq_p, rebuilt_p);
27382757
if (EXPECT(rebuilt_p, 0))
@@ -2773,7 +2792,7 @@ set_find_table_bin_ind_direct(set_table *tab, st_hash_t hash_value, st_data_t ke
27732792
perturb = hash_value;
27742793
#endif
27752794
for (;;) {
2776-
bin = get_bin(tab->bins, set_get_size_ind(tab), ind);
2795+
bin = get_bin(set_bins_ptr(tab), set_get_size_ind(tab), ind);
27772796
if (EMPTY_OR_DELETED_BIN_P(bin))
27782797
return ind;
27792798
#ifdef QUADRATIC_PROBE
@@ -2787,7 +2806,7 @@ set_find_table_bin_ind_direct(set_table *tab, st_hash_t hash_value, st_data_t ke
27872806

27882807
/* Mark I-th bin of table TAB as empty, in other words not
27892808
corresponding to any entry. */
2790-
#define MARK_SET_BIN_EMPTY(tab, i) (set_bin((tab)->bins, set_get_size_ind(tab), i, EMPTY_BIN))
2809+
#define MARK_SET_BIN_EMPTY(tab, i) (set_bin(set_bins_ptr(tab), set_get_size_ind(tab), i, EMPTY_BIN))
27912810

27922811
/* Return index of table TAB bin for HASH_VALUE and KEY through
27932812
BIN_IND and the pointed value as the function result. Reserve the
@@ -2823,7 +2842,7 @@ set_find_table_bin_ptr_and_reserve(set_table *tab, st_hash_t *hash_value,
28232842
firset_deleted_bin_ind = UNDEFINED_BIN_IND;
28242843
entries = tab->entries;
28252844
for (;;) {
2826-
entry_index = get_bin(tab->bins, set_get_size_ind(tab), ind);
2845+
entry_index = get_bin(set_bins_ptr(tab), set_get_size_ind(tab), ind);
28272846
if (EMPTY_BIN_P(entry_index)) {
28282847
tab->num_entries++;
28292848
entry_index = UNDEFINED_ENTRY_IND;
@@ -2863,7 +2882,7 @@ set_table_lookup(set_table *tab, st_data_t key)
28632882
st_hash_t hash = set_do_hash(key, tab);
28642883

28652884
retry:
2866-
if (tab->bins == NULL) {
2885+
if (!set_has_bins(tab)) {
28672886
bin = set_find_entry(tab, hash, key);
28682887
if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
28692888
goto retry;
@@ -2907,7 +2926,7 @@ set_insert(set_table *tab, st_data_t key)
29072926
hash_value = set_do_hash(key, tab);
29082927
retry:
29092928
set_rebuild_table_if_necessary(tab);
2910-
if (tab->bins == NULL) {
2929+
if (!set_has_bins(tab)) {
29112930
bin = set_find_entry(tab, hash_value, key);
29122931
if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
29132932
goto retry;
@@ -2930,7 +2949,7 @@ set_insert(set_table *tab, st_data_t key)
29302949
entry->hash = hash_value;
29312950
entry->key = key;
29322951
if (bin_ind != UNDEFINED_BIN_IND)
2933-
set_bin(tab->bins, set_get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
2952+
set_bin(set_bins_ptr(tab), set_get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
29342953
return 0;
29352954
}
29362955
return 1;
@@ -2941,18 +2960,9 @@ static set_table *
29412960
set_replace(set_table *new_tab, set_table *old_tab)
29422961
{
29432962
*new_tab = *old_tab;
2944-
if (old_tab->bins == NULL)
2945-
new_tab->bins = NULL;
2946-
else {
2947-
new_tab->bins = (st_index_t *) malloc(set_bins_size(old_tab));
2948-
}
2949-
new_tab->entries = (set_table_entry *) malloc(set_get_allocated_entries(old_tab)
2950-
* sizeof(set_table_entry));
2951-
MEMCPY(new_tab->entries, old_tab->entries, set_table_entry,
2952-
set_get_allocated_entries(old_tab));
2953-
if (old_tab->bins != NULL)
2954-
MEMCPY(new_tab->bins, old_tab->bins, char, set_bins_size(old_tab));
2955-
2963+
size_t memsize = set_allocated_entries_size(old_tab);
2964+
new_tab->entries = (set_table_entry *)malloc(memsize);
2965+
MEMCPY(new_tab->entries, old_tab->entries, char, memsize);
29562966
return new_tab;
29572967
}
29582968

@@ -2991,7 +3001,7 @@ set_update_range_for_deleted(set_table *tab, st_index_t n)
29913001
corresponding to deleted entries. */
29923002
#define MARK_SET_BIN_DELETED(tab, i) \
29933003
do { \
2994-
set_bin((tab)->bins, set_get_size_ind(tab), i, DELETED_BIN); \
3004+
set_bin(set_bins_ptr(tab), set_get_size_ind(tab), i, DELETED_BIN); \
29953005
} while (0)
29963006

29973007
/* Delete entry with KEY from table TAB, and return non-zero. If
@@ -3006,7 +3016,7 @@ set_table_delete(set_table *tab, st_data_t *key)
30063016

30073017
hash = set_do_hash(*key, tab);
30083018
retry:
3009-
if (tab->bins == NULL) {
3019+
if (!set_has_bins(tab)) {
30103020
bin = set_find_entry(tab, hash, *key);
30113021
if (EXPECT(bin == REBUILT_TABLE_ENTRY_IND, 0))
30123022
goto retry;
@@ -3021,7 +3031,7 @@ set_table_delete(set_table *tab, st_data_t *key)
30213031
if (bin_ind == UNDEFINED_BIN_IND) {
30223032
return 0;
30233033
}
3024-
bin = get_bin(tab->bins, set_get_size_ind(tab), bin_ind) - ENTRY_BASE;
3034+
bin = get_bin(set_bins_ptr(tab), set_get_size_ind(tab), bin_ind) - ENTRY_BASE;
30253035
MARK_SET_BIN_DELETED(tab, bin_ind);
30263036
}
30273037
entry = &tab->entries[bin];
@@ -3052,7 +3062,7 @@ set_general_foreach(set_table *tab, set_foreach_check_callback_func *func,
30523062
st_index_t i, rebuilds_num;
30533063
st_hash_t hash;
30543064
st_data_t key;
3055-
int error_p, packed_p = tab->bins == NULL;
3065+
int error_p, packed_p = !set_has_bins(tab);
30563066

30573067
entries = tab->entries;
30583068
/* The bound can change inside the loop even without rebuilding
@@ -3074,7 +3084,7 @@ set_general_foreach(set_table *tab, set_foreach_check_callback_func *func,
30743084
if (rebuilds_num != tab->rebuilds_num) {
30753085
retry:
30763086
entries = tab->entries;
3077-
packed_p = tab->bins == NULL;
3087+
packed_p = !set_has_bins(tab);
30783088
if (packed_p) {
30793089
i = set_find_entry(tab, hash, key);
30803090
if (EXPECT(i == REBUILT_TABLE_ENTRY_IND, 0))
@@ -3122,7 +3132,7 @@ set_general_foreach(set_table *tab, set_foreach_check_callback_func *func,
31223132
goto again;
31233133
if (bin_ind == UNDEFINED_BIN_IND)
31243134
break;
3125-
bin = get_bin(tab->bins, set_get_size_ind(tab), bin_ind) - ENTRY_BASE;
3135+
bin = get_bin(set_bins_ptr(tab), set_get_size_ind(tab), bin_ind) - ENTRY_BASE;
31263136
MARK_SET_BIN_DELETED(tab, bin_ind);
31273137
}
31283138
curr_entry_ptr = &entries[bin];

0 commit comments

Comments
 (0)