PageRenderTime 20ms CodeModel.GetById 14ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

/src/wrappers/glib/partially-implemented/g_hash_table.e

http://github.com/tybor/Liberty
Specman e | 517 lines | 169 code | 109 blank | 239 comment | 5 complexity | 2188b1c9988478f8eaf1abaf909c8be6 MD5 | raw file
  1indexing
  2	description: "Hash Tables associations between keys and values so that given a key the value can be found quickly."
  3	copyright: "(C) 2005 Paolo Redaelli "
  4	license: "LGPL v2 or later"
  5	date: "$Date:$"
  6	revision: "$REvision:$"
  7
  8class G_HASH_TABLE [VALUE->SHARED_C_STRUCT, KEY->COMPARABLE_SHARED_C_STRUCT]
  9	-- A G_HASH_TABLE provides associations between keys and values
 10	-- which is optimized so that given a key, the associated value can
 11	-- be found very quickly.
 12
 13	-- TODO: provide non-fast features, i.e. features that compare 
 14	-- keys by their content, not by their address.
 15
 16	-- TODO: Eiffellize the following documentation.
 17	
 18	-- Note: the following note, valid for the manual memory management
 19	-- of the C world is not true anymore in an Eiffel program, if a
 20	-- caching wrapper factory is used... "Note that neither keys nor
 21	-- values are copied when inserted into the G_HASH_TABLE, so they
 22	-- must exist for the lifetime of the G_HASH_TABLE. This means that
 23	-- the use of static strings is OK, but temporary strings
 24	-- (i.e. those created in buffers and those returned by GTK+
 25	-- widgets) should be copied with g_strdup() before being
 26	-- inserted".
 27
 28	-- If keys or values are dynamically allocated, you must be careful
 29	-- to ensure that they are freed when they are removed from the
 30	-- G_HASH_TABLE, and also when they are overwritten by new
 31	-- insertions into the G_HASH_TABLE. It is also not advisable to
 32	-- mix static strings and dynamically-allocated strings in a
 33	-- GHashTable, because it then becomes difficult to determine
 34	-- whether the string should be freed.
 35
 36	-- To create a GHashTable, use g_hash_table_new().
 37	
 38	-- To insert a key and value into a GHashTable, use
 39	-- g_hash_table_insert().
 40
 41	-- To lookup a value corresponding to a given key, use
 42	-- g_hash_table_lookup() and g_hash_table_lookup_extended().
 43
 44	-- To remove a key and value, use g_hash_table_remove().
 45
 46	-- To call a function for each key and value pair use
 47	-- g_hash_table_foreach().
 48
 49	-- To destroy a GHashTable use g_hash_table_destroy().
 50
 51inherit
 52	WRAPPER_DICTIONARY [VALUE, KEY]
 53		redefine
 54			dispose
 55		end
 56		
 57insert
 58	G_HASH_TABLE_EXTERNALS
 59
 60creation  from_external
 61
 62feature {} -- Creation
 63	from_external (a_pointer: POINTER; a_factory: WRAPPER_FACTORY[VALUE]) is
 64		require factory_not_void: a_factory/=Void
 65		do
 66			factory := a_factory
 67			from_external_pointer(a_pointer)
 68		end
 69	
 70
 71	with_factory (a_factory: WRAPPER_FACTORY[VALUE]) is
 72		require factory_not_void: a_factory/=Void
 73		do
 74			factory := a_factory
 75			from_external_pointer
 76			(g_hash_table_new
 77			 (default_pointer, -- Using g_direct_hash as hash function;
 78			  default_pointer, -- Direct comparison of address, like using g_direct_equal as key equal function but with no overhead
 79			  ),a_factory)
 80	
 81			-- g_hash_table_new creates a new GHashTable.
 82			
 83			-- hash_func : a function to create a hash value from a
 84			-- key. Hash values are used to determine where keys are
 85			-- stored within the GHashTable data structure. The
 86			-- g_direct_hash(), g_int_hash() and g_str_hash() functions
 87			-- are provided for some common types of keys. If hash_func
 88			-- is NULL, g_direct_hash() is used.
 89			
 90			-- key_equal_func : a function to check two keys for
 91			-- equality. This is used when looking up keys in the
 92			-- GHashTable. The g_direct_equal(), g_int_equal() and
 93			-- g_str_equal() functions are provided for the most common
 94			-- types of keys. If key_equal_func is NULL, keys are
 95			-- compared directly in a similar fashion to
 96			-- g_direct_equal(), but without the overhead of a function
 97			-- call.
 98		end
 99
