{
HASHCTL hash_ctl;
+ /* Make array first; existence of hash table asserts array exists */
+ comboCids = (ComboCidKeyData *)
+ MemoryContextAlloc(TopTransactionContext,
+ sizeof(ComboCidKeyData) * CCID_ARRAY_SIZE);
+ sizeComboCids = CCID_ARRAY_SIZE;
+ usedComboCids = 0;
+
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(ComboCidKeyData);
hash_ctl.entrysize = sizeof(ComboCidEntryData);
CCID_HASH_SIZE,
&hash_ctl,
HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
+ }
+
+ /*
+ * Grow the array if there's not at least one free slot. We must do this
+ * before possibly entering a new hashtable entry, else failure to
+ * repalloc would leave a corrupt hashtable entry behind.
+ */
+ if (usedComboCids >= sizeComboCids)
+ {
+ int newsize = sizeComboCids * 2;
comboCids = (ComboCidKeyData *)
- MemoryContextAlloc(TopTransactionContext,
- sizeof(ComboCidKeyData) * CCID_ARRAY_SIZE);
- sizeComboCids = CCID_ARRAY_SIZE;
- usedComboCids = 0;
+ repalloc(comboCids, sizeof(ComboCidKeyData) * newsize);
+ sizeComboCids = newsize;
}
/* Lookup or create a hash entry with the desired cmin/cmax */
return entry->combocid;
}
- /*
- * We have to create a new combo cid. Check that there's room for it in
- * the array, and grow it if there isn't.
- */
- if (usedComboCids >= sizeComboCids)
- {
- /* We need to grow the array */
- int newsize = sizeComboCids * 2;
-
- comboCids = (ComboCidKeyData *)
- repalloc(comboCids, sizeof(ComboCidKeyData) * newsize);
- sizeComboCids = newsize;
- }
-
+ /* We have to create a new combo cid; we already made room in the array */
combocid = usedComboCids;
comboCids[combocid].cmin = cmin;
elog(ERROR, "not enough space to serialize ComboCID state");
/* Now, copy the actual cmin/cmax pairs. */
- memcpy(start_address + sizeof(int), comboCids,
- (sizeof(ComboCidKeyData) * usedComboCids));
+ if (usedComboCids > 0)
+ memcpy(start_address + sizeof(int), comboCids,
+ (sizeof(ComboCidKeyData) * usedComboCids));
}
/*