summaryrefslogtreecommitdiff
path: root/debian/patches/0010-libihash-make-the-locp-offset-mechanism-more-flexibl.patch
blob: 499ab8c7693af678f329264f7ad2478c357b855b (plain)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
From 0fb2ddfbd9706f7473c454524ef6d52fd7b93df8 Mon Sep 17 00:00:00 2001
From: Justus Winter <4winter@informatik.uni-hamburg.de>
Date: Fri, 16 May 2014 12:18:40 +0200
Subject: [PATCH 10/20] libihash: make the locp offset mechanism more flexible

libihash allows one to store a location pointer inside the value being
stored.  This location pointer points to the hash table bucket a value
occupies.  This allows one to quickly remove the item.

Previously, it was only possible to store the location pointer within
the value directly.  Make it possible to store the location pointer
within an object referenced by a pointer stored in the value.

This allows one to store e.g. struct node objects as values, while
putting the location pointer inside the related struct netnode objects
in trans/fakeroot.

* libihash/ihash.c (update_locp): New function to update the location
pointer.
(add_one, hurd_ihash_locp_add): Use the new function.
(hurd_ihash_init_indirect, hurd_ihash_create_indirect): New functions.
* libihash/ihash.h (struct hurd_ihash): New field
locp_indirection_offset.
(HURD_IHASH_NO_INDIRECTION, HURD_IHASH_INITIALIZER_INDIRECT): New macros.
(hurd_ihash_init_indirect, hurd_ihash_create_indirect): New declarations.
---
 libihash/ihash.c | 60 ++++++++++++++++++++++++++++++++++++++++++++------------
 libihash/ihash.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 100 insertions(+), 13 deletions(-)

diff --git a/libihash/ihash.c b/libihash/ihash.c
index 167c872..c362c8c 100644
--- a/libihash/ihash.c
+++ b/libihash/ihash.c
@@ -107,6 +107,24 @@ locp_remove (hurd_ihash_t ht, hurd_ihash_locp_t locp)
   ht->nr_items--;
 }
 
+
+/* If HT uses location pointers, update the location pointer of VALUE
+   to LOCP.  */
+static inline void
+update_locp (hurd_ihash_t ht, hurd_ihash_value_t value,
+             hurd_ihash_locp_t locp)
+{
+  if (ht->locp_offset != HURD_IHASH_NO_LOCP)
+    {
+      char *base;
+      if (ht->locp_indirection_offset != HURD_IHASH_NO_INDIRECTION)
+	base = *((char **) ((char *) value + ht->locp_indirection_offset));
+      else
+	base = (char *) value;
+      *((hurd_ihash_locp_t *) (base + ht->locp_offset)) = locp;
+    }
+}
+
 
 /* Construction and destruction of hash tables.  */
 
@@ -114,9 +132,21 @@ locp_remove (hurd_ihash_t ht, hurd_ihash_locp_t locp)
 void
 hurd_ihash_init (hurd_ihash_t ht, intptr_t locp_offs)
 {
+  hurd_ihash_init_indirect (ht, HURD_IHASH_NO_INDIRECTION, locp_offs);
+}
+
+
+/* Initialize the hash table at address HT, indirect location pointer
+   version.  */
+void
+hurd_ihash_init_indirect (hurd_ihash_t ht,
+			  intptr_t locp_indirection_offset,
+			  intptr_t locp_offset)
+{
   ht->nr_items = 0;
   ht->size = 0;
-  ht->locp_offset = locp_offs;
+  ht->locp_offset = locp_offset;
+  ht->locp_indirection_offset = locp_indirection_offset;
   ht->max_load = HURD_IHASH_MAX_LOAD_DEFAULT;
   ht->cleanup = 0;
 }
@@ -147,11 +177,25 @@ hurd_ihash_destroy (hurd_ihash_t ht)
 error_t
 hurd_ihash_create (hurd_ihash_t *ht, intptr_t locp_offs)
 {
+  return hurd_ihash_create_indirect (ht,
+				     HURD_IHASH_NO_INDIRECTION,
+				     locp_offs);
+}
+
+
+/* Create a hash table, initialize it and return it in HT, indirect
+   location pointer version.  If a memory allocation error occurs,
+   ENOMEM is returned, otherwise 0.  */
+error_t
+hurd_ihash_create_indirect (hurd_ihash_t *ht,
+			    intptr_t locp_indirection_offset,
+			    intptr_t locp_offset)
+{
   *ht = malloc (sizeof (struct hurd_ihash));
   if (*ht == NULL)
     return ENOMEM;
 
-  hurd_ihash_init (*ht, locp_offs);
+  hurd_ihash_init_indirect (*ht, locp_indirection_offset, locp_offset);
 
   return 0;
 }
@@ -247,11 +291,7 @@ add_one (hurd_ihash_t ht, hurd_ihash_key_t key, hurd_ihash_value_t value)
       ht->nr_items++;
       ht->items[first_free].value = value;
       ht->items[first_free].key = key;
-
-      if (ht->locp_offset != HURD_IHASH_NO_LOCP)
-	*((hurd_ihash_locp_t *) (((char *) value) + ht->locp_offset))
-	  = &ht->items[first_free].value;
-
+      update_locp (ht, value, &ht->items[first_free].value);
       return 1;
     }
 
