comparison src/elhash.c @ 272:c5d627a313b1 r21-0b34

Import from CVS: tag r21-0b34
author cvs
date Mon, 13 Aug 2007 10:28:48 +0200
parents 677f6a0ee643
children 8626e4521993
comparison
equal deleted inserted replaced
271:c7b7086b0a39 272:c5d627a313b1
25 #include <config.h> 25 #include <config.h>
26 #include "lisp.h" 26 #include "lisp.h"
27 #include "hash.h" 27 #include "hash.h"
28 #include "elhash.h" 28 #include "elhash.h"
29 #include "bytecode.h" 29 #include "bytecode.h"
30
31 EXFUN (Fmake_weak_hashtable, 2);
32 EXFUN (Fmake_key_weak_hashtable, 2);
33 EXFUN (Fmake_value_weak_hashtable, 2);
30 34
31 Lisp_Object Qhashtablep, Qhashtable; 35 Lisp_Object Qhashtablep, Qhashtable;
32 Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qnon_weak; 36 Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qnon_weak;
33 37
34 #define LISP_OBJECTS_PER_HENTRY (sizeof (hentry) / sizeof (Lisp_Object))/* 2 */ 38 #define LISP_OBJECTS_PER_HENTRY (sizeof (hentry) / sizeof (Lisp_Object))/* 2 */
45 Lisp_Object next_weak; /* Used to chain together all of the weak 49 Lisp_Object next_weak; /* Used to chain together all of the weak
46 hashtables. Don't mark through this. */ 50 hashtables. Don't mark through this. */
47 }; 51 };
48 52
49 static Lisp_Object Vall_weak_hashtables; 53 static Lisp_Object Vall_weak_hashtables;
50
51 static Lisp_Object mark_hashtable (Lisp_Object, void (*) (Lisp_Object));
52 static void print_hashtable (Lisp_Object, Lisp_Object, int);
53 static int hashtable_equal (Lisp_Object t1, Lisp_Object t2, int depth);
54 DEFINE_LRECORD_IMPLEMENTATION ("hashtable", hashtable,
55 mark_hashtable, print_hashtable, 0,
56 /* #### Implement hashtable_hash()! */
57 hashtable_equal, 0,
58 struct hashtable);
59 54
60 static Lisp_Object 55 static Lisp_Object
61 mark_hashtable (Lisp_Object obj, void (*markobj) (Lisp_Object)) 56 mark_hashtable (Lisp_Object obj, void (*markobj) (Lisp_Object))
62 { 57 {
63 struct hashtable *table = XHASHTABLE (obj); 58 struct hashtable *table = XHASHTABLE (obj);
255 sprintf (buf, " 0x%x>", table->header.uid); 250 sprintf (buf, " 0x%x>", table->header.uid);
256 write_c_string (buf, printcharfun); 251 write_c_string (buf, printcharfun);
257 } 252 }
258 } 253 }
259 254
255 DEFINE_LRECORD_IMPLEMENTATION ("hashtable", hashtable,
256 mark_hashtable, print_hashtable, 0,
257 /* #### Implement hashtable_hash()! */
258 hashtable_equal, 0,
259 struct hashtable);
260 260
261 /* Pretty reading of hashtables. 261 /* Pretty reading of hashtables.
262 262
263 Here we use the existing structures mechanism (which is, 263 Here we use the existing structures mechanism (which is,
264 unfortunately, pretty cumbersome) for validating and instantiating 264 unfortunately, pretty cumbersome) for validating and instantiating
348 hashtable_instantiate (Lisp_Object plist) 348 hashtable_instantiate (Lisp_Object plist)
349 { 349 {
350 /* I'm not sure whether this can GC, but better safe than sorry. */ 350 /* I'm not sure whether this can GC, but better safe than sorry. */
351 Lisp_Object hashtab = Qnil; 351 Lisp_Object hashtab = Qnil;
352 Lisp_Object type = Qnil, test = Qnil, size = Qnil, data = Qnil; 352 Lisp_Object type = Qnil, test = Qnil, size = Qnil, data = Qnil;
353 Lisp_Object key, value;
354 struct gcpro gcpro1; 353 struct gcpro gcpro1;
355 GCPRO1 (hashtab); 354 GCPRO1 (hashtab);
356 355
357 while (!NILP (plist)) 356 while (!NILP (plist))
358 { 357 {
359 key = XCAR (plist); 358 Lisp_Object key, value;
360 plist = XCDR (plist); 359 key = XCAR (plist); plist = XCDR (plist);
361 value = XCAR (plist); 360 value = XCAR (plist); plist = XCDR (plist);
362 plist = XCDR (plist); 361
363 if (EQ (key, Qtype)) 362 if (EQ (key, Qtype)) type = value;
364 type = value; 363 else if (EQ (key, Qtest)) test = value;
365 else if (EQ (key, Qtest)) 364 else if (EQ (key, Qsize)) size = value;
366 test = value; 365 else if (EQ (key, Qdata)) data = value;
367 else if (EQ (key, Qsize))
368 size = value;
369 else if (EQ (key, Qdata))
370 data = value;
371 else 366 else
372 abort (); 367 abort ();
373 } 368 }
369
374 if (NILP (type)) 370 if (NILP (type))
375 type = Qnon_weak; 371 type = Qnon_weak;
372
376 if (NILP (size)) 373 if (NILP (size))
377 { 374 /* Divide by two, because data is a plist. */
378 /* Divide by two, because data is a plist. */ 375 size = make_int (XINT (Flength (data)) / 2);
379 XSETINT (size, XINT (Flength (data)) / 2);
380 }
381 376
382 /* Create the hashtable. */ 377 /* Create the hashtable. */
383 if (EQ (type, Qnon_weak)) 378 if (EQ (type, Qnon_weak))
384 hashtab = Fmake_hashtable (size, test); 379 hashtab = Fmake_hashtable (size, test);
385 else if (EQ (type, Qweak)) 380 else if (EQ (type, Qweak))
392 abort (); 387 abort ();
393 388
394 /* And fill it with data. */ 389 /* And fill it with data. */
395 while (!NILP (data)) 390 while (!NILP (data))
396 { 391 {
397 key = XCAR (data); 392 Lisp_Object key, value;
398 data = XCDR (data); 393 key = XCAR (data); data = XCDR (data);
399 value = XCAR (data); 394 value = XCAR (data); data = XCDR (data);
400 data = XCDR (data);
401 Fputhash (key, value, hashtab); 395 Fputhash (key, value, hashtab);
402 } 396 }
403 397
404 UNGCPRO; 398 UNGCPRO;
405 return hashtab; 399 return hashtab;
635 signal_simple_error ("Invalid hashtable test function", sym); 629 signal_simple_error ("Invalid hashtable test function", sym);
636 return HASHTABLE_EQ; /* not reached */ 630 return HASHTABLE_EQ; /* not reached */
637 } 631 }
638 632
639 DEFUN ("make-hashtable", Fmake_hashtable, 1, 2, 0, /* 633 DEFUN ("make-hashtable", Fmake_hashtable, 1, 2, 0, /*
640 Make a hashtable of initial size SIZE. 634 Return a new hashtable object of initial size SIZE.
641 Comparison between keys is done with TEST-FUN, which must be one of 635 Comparison between keys is done with TEST-FUN, which must be one of
642 `eq', `eql', or `equal'. The default is `eql'; i.e. two keys must 636 `eq', `eql', or `equal'. The default is `eql'; i.e. two keys must
643 be the same object (or have the same floating-point value, for floats) 637 be the same object (or have the same floating-point value, for floats)
644 to be considered equivalent. 638 to be considered equivalent.
645 639
652 return make_lisp_hashtable (XINT (size), HASHTABLE_NONWEAK, 646 return make_lisp_hashtable (XINT (size), HASHTABLE_NONWEAK,
653 decode_hashtable_test_fun (test_fun)); 647 decode_hashtable_test_fun (test_fun));
654 } 648 }
655 649
656 DEFUN ("copy-hashtable", Fcopy_hashtable, 1, 1, 0, /* 650 DEFUN ("copy-hashtable", Fcopy_hashtable, 1, 1, 0, /*
657 Make a new hashtable which contains the same keys and values 651 Return a new hashtable containing the same keys and values as HASHTABLE.
658 as the given table. The keys and values will not themselves be copied. 652 The keys and values will not themselves be copied.
659 */ 653 */
660 (old_table)) 654 (hashtable))
661 { 655 {
662 struct _C_hashtable old_htbl; 656 struct _C_hashtable old_htbl;
663 struct _C_hashtable new_htbl; 657 struct _C_hashtable new_htbl;
664 struct hashtable *old_ht; 658 struct hashtable *old_ht;
665 struct hashtable *new_ht; 659 struct hashtable *new_ht;
666 Lisp_Object result; 660 Lisp_Object result;
667 661
668 CHECK_HASHTABLE (old_table); 662 CHECK_HASHTABLE (hashtable);
669 old_ht = XHASHTABLE (old_table); 663 old_ht = XHASHTABLE (hashtable);
670 ht_copy_to_c (old_ht, &old_htbl); 664 ht_copy_to_c (old_ht, &old_htbl);
671 665
672 /* we can't just call Fmake_hashtable() here because that will make a 666 /* we can't just call Fmake_hashtable() here because that will make a
673 table that is slightly larger than the one we're trying to copy, 667 table that is slightly larger than the one we're trying to copy,
674 which will make copy_hash() blow up. */ 668 which will make copy_hash() blow up. */
791 { 785 {
792 CHECK_HASHTABLE (hashtable); 786 CHECK_HASHTABLE (hashtable);
793 787
794 switch (XHASHTABLE (hashtable)->type) 788 switch (XHASHTABLE (hashtable)->type)
795 { 789 {
796 case HASHTABLE_WEAK: 790 case HASHTABLE_WEAK: return Qweak;
797 return Qweak; 791 case HASHTABLE_KEY_WEAK: return Qkey_weak;
798 break; 792 case HASHTABLE_VALUE_WEAK: return Qvalue_weak;
799 case HASHTABLE_KEY_WEAK: 793 default: return Qnon_weak;
800 return Qkey_weak;
801 break;
802 case HASHTABLE_VALUE_WEAK:
803 return Qvalue_weak;
804 break;
805 default:
806 return Qnon_weak;
807 } 794 }
808 } 795 }
809 796
810 DEFUN ("hashtable-test-function", Fhashtable_test_function, 1, 1, 0, /* 797 DEFUN ("hashtable-test-function", Fhashtable_test_function, 1, 1, 0, /*
811 Return test function of HASHTABLE. 798 Return test function of HASHTABLE.
830 static void 817 static void
831 verify_function (Lisp_Object function, CONST char *description) 818 verify_function (Lisp_Object function, CONST char *description)
832 { 819 {
833 /* #### Unused DESCRIPTION? */ 820 /* #### Unused DESCRIPTION? */
834 if (SYMBOLP (function)) 821 if (SYMBOLP (function))
835 { 822 {
836 if (NILP (function)) 823 if (NILP (function))
837 return; 824 return;
838 else 825 else
839 function = indirect_function (function, 1); 826 function = indirect_function (function, 1);
840 } 827 }
841 if (SUBRP (function) || COMPILED_FUNCTIONP (function)) 828 if (SUBRP (function) || COMPILED_FUNCTIONP (function))
842 return; 829 return;
843 else if (CONSP (function)) 830 else if (CONSP (function))
844 { 831 {
845 Lisp_Object funcar = XCAR (function); 832 Lisp_Object funcar = XCAR (function);
846 if ((SYMBOLP (funcar)) && (EQ (funcar, Qlambda) || 833 if ((SYMBOLP (funcar)) && (EQ (funcar, Qlambda) ||
847 EQ (funcar, Qautoload))) 834 EQ (funcar, Qautoload)))
848 return; 835 return;
849 } 836 }
850 signal_error (Qinvalid_function, list1 (function)); 837 signal_error (Qinvalid_function, list1 (function));
851 } 838 }
852 839
853 static int 840 static int
854 lisp_maphash_function (CONST void *void_key, 841 lisp_maphash_function (CONST void *void_key,
898 ht_copy_to_c (XHASHTABLE (hashtable), &htbl); 885 ht_copy_to_c (XHASHTABLE (hashtable), &htbl);
899 maphash (function, &htbl, closure); 886 maphash (function, &htbl, closure);
900 } 887 }
901 888
902 void 889 void
903 elisp_map_remhash (int (*function) (CONST void *key, 890 elisp_map_remhash (remhash_predicate function, Lisp_Object hashtable,
904 CONST void *contents,
905 void *extra_arg),
906 Lisp_Object hashtable,
907 void *closure) 891 void *closure)
908 { 892 {
909 struct _C_hashtable htbl; 893 struct _C_hashtable htbl;
910 894
911 if (!gc_in_progress) CHECK_HASHTABLE (hashtable); 895 if (!gc_in_progress) CHECK_HASHTABLE (hashtable);
928 #endif /* 0 */ 912 #endif /* 0 */
929 913
930 914
931 915
932 DEFUN ("make-weak-hashtable", Fmake_weak_hashtable, 1, 2, 0, /* 916 DEFUN ("make-weak-hashtable", Fmake_weak_hashtable, 1, 2, 0, /*
933 Make a fully weak hashtable of initial size SIZE. 917 Return a new fully weak hashtable object of initial size SIZE.
934 A weak hashtable is one whose pointers do not count as GC referents: 918 A weak hashtable is one whose pointers do not count as GC referents:
935 for any key-value pair in the hashtable, if the only remaining pointer 919 for any key-value pair in the hashtable, if the only remaining pointer
936 to either the key or the value is in a weak hash table, then the pair 920 to either the key or the value is in a weak hash table, then the pair
937 will be removed from the table, and the key and value collected. A 921 will be removed from the table, and the key and value collected. A
938 non-weak hash table (or any other pointer) would prevent the object 922 non-weak hash table (or any other pointer) would prevent the object
947 return make_lisp_hashtable (XINT (size), HASHTABLE_WEAK, 931 return make_lisp_hashtable (XINT (size), HASHTABLE_WEAK,
948 decode_hashtable_test_fun (test_fun)); 932 decode_hashtable_test_fun (test_fun));
949 } 933 }
950 934
951 DEFUN ("make-key-weak-hashtable", Fmake_key_weak_hashtable, 1, 2, 0, /* 935 DEFUN ("make-key-weak-hashtable", Fmake_key_weak_hashtable, 1, 2, 0, /*
952 Make a key-weak hashtable of initial size SIZE. 936 Return a new key-weak hashtable object of initial size SIZE.
953 A key-weak hashtable is similar to a fully-weak hashtable (see 937 A key-weak hashtable is similar to a fully-weak hashtable (see
954 `make-weak-hashtable') except that a key-value pair will be removed 938 `make-weak-hashtable') except that a key-value pair will be removed
955 only if the key remains unmarked outside of weak hashtables. The pair 939 only if the key remains unmarked outside of weak hashtables. The pair
956 will remain in the hashtable if the key is pointed to by something other 940 will remain in the hashtable if the key is pointed to by something other
957 than a weak hashtable, even if the value is not. 941 than a weak hashtable, even if the value is not.
962 return make_lisp_hashtable (XINT (size), HASHTABLE_KEY_WEAK, 946 return make_lisp_hashtable (XINT (size), HASHTABLE_KEY_WEAK,
963 decode_hashtable_test_fun (test_fun)); 947 decode_hashtable_test_fun (test_fun));
964 } 948 }
965 949
966 DEFUN ("make-value-weak-hashtable", Fmake_value_weak_hashtable, 1, 2, 0, /* 950 DEFUN ("make-value-weak-hashtable", Fmake_value_weak_hashtable, 1, 2, 0, /*
967 Make a value-weak hashtable of initial size SIZE. 951 Return a new value-weak hashtable object of initial size SIZE.
968 A value-weak hashtable is similar to a fully-weak hashtable (see 952 A value-weak hashtable is similar to a fully-weak hashtable (see
969 `make-weak-hashtable') except that a key-value pair will be removed only 953 `make-weak-hashtable') except that a key-value pair will be removed only
970 if the value remains unmarked outside of weak hashtables. The pair will 954 if the value remains unmarked outside of weak hashtables. The pair will
971 remain in the hashtable if the value is pointed to by something other 955 remain in the hashtable if the value is pointed to by something other
972 than a weak hashtable, even if the key is not. 956 than a weak hashtable, even if the key is not.