Mercurial > hg > xemacs-beta
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. |