Mercurial > hg > xemacs-beta
comparison src/elhash.c @ 440:8de8e3f6228a r21-2-28
Import from CVS: tag r21-2-28
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:33:38 +0200 |
parents | 84b14dcb0985 |
children | abe6d1db359e |
comparison
equal
deleted
inserted
replaced
439:357dd071b03c | 440:8de8e3f6228a |
---|---|
57 hentry *hentries; | 57 hentry *hentries; |
58 enum hash_table_weakness weakness; | 58 enum hash_table_weakness weakness; |
59 Lisp_Object next_weak; /* Used to chain together all of the weak | 59 Lisp_Object next_weak; /* Used to chain together all of the weak |
60 hash tables. Don't mark through this. */ | 60 hash tables. Don't mark through this. */ |
61 }; | 61 }; |
62 typedef struct Lisp_Hash_Table Lisp_Hash_Table; | |
63 | 62 |
64 #define HENTRY_CLEAR_P(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) == 0) | 63 #define HENTRY_CLEAR_P(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) == 0) |
65 #define CLEAR_HENTRY(hentry) \ | 64 #define CLEAR_HENTRY(hentry) \ |
66 ((*(EMACS_UINT*)(&((hentry)->key))) = 0, \ | 65 ((*(EMACS_UINT*)(&((hentry)->key))) = 0, \ |
67 (*(EMACS_UINT*)(&((hentry)->value))) = 0) | 66 (*(EMACS_UINT*)(&((hentry)->value))) = 0) |
372 ht->hentries = 0; | 371 ht->hentries = 0; |
373 } | 372 } |
374 } | 373 } |
375 | 374 |
376 static const struct lrecord_description hentry_description_1[] = { | 375 static const struct lrecord_description hentry_description_1[] = { |
377 { XD_LISP_OBJECT, offsetof(hentry, key), 2 }, | 376 { XD_LISP_OBJECT, offsetof (hentry, key) }, |
377 { XD_LISP_OBJECT, offsetof (hentry, value) }, | |
378 { XD_END } | 378 { XD_END } |
379 }; | 379 }; |
380 | 380 |
381 static const struct struct_description hentry_description = { | 381 static const struct struct_description hentry_description = { |
382 sizeof(hentry), | 382 sizeof (hentry), |
383 hentry_description_1 | 383 hentry_description_1 |
384 }; | 384 }; |
385 | 385 |
386 const struct lrecord_description hash_table_description[] = { | 386 const struct lrecord_description hash_table_description[] = { |
387 { XD_SIZE_T, offsetof(Lisp_Hash_Table, size) }, | 387 { XD_SIZE_T, offsetof (Lisp_Hash_Table, size) }, |
388 { XD_STRUCT_PTR, offsetof(Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description }, | 388 { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description }, |
389 { XD_LO_LINK, offsetof(Lisp_Hash_Table, next_weak) }, | 389 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) }, |
390 { XD_END } | 390 { XD_END } |
391 }; | 391 }; |
392 | 392 |
393 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table, | 393 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table, |
394 mark_hash_table, print_hash_table, | 394 mark_hash_table, print_hash_table, |
881 } | 881 } |
882 | 882 |
883 static void | 883 static void |
884 resize_hash_table (Lisp_Hash_Table *ht, size_t new_size) | 884 resize_hash_table (Lisp_Hash_Table *ht, size_t new_size) |
885 { | 885 { |
886 hentry *old_entries, *new_entries, *old_sentinel, *new_sentinel, *e; | 886 hentry *old_entries, *new_entries, *sentinel, *e; |
887 size_t old_size; | 887 size_t old_size; |
888 | 888 |
889 old_size = ht->size; | 889 old_size = ht->size; |
890 ht->size = new_size; | 890 ht->size = new_size; |
891 | 891 |
892 old_entries = ht->hentries; | 892 old_entries = ht->hentries; |
893 | 893 |
894 ht->hentries = xnew_array (hentry, new_size + 1); | 894 ht->hentries = xnew_array_and_zero (hentry, new_size + 1); |
895 new_entries = ht->hentries; | 895 new_entries = ht->hentries; |
896 | 896 |
897 old_sentinel = old_entries + old_size; | |
898 new_sentinel = new_entries + new_size; | |
899 | |
900 for (e = new_entries; e <= new_sentinel; e++) | |
901 CLEAR_HENTRY (e); | |
902 | |
903 compute_hash_table_derived_values (ht); | 897 compute_hash_table_derived_values (ht); |
904 | 898 |
905 for (e = old_entries; e < old_sentinel; e++) | 899 for (e = old_entries, sentinel = e + old_size; e < sentinel; e++) |
906 if (!HENTRY_CLEAR_P (e)) | 900 if (!HENTRY_CLEAR_P (e)) |
907 { | 901 { |
908 hentry *probe = new_entries + HASH_CODE (e->key, ht); | 902 hentry *probe = new_entries + HASH_CODE (e->key, ht); |
909 LINEAR_PROBING_LOOP (probe, new_entries, new_size) | 903 LINEAR_PROBING_LOOP (probe, new_entries, new_size) |
910 ; | 904 ; |
913 | 907 |
914 if (!DUMPEDP (old_entries)) | 908 if (!DUMPEDP (old_entries)) |
915 xfree (old_entries); | 909 xfree (old_entries); |
916 } | 910 } |
917 | 911 |
912 /* After a hash table has been saved to disk and later restored by the | |
913 portable dumper, it contains the same objects, but their addresses | |
914 and thus their HASH_CODEs have changed. */ | |
918 void | 915 void |
919 reorganize_hash_table (Lisp_Hash_Table *ht) | 916 pdump_reorganize_hash_table (Lisp_Object hash_table) |
920 { | 917 { |
921 resize_hash_table (ht, ht->size); | 918 CONST Lisp_Hash_Table *ht = xhash_table (hash_table); |
919 hentry *new_entries = xnew_array_and_zero (hentry, ht->size + 1); | |
920 hentry *e, *sentinel; | |
921 | |
922 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) | |
923 if (!HENTRY_CLEAR_P (e)) | |
924 { | |
925 hentry *probe = new_entries + HASH_CODE (e->key, ht); | |
926 LINEAR_PROBING_LOOP (probe, new_entries, ht->size) | |
927 ; | |
928 *probe = *e; | |
929 } | |
930 | |
931 memcpy (ht->hentries, new_entries, ht->size * sizeof (hentry)); | |
932 | |
933 xfree (new_entries); | |
922 } | 934 } |
923 | 935 |
924 static void | 936 static void |
925 enlarge_hash_table (Lisp_Hash_Table *ht) | 937 enlarge_hash_table (Lisp_Hash_Table *ht) |
926 { | 938 { |