More initialization code.
authorRobert Haas <[email protected]>
Fri, 13 Jul 2012 23:09:26 +0000 (19:09 -0400)
committerRobert Haas <[email protected]>
Tue, 24 Jul 2012 16:31:53 +0000 (12:31 -0400)
src/backend/utils/hash/chash.c

index 3d9adca098f3bde3e61b0204e1a88ee3a4873864..50fdafca430af2b8052dab12d244ad00757e7ddf 100644 (file)
@@ -19,7 +19,9 @@
  * while arena offsets can be stored in a 32-bit word.  In fact, we
  * reserve one bit in each such word as a mark bit, so the maximum size
  * of the arena is 2^31 elements, a restriction that does not currently
- * appear to be problematic.
+ * appear to be problematic.  An additional advantage of this representation
+ * is that aligned 32-bit loads and stores are atomic on all architectures
+ * we support, but 64-bit loads and stores are not.
  *
  * When an element is inserted, we copy the data from the backend-private
  * object supplied by the caller into one of these shared-memory entities.
@@ -250,6 +252,7 @@ CHashInitialize(CHashTable table, CHashDescriptor *desc)
        Size    size;
        bool    found;
        void   *shmem;
+       uint32  i;
 
        /*
         * If we're under the postmaster, this must be the EXEC_BACKEND case where
@@ -286,8 +289,32 @@ CHashInitialize(CHashTable table, CHashDescriptor *desc)
        /* Arena follows the various lists. */
        table->arena = (void *) (&table->freelist[table->nfreelists]);
 
-       /* XXX. Must initialize spinlocks, set lists to empty, and then put
-        * all arena nodes on free lists. */
+       /* Initialize all three sets of lists to empty. */
+       for (i = 0; i < table->nbuckets; ++i)
+       {
+               table->bucket[i].head = InvalidCHashPtr;
+               SpinLockInit(&table->bucket[i].head);
+       }
+       for (i = 0; i < table->ngarbage; ++i)
+       {
+               table->garbage[i].head = InvalidCHashPtr;
+               SpinLockInit(&table->garbage[i].head);
+       }
+       for (i = 0; i < table->nfreelists; ++i)
+       {
+               table->freelist[i].head = InvalidCHashPtr;
+               SpinLockInit(&table->freelist[i].head);
+       }
+
+       /* Put all arena elements on the free lists. */
+       for (i = 0; i < table->arena_limit; ++i)
+       {
+               CHashBucket        *f = &table->freelist[i % table->nfreelists];
+               CHashNode          *n = CHashTableGetNode(table, i);
+
+               n->next = f->head;
+               f->head = i;
+       }
 
        /*
         * Copy table (with pointers now filled in) to shared memory.  This is