少年修仙传客户端基础资源
hch
2024-04-01 d01413b00ef631ac20347716b23818b0b811f65f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**
 * \file
 * A hash table which uses the values themselves as nodes.
 *
 * Author:
 *   Mark Probst (mark.probst@gmail.com)
 *
 * (C) 2007 Novell, Inc.
 *
 */
 
#include <config.h>
#include <glib.h>
#include <mono/utils/mono-compiler.h>
#include <mono/utils/mono-internal-hash.h>
 
#define MIN_SIZE    11
#define HASH(k,f,s)    ((f)((k)) % (s))
 
void
mono_internal_hash_table_init (MonoInternalHashTable *table,
                   GHashFunc hash_func,
                   MonoInternalHashKeyExtractFunc key_extract,
                   MonoInternalHashNextValueFunc next_value)
{
    table->hash_func = hash_func;
    table->key_extract = key_extract;
    table->next_value = next_value;
 
    table->size = MIN_SIZE;
    table->num_entries = 0;
    table->table = g_new0 (gpointer, table->size);
}
 
void
mono_internal_hash_table_destroy (MonoInternalHashTable *table)
{
    g_free (table->table);
    table->table = NULL;
}
 
gpointer
mono_internal_hash_table_lookup (MonoInternalHashTable *table, gpointer key)
{
    gpointer value;
 
    g_assert (table->table != NULL);
 
    for (value = table->table [HASH (key, table->hash_func, table->size)];
         value != NULL;
         value = *(table->next_value (value))) {
        if (table->key_extract (value) == key)
            return value;
    }
    return NULL;
}
 
static void
resize_if_needed (MonoInternalHashTable *table)
{
    gpointer *new_table;
    gint new_size;
    gint i;
 
    if (table->num_entries < table->size * 3)
        return;
 
    new_size = g_spaced_primes_closest (table->num_entries);
    new_table = g_new0 (gpointer, new_size);
 
    for (i = 0; i < table->size; ++i) {
        while (table->table[i] != NULL) {
            gpointer value;
            gint hash;
 
            value = table->table [i];
            table->table [i] = *(table->next_value (value));
 
            hash = HASH (table->key_extract (value), table->hash_func, new_size);
            *(table->next_value (value)) = new_table [hash];
            new_table [hash] = value;
        }
    }
 
    g_free (table->table);
 
    table->size = new_size;
    table->table = new_table;
}
 
void
mono_internal_hash_table_insert (MonoInternalHashTable *table,
                 gpointer key, gpointer value)
{
    gint hash = HASH (key, table->hash_func, table->size);
 
    g_assert (table->key_extract(value) == key);
    g_assert (*(table->next_value (value)) == NULL);
    g_assert (mono_internal_hash_table_lookup (table, key) == NULL);
 
    *(table->next_value (value)) = table->table[hash];
    table->table [hash] = value;
 
    ++table->num_entries;
 
    resize_if_needed (table);
}
 
void
mono_internal_hash_table_remove (MonoInternalHashTable *table, gpointer key)
{
    gint hash = HASH (key, table->hash_func, table->size);
    gpointer *value;
 
    for (value = &table->table [hash];
         *value != NULL;
         value = table->next_value (*value)) {
        if (table->key_extract (*value) == key)
        {
            *value = *(table->next_value (*value));
            --table->num_entries;
            return;
        }
    }
 
    g_assert (0);
}