@@ -297,11 +337,7 @@ hurd_ihash_locp_add (hurd_ihash_t ht, hurd_ihash_locp_t locp,
     }
 
   item->value = value;
-
-  if (ht->locp_offset != HURD_IHASH_NO_LOCP)
-    *((hurd_ihash_locp_t *) (((char *) value) + ht->locp_offset))
-      = locp;
-
+  update_locp (ht, value, locp);
   return 0;
 }
 
diff --git a/libihash/ihash.h b/libihash/ihash.h
index f7ecf1b..ca253a9 100644
--- a/libihash/ihash.h
+++ b/libihash/ihash.h
@@ -87,6 +87,11 @@ struct hurd_ihash
   /* The offset of the location pointer from the hash value.  */
   intptr_t locp_offset;
 
+  /* If the location pointer is not in hash value, but in an object
+     pointed to by a pointer in hash value, this is the offset of said
+     pointer in hash value.  */
+  intptr_t locp_indirection_offset;
+
   /* The maximum load factor in binary percent.  */
   unsigned int max_load;
 
@@ -112,11 +117,20 @@ typedef struct hurd_ihash *hurd_ihash_t;
 /* The LOCP_OFFS to use if no location pointer is available.  */
 #define HURD_IHASH_NO_LOCP	INTPTR_MIN
 
+/* The LOCP_INDIRECTION_OFFSET to use if the location pointer is in
+   the hash value.  */
+#define HURD_IHASH_NO_INDIRECTION	INTPTR_MIN
+
 /* The static initializer for a struct hurd_ihash.  */
 #define HURD_IHASH_INITIALIZER(locp_offs)				\
+  HURD_IHASH_INITIALIZER_INDIRECT (HURD_IHASH_NO_INDIRECTION, (locp_offs))
+
+/* The static initializer for a struct hurd_ihash, indirect location
+   pointer version.  */
+#define HURD_IHASH_INITIALIZER_INDIRECT(ind_offs, locp_offs)            \
   { .nr_items = 0, .size = 0, .cleanup = (hurd_ihash_cleanup_t) 0,	\
     .max_load = HURD_IHASH_MAX_LOAD_DEFAULT,				\
-    .locp_offset = (locp_offs)}
+    .locp_offset = (locp_offs), .locp_indirection_offset = (ind_offs)}
 
 /* Initialize the hash table at address HT.  If LOCP_OFFSET is not
    HURD_IHASH_NO_LOCP, then this is an offset (in bytes) from the
@@ -125,6 +139,24 @@ typedef struct hurd_ihash *hurd_ihash_t;
    for fast removal with hurd_ihash_locp_remove().  */
 void hurd_ihash_init (hurd_ihash_t ht, intptr_t locp_offs);
 
+/* Initialize the hash table at address HT, indirect location pointer
+   version.
+
+   If LOCP_OFFSET is not HURD_IHASH_NO_LOCP, then this is an offset
+   (in bytes) from the address of a hash value where a location
+   pointer can be found.
+
+   If furthermore LOCP_INDIRECTION_OFFSET is not
+   HURD_IHASH_NO_INDIRECTION, then this is an offset (in bytes) from
+   the address of a hash value where a pointer can be found that
+   points to the object containing the location pointer.
+
+   The location pointer must be of type hurd_ihash_locp_t and can be
+   used for fast removal with hurd_ihash_locp_remove().  */
+void hurd_ihash_init_indirect (hurd_ihash_t ht,
+			       intptr_t locp_indirection_offset,
+			       intptr_t locp_offset);
+
 /* Destroy the hash table at address HT.  This first removes all
    elements which are still in the hash table, and calling the cleanup
    function for them (if any).  */
@@ -139,6 +171,25 @@ void hurd_ihash_destroy (hurd_ihash_t ht);
    ENOMEM is returned, otherwise 0.  */
 error_t hurd_ihash_create (hurd_ihash_t *ht, intptr_t locp_offs);
 
+/* Create a hash table, initialize it and return it in HT, indirect
+   location pointer version.
+
+   If LOCP_OFFSET is not HURD_IHASH_NO_LOCP, then this is an offset
+   (in bytes) from the address of a hash value where a location
+   pointer can be found.
+
+   If furthermore LOCP_INDIRECTION_OFFSET is not
+   HURD_IHASH_NO_INDIRECTION, then this is an offset (in bytes) from
+   the address of a hash value where a pointer can be found that
+   points to the object containing the location pointer.
+
+   The location pointer must be of type hurd_ihash_locp_t and can be
+   used for fast removal with hurd_ihash_locp_remove().  If a memory
+   allocation error occurs, ENOMEM is returned, otherwise 0.  */
+error_t hurd_ihash_create_indirect (hurd_ihash_t *ht,
+				    intptr_t locp_indirection_offset,
+				    intptr_t locp_offset);
+
 /* Destroy the hash table HT and release the memory allocated for it
    by hurd_ihash_create().  */
 void hurd_ihash_free (hurd_ihash_t ht);
-- 
2.0.0.rc0