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 {