/src/irssi/src/core/refstrings.c
Line | Count | Source |
1 | | #include <glib.h> |
2 | | #include <string.h> |
3 | | |
4 | | #include <irssi/src/core/refstrings.h> |
5 | | |
6 | | #if GLIB_CHECK_VERSION(2, 58, 0) |
7 | | |
8 | | void i_refstr_init(void) |
9 | 8 | { |
10 | | /* nothing */ |
11 | 8 | } |
12 | | |
13 | | char *i_refstr_intern(const char *str) |
14 | 9.07k | { |
15 | 9.07k | if (str == NULL) { |
16 | 0 | return NULL; |
17 | 0 | } |
18 | | |
19 | 9.07k | return g_ref_string_new_intern(str); |
20 | 9.07k | } |
21 | | |
22 | | void i_refstr_release(char *str) |
23 | 9.07k | { |
24 | 9.07k | if (str == NULL) { |
25 | 0 | return; |
26 | 0 | } |
27 | | |
28 | 9.07k | g_ref_string_release(str); |
29 | 9.07k | } |
30 | | |
31 | | void i_refstr_deinit(void) |
32 | 0 | { |
33 | | /* nothing */ |
34 | 0 | } |
35 | | |
36 | | char *i_refstr_table_size_info(void) |
37 | 0 | { |
38 | | /* not available */ |
39 | | return NULL; |
40 | 0 | } |
41 | | |
42 | | #else |
43 | | |
44 | | GHashTable *i_refstr_table; |
45 | | |
46 | | void i_refstr_init(void) |
47 | | { |
48 | | i_refstr_table = g_hash_table_new(g_str_hash, g_str_equal); |
49 | | } |
50 | | |
51 | | char *i_refstr_intern(const char *str) |
52 | | { |
53 | | char *ret; |
54 | | gpointer rc_p, ret_p; |
55 | | size_t rc; |
56 | | |
57 | | if (str == NULL) |
58 | | return NULL; |
59 | | |
60 | | if (g_hash_table_lookup_extended(i_refstr_table, str, &ret_p, &rc_p)) { |
61 | | rc = GPOINTER_TO_SIZE(rc_p); |
62 | | ret = ret_p; |
63 | | } else { |
64 | | rc = 0; |
65 | | ret = g_strdup(str); |
66 | | } |
67 | | |
68 | | if (rc + 1 <= G_MAXSIZE) { |
69 | | g_hash_table_insert(i_refstr_table, ret, GSIZE_TO_POINTER(rc + 1)); |
70 | | return ret; |
71 | | } else { |
72 | | return g_strdup(str); |
73 | | } |
74 | | } |
75 | | |
76 | | void i_refstr_release(char *str) |
77 | | { |
78 | | char *ret; |
79 | | gpointer rc_p, ret_p; |
80 | | size_t rc; |
81 | | |
82 | | if (str == NULL) |
83 | | return; |
84 | | |
85 | | if (g_hash_table_lookup_extended(i_refstr_table, str, &ret_p, &rc_p)) { |
86 | | rc = GPOINTER_TO_SIZE(rc_p); |
87 | | ret = ret_p; |
88 | | } else { |
89 | | rc = 0; |
90 | | ret = NULL; |
91 | | } |
92 | | |
93 | | if (ret == str) { |
94 | | if (rc > 1) { |
95 | | g_hash_table_insert(i_refstr_table, ret, GSIZE_TO_POINTER(rc - 1)); |
96 | | } else { |
97 | | g_hash_table_remove(i_refstr_table, ret); |
98 | | g_free(ret); |
99 | | } |
100 | | } else { |
101 | | g_free(str); |
102 | | } |
103 | | } |
104 | | |
105 | | void i_refstr_deinit(void) |
106 | | { |
107 | | g_hash_table_foreach(i_refstr_table, (GHFunc) g_free, NULL); |
108 | | g_hash_table_destroy(i_refstr_table); |
109 | | } |
110 | | |
111 | | char *i_refstr_table_size_info(void) |
112 | | { |
113 | | GHashTableIter iter; |
114 | | void *k_p, *v_p; |
115 | | size_t count, mem; |
116 | | count = 0; |
117 | | mem = 0; |
118 | | g_hash_table_iter_init(&iter, i_refstr_table); |
119 | | while (g_hash_table_iter_next(&iter, &k_p, &v_p)) { |
120 | | char *key = k_p; |
121 | | count++; |
122 | | mem += sizeof(char) * (strlen(key) + 1) + 2 * sizeof(void *); |
123 | | } |
124 | | |
125 | | return g_strdup_printf("Shared strings: %ld, %dkB of data", count, |
126 | | (int) (mem / 1024)); |
127 | | } |
128 | | |
129 | | #endif |