|
21 | 21 | * lookup key's hash value as a partition number --- this will work because |
22 | 22 | * of the way calc_bucket() maps hash values to bucket numbers. |
23 | 23 | * |
| 24 | + * For hash tables in shared memory, the memory allocator function should |
| 25 | + * match malloc's semantics of returning NULL on failure. For hash tables |
| 26 | + * in local memory, we typically use palloc() which will throw error on |
| 27 | + * failure. The code in this file has to cope with both cases. |
| 28 | + * |
24 | 29 | * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group |
25 | 30 | * Portions Copyright (c) 1994, Regents of the University of California |
26 | 31 | * |
@@ -820,6 +825,27 @@ hash_search_with_hash_value(HTAB *hashp, |
820 | 825 | hctl->accesses++; |
821 | 826 | #endif |
822 | 827 |
|
| 828 | + /* |
| 829 | + * If inserting, check if it is time to split a bucket. |
| 830 | + * |
| 831 | + * NOTE: failure to expand table is not a fatal error, it just means we |
| 832 | + * have to run at higher fill factor than we wanted. However, if we're |
| 833 | + * using the palloc allocator then it will throw error anyway on |
| 834 | + * out-of-memory, so we must do this before modifying the table. |
| 835 | + */ |
| 836 | + if (action == HASH_ENTER || action == HASH_ENTER_NULL) |
| 837 | + { |
| 838 | + /* |
| 839 | + * Can't split if running in partitioned mode, nor if frozen, nor if |
| 840 | + * table is the subject of any active hash_seq_search scans. Strange |
| 841 | + * order of these tests is to try to check cheaper conditions first. |
| 842 | + */ |
| 843 | + if (!IS_PARTITIONED(hctl) && !hashp->frozen && |
| 844 | + hctl->nentries / (long) (hctl->max_bucket + 1) >= hctl->ffactor && |
| 845 | + !has_seq_scans(hashp)) |
| 846 | + (void) expand_table(hashp); |
| 847 | + } |
| 848 | + |
823 | 849 | /* |
824 | 850 | * Do the initial lookup |
825 | 851 | */ |
@@ -940,24 +966,12 @@ hash_search_with_hash_value(HTAB *hashp, |
940 | 966 | currBucket->hashvalue = hashvalue; |
941 | 967 | hashp->keycopy(ELEMENTKEY(currBucket), keyPtr, keysize); |
942 | 968 |
|
943 | | - /* caller is expected to fill the data field on return */ |
944 | | - |
945 | 969 | /* |
946 | | - * Check if it is time to split a bucket. Can't split if running |
947 | | - * in partitioned mode, nor if table is the subject of any active |
948 | | - * hash_seq_search scans. Strange order of these tests is to try |
949 | | - * to check cheaper conditions first. |
| 970 | + * Caller is expected to fill the data field on return. DO NOT |
| 971 | + * insert any code that could possibly throw error here, as doing |
| 972 | + * so would leave the table entry incomplete and hence corrupt the |
| 973 | + * caller's data structure. |
950 | 974 | */ |
951 | | - if (!IS_PARTITIONED(hctl) && |
952 | | - hctl->nentries / (long) (hctl->max_bucket + 1) >= hctl->ffactor && |
953 | | - !has_seq_scans(hashp)) |
954 | | - { |
955 | | - /* |
956 | | - * NOTE: failure to expand table is not a fatal error, it just |
957 | | - * means we have to run at higher fill factor than we wanted. |
958 | | - */ |
959 | | - expand_table(hashp); |
960 | | - } |
961 | 975 |
|
962 | 976 | return (void *) ELEMENTKEY(currBucket); |
963 | 977 | } |
|
0 commit comments