Method: (TRANSACTION-COMMIT-1 STANDARD-TRANSACTION STANDARD-CACHE STANDARD-RUCKSACK)

Source

(defmethod transaction-commit-1 ((transaction standard-transaction)
                                 (cache standard-cache)
                                 (rucksack standard-rucksack))
  ;; Save all dirty objects to disk.
  (if (zerop (transaction-nr-dirty-objects transaction))
      (close-transaction cache transaction)
    (progn
      ;; 1. Create the commit file
      (create-commit-file transaction cache)
      ;; 2. Commit all dirty objects.
      ;; Q: What if this is interleaved with other commits?
      (let ((queue (dirty-queue transaction))
            (table (dirty-objects transaction))
            (heap (heap cache))
            nr-allocated-octets)
        (with-allocation-counter (heap)
          (loop until (queue-empty-p queue)
                do (let* ((id (queue-remove queue))
                          (object (gethash id table)))
                     (when object
                       ;; If it's not in the dirty-objects table anymore, the
                       ;; object was already saved during this transaction-commit.
                       ;; That's possible, because the queue can contain duplicates.
                       (save-dirty-object object cache transaction id)
                       ;; Remove from hash-table too.
                       (remhash id table))))
          (setq nr-allocated-octets (nr-allocated-octets heap)))
        ;; Check for consistency between hash table and queue.
        (unless (zerop (hash-table-count table))
          (internal-rucksack-error
           "Mismatch between dirty hash-table and queue while committing ~S:
~D objects left in hash-table."
           transaction
           (hash-table-count table)))
        ;; 3. Remove transaction from the cache's open transactions.
        (close-transaction cache transaction)
        ;; 4. Delete the commit file to indicate that everything went fine
        ;; and we don't need to recover from this commit.
        (delete-commit-file transaction cache)
        ;; 5. Let the garbage collector do an amount of work proportional
        ;; to the number of octets that were allocated during the commit.
        (when *collect-garbage-on-commit*
          (collect-some-garbage heap
                                (gc-work-for-size heap nr-allocated-octets)))
        ;; 6. Make sure that all changes are actually on disk before
        ;; we continue.
        (finish-all-output rucksack)))))
Source Context