100	-- TODO: GHashTable* g_hash_table_new_full (GHashFunc hash_func,
101	-- GEqualFunc key_equal_func, GDestroyNotify key_destroy_func,
102	-- GDestroyNotify value_destroy_func);
103	
104	-- Creates a new GHashTable like g_hash_table_new() and allows to
105	-- specify functions to free the memory allocated for the key and
106	-- value that get called when removing the entry from the
107	-- GHashTable.
108
109	-- hash_func : 	a function to create a hash value from a key.
110	-- key_equal_func : 	a function to check two keys for equality.
111	-- key_destroy_func : 	a function to free the memory allocated for the key used when removing the entry from the GHashTable or NULL if you don't want to supply such a function.
112	-- value_destroy_func : 	a function to free the memory allocated for the value used when removing the entry from the GHashTable or NULL if you don't want to supply such a function.
113	-- Returns : 	a new GHashTable.
114
115	-- TODO: feature {} -- Implement manifest generic creation:
116	-- 	manifest_make (needed_capacity: INTEGER) is
117	-- 			-- Manifest creation of a dictionary.
118	-- 		do
119	-- 			allocate
120	-- 		end
121	
122feature {ANY} -- Basic access:
123	has (a_key: KEY): BOOLEAN is
124		local orig_key_ptr, value_ptr: POINTER
125		do
126			Result:=(g_hash_table_lookup_extended
127						(handle, a_key.handle, orig_key_ptr, value_ptr)).to_boolean
128		end
129
130	at (a_key: KEY): VALUE is
131			-- Looks up `a_key' in a GHashTable. 
132		local ptr: POINTER
133		do
134			ptr := g_hash_table_lookup (handle, a_key.handle)
135			if ptr.is_not_null then
136				Result:=factory.wrapper(ptr)
137			end
138		end
139
140	reference_at (a_key: KEY): VALUE is
141			-- The value associated to `a_key'. Void if there is no value
142			-- for `a_key'.
143		local ptr: POINTER
144		do
145			ptr := g_hash_table_lookup (handle, a_key.handle)
146			if ptr.is_not_null then
147				Result:=factory.wrapper(ptr)
148			end
149
150			-- Looks up a key in the GHashTable, returning the original
151			-- key and the associated value and a gboolean which is TRUE
152			-- if the key was found. This is useful if you need to free
153			-- the memory allocated for the original key, for example
154			-- before calling `remove'.
155
156			-- `a_key': 	the key to look up.
157		
158			-- orig_key : 	returns the original key.
159			-- value : 	returns the value associated with the key.
160			-- Returns : 	TRUE if the key was found in the GHashTable.
161			-- gboolean g_hash_table_lookup_extended (GHashTable
162			-- *hash_table, gconstpointer lookup_key, gpointer *orig_key,
163			-- gpointer *value);
164		end
165
166	fast_has (k: KEY): BOOLEAN is
167		do
168			debug 
169				print_no_fast_notice
170				print(fast_fallback_notice)
171			end
172			Result:=has(k)
173		end
174
175	fast_at (k: KEY): VALUE is
176		do	
177			debug 
178				print_no_fast_notice
179				print(fast_fallback_notice)
180			end
181			Result:=at(k)
182		end
183
184	fast_reference_at (k: KEY): VALUE is
185		do
186			debug 
187				print_no_fast_notice
188				print(fast_fallback_notice)
189			end
190			Result:=reference_at(k)
191		end
192
193feature {ANY}
194	put (a_value: VALUE; a_key: KEY) is
195			-- Inserts a new key and value into a GHashTable.
196		
197			-- If the key already exists in the GHashTable its current
198			-- value is replaced with the new value. If you supplied a
199			-- value_destroy_func when creating the GHashTable, the old
200			-- value is freed using that function. If you supplied a
201			-- key_destroy_func when creating the GHashTable, the passed
202			-- key is freed using that function.
203		
204			-- hash_table : 	a GHashTable.
205			-- key : 	a key to insert.
206			-- value : 	the value to associate with the key.
207		require else value_not_void: a_value /= Void
208		do
209			g_hash_table_insert (handle, a_key.handle, a_value.handle)
210		end
211
212	fast_put (v: VALUE; k: KEY) is
213		require else value_not_void: v /= Void
214		do
215			debug 
216				print_no_fast_notice
217				print(fast_fallback_notice)
218			end
219			put(v,k)
220		end
221
222	add (v: VALUE; k: KEY) is
223		require else value_not_void: v /= Void
224		do
225			put(v,k)
226		end
227
228feature {ANY} -- Removing:
229	remove (a_key: KEY) is
230			-- Removes a key and its associated value from a GHashTable.
231
232			-- `is_successful' will be True if the key was found and
233			-- removed from the GHashTable.
234		do
235			-- TODO: Translate/implement this C-ism: If the GHashTable
236			-- was created using `make_full', the key and value are freed
237			-- using the supplied destroy functions, otherwise you have
238			-- to make sure that any dynamically allocated values are
239			-- freed yourself.
240			is_successful := (g_hash_table_remove (handle, a_key.handle)).to_boolean
241		end
242
243	fast_remove (k: KEY) is
244		do
245			debug 
246				print_no_fast_notice
247				print(fast_fallback_notice)
248			end
249			remove(k)
250		end
251
252	clear_count is
253		do
254			g_hash_table_remove_all(handle)
255		end
256
257	clear_count_and_capacity is
258		do
259			dispose
260			make
261		end
262
263	capacity: INTEGER is
264		do
265			Result:=g_hash_table_size(handle)
266		end
267
268feature {ANY} -- To provide iterating facilities:
269	item (index: INTEGER): VALUE is
270		do
271		ensure then implemented: False
272		end
273
274	key (index: INTEGER): KEY is
275		do
276		ensure then implemented: False
277		end
278
279	get_new_iterator_on_keys: ITERATOR[KEY] is
280		do
281		ensure then implemented: False
282		end
283
284feature {ANY} -- Other features:
285	internal_key (k: KEY): KEY is
286		do
287		ensure then implemented: False
288		end
289
290	-- GHashFunc ()
291
292	-- guint       (*GHashFunc)                    (gconstpointer key);
293	
294	-- Specifies the type of the hash function which is passed to
295	-- g_hash_table_new() when a GHashTable is created.
296
297	-- The function is passed a key and should return a guint hash
298	-- value. The functions g_direct_hash(), g_int_hash() and
299	-- g_str_hash() provide hash functions which can be used when the
300	-- key is a gpointer, gint, and gchar* respectively.
301	
302	-- FIXME: Need more here. The hash values should be evenly
303	-- distributed over a fairly large range? The modulus is taken with
304	-- the hash table size (a prime number) to find the 'bucket' to
305	-- place each key into. The function should also be very fast,
306	-- since it is called for each key lookup.  key : a key.  Returns :
307	-- the hash value corresponding to the key.  GEqualFunc ()
308
309	-- gboolean (*GEqualFunc) (gconstpointer a, gconstpointer b);
310
311	-- Specifies the type of a function used to test two values for
312	-- equality. The function should return TRUE if both values are
313	-- equal and FALSE otherwise.
314	
315	-- a : 	a value.
316	-- b : 	a value to compare with.
317	-- Returns : 	TRUE if a = b; FALSE otherwise.
318	-- g_hash_table_insert ()
319
320feature
321
322	count: INTEGER is
323			-- the number of elements (key/value pairs) contained in the
324			-- GHashTable.
325		do
326			Result := g_hash_table_size (handle)
327		end
328
329	-- g_hash_table_foreach ()
330	
331	-- void g_hash_table_foreach (GHashTable *hash_table, GHFunc func,
332	-- gpointer user_data);
333	
334	-- Calls the given function for each of the key/value pairs in the
335	-- GHashTable. The function is passed the key and value of each
336	-- pair, and the given user_data parameter. The hash table may not
337	-- be modified while iterating over it (you can't add/remove
338	-- items). To remove all items matching a predicate, use
339	-- g_hash_table_foreach_remove().
340
341	-- hash_table : 	a GHashTable.
342	-- func : 	the function to call for each key/value pair.
343	-- user_data : 	user data to pass to the function.
344	
345	-- g_hash_table_find ()
346	
347	-- gpointer g_hash_table_find (GHashTable *hash_table, GHRFunc
348	-- predicate, gpointer user_data);
349
350	-- Calls the given function for key/value pairs in the GHashTable
351	-- until predicate returns TRUE. The function is passed the key and
352	-- value of each pair, and the given user_data parameter. The hash
353	-- table may not be modified while iterating over it (you can't
354	-- add/remove items).
355	
356	-- hash_table : 	a GHashTable.
357	-- predicate : 	function to test the key/value pairs for a certain property.
358	-- user_data : 	user data to pass to the function.
359	-- Returns : 	The value of the first key/value pair is returned, for which func evaluates to TRUE. If no pair with the requested property is found, NULL is returned.
360
361
362	-- GHFunc ()
363	
364	-- void (*GHFunc) (gpointer key, gpointer value, gpointer
365	-- user_data);
366	
367	-- Specifies the type of the function passed to g_hash_table_foreach(). It is called with each key/value pair, together with the user_data parameter which is passed to g_hash_table_foreach().
368	-- key : 	a key.
369	-- value : 	the value corresponding to the key.
370	-- user_data : 	user data passed to g_hash_table_foreach().
371
372	is_successful: BOOLEAN
373	
374	-- g_hash_table_foreach_remove ()
375	
376	-- guint       g_hash_table_foreach_remove     (GHashTable *hash_table,
377	--                                              GHRFunc func,
378	--                                              gpointer user_data);
379
380	-- Calls the given function for each key/value pair in the GHashTable. If the function returns TRUE, then the key/value pair is removed from the GHashTable. If you supplied key or value destroy functions when creating the GHashTable, they are used to free the memory allocated for the removed keys and values.
381
382	-- hash_table : 	a GHashTable.
383	-- func : 	the function to call for each key/value pair.
384	-- user_data : 	user data to pass to the function.
385	-- Returns : 	the number of key/value pairs removed.
386	-- g_hash_table_foreach_steal ()
387
388	-- guint       g_hash_table_foreach_steal      (GHashTable *hash_table,
389	--                                              GHRFunc func,
390	--                                              gpointer user_data);
391
392	-- Calls the given function for each key/value pair in the GHashTable. If the function returns TRUE, then the key/value pair is removed from the GHashTable, but no key or value destroy functions are called.
393
394	-- hash_table : 	a GHashTable.
395	-- func : 	the function to call for each key/value pair.
396	-- user_data : 	user data to pass to the function.
397	-- Returns : 	the number of key/value pairs removed.
398	-- GHRFunc ()
399
400	-- gboolean    (*GHRFunc)                      (gpointer key,
401	--                                              gpointer value,
402	--                                              gpointer user_data);
403
404	-- Specifies the type of the function passed to g_hash_table_foreach_remove(). It is called with each key/value pair, together with the user_data parameter passed to g_hash_table_foreach_remove(). It should return TRUE if the key/value pair should be removed from the GHashTable.
405	-- key : 	a key.
406	-- value : 	the value associated with the key.
407	-- user_data : 	user data passed to g_hash_table_remove().
408	-- Returns : 	TRUE if the key/value pair should be removed from the GHashTable.
409
410	dispose is
411			-- Destroys the GHashTable. If keys and/or values are
412			-- dynamically allocated, you should either free them first
413			-- or create the GHashTable using g_hash_table_new_full(). In
414			-- the latter case the destroy functions you supplied will be
415			-- called on all keys and values before destroying the
416			-- GHashTable.
417		do
418			g_hash_table_destroy (handle)
419		end
420
421feature {}
422	-- g_direct_equal ()
423
424	-- Compares two gpointer arguments and returns TRUE if they
425	-- are equal. It can be passed to `g_hash_table_new' as the
426	-- key_equal_func parameter, when using pointers as keys in a
427	-- GHashTable.
428	
429	-- g_direct_hash ()
430
431	-- guint       g_direct_hash                   (gconstpointer v);
432
433	-- Converts a gpointer to a hash value. It can be passed to g_hash_table_new() as the hash_func parameter, when using pointers as keys in a GHashTable.
434
435	-- v : 	a gpointer key
436	-- Returns : 	a hash value corresponding to the key.
437	-- g_int_equal ()
438
439	-- gboolean    g_int_equal                     (gconstpointer v1,
440	--                                              gconstpointer v2);
441
442	-- Compares the two gint values being pointed to and returns TRUE if they are equal. It can be passed to g_hash_table_new() as the key_equal_func parameter, when using pointers to integers as keys in a GHashTable.
443
444	-- v1 : 	a pointer to a gint key.
445	-- v2 : 	a pointer to a gint key to compare with v1.
446	-- Returns : 	TRUE if the two keys match.
447	-- g_int_hash ()
448
449	-- guint       g_int_hash                      (gconstpointer v);
450
451	-- Converts a pointer to a gint to a hash value. It can be passed to g_hash_table_new() as the hash_func parameter, when using pointers to integers values as keys in a GHashTable.
452
453	-- v : 	a pointer to a gint key
454	-- Returns : 	a hash value corresponding to the key.
455	-- g_str_equal ()
456
457	-- gboolean    g_str_equal                     (gconstpointer v1,
458	--                                              gconstpointer v2);
459
460	-- Compares two strings and returns TRUE if they are equal. It can be passed to g_hash_table_new() as the key_equal_func parameter, when using strings as keys in a GHashTable.
461
462	-- v1 : 	a key.
463	-- v2 : 	a key to compare with v1.
464	-- Returns : 	TRUE if the two keys match.
465	-- g_str_hash ()
466
467	-- guint       g_str_hash                      (gconstpointer v);
468
469	-- Converts a string to a hash value. It can be passed to g_hash_table_new() as the hash_func parameter, when using strings as keys in a GHashTable.
470
471	-- v : 	a string key.
472	-- Returns : 	a hash value corresponding to the key.
473feature -- size
474
475	struct_size: INTEGER is
476		external "C inline use <glib.h>"
477		alias "sizeof(GHashTable)"
478		end
479
480feature {} -- Low level implementation
481	print_no_fast_notice is
482		once
483			print(no_fast_notice)
484		end
485
486	no_fast_notice: STRING is
487		"Original C GHashTable implementation does not offer functions equivalent to `fast_has,' `fast_at', `fast_reference_at', `fast_put' and `fast_remove'. An eventual implementation of those features would require to manipulate directly GHashTable data-structure, skipping the Glib abstraction. Paolo 2007-07-15%N"
488
489	fast_fallback_notice: STRING is
490		"Fast_[has|at|reference_at|put|remove] feature not available. Falling back to non-fast features.%N"
491
492
493		--	steal (a_key: KEY): VALUE is
494		-- Removes a key and its associated value from a GHashTable
495		-- without calling the key and value destroy functions.
496	
497		-- `is_successful' is True if the key was found and removed
498		-- from the GHashTable.
499		-- require key_not_void: a_key /= Void
500
501		-- do is_successful := (g_hash_table_steal (handle,
502		-- a_key.handle)).to_boolean end
503
504		-- replace (a_key: KEY; a_value: VALUE) is Inserts a new key and
505		-- value into a GHashTable similar to g_hash_table_insert(). The
506		-- difference is that if the key already exists in the
507		-- GHashTable, it gets replaced by the new key. If you supplied
508		-- a value_destroy_func when creating the GHashTable, the old
509		-- value is freed using that function. If you supplied a
510		-- key_destroy_func when creating the GHashTable, the old key is
511		-- freed using that function.  hash_table : a GHashTable.  key :
512		-- a key to insert.  value : the value to associate with the
513		-- key.  require key_not_void: a_key /= Void value_not_void:
514		-- a_value /= Void do g_hash_table_replace (handle,
515		-- a_key.handle, a_value.handle) end
516	
517end