Hi ZizhuanLiu,

> Rebase v4 .

Thanks for the rebase. I read through the v4 refactor of
ReserveXLogSwitch() -- computing the standard EndPos once and reusing it
reads much cleaner than the previous duplicated arithmetic. A few small,
behavior-neutral suggestions on the new out-parameter, in case you'd like
to fold them into the next version:

1) Naming. Of the three, this is the one I'd really like to see in the
next version. The parameter is spelled actual_EndPos, which is neither
snake_case nor CamelCase -- an underscore-separated lowercase prefix glued
to a CamelCase tail -- unlike its sibling out-parameters in the same
function (StartPos, EndPos, PrevPtr) that are plain CamelCase; and
"actual" doesn't say what it is actual relative to.
Since it carries the end of the record itself -- as opposed to EndPos,
which is padded out to the segment boundary -- I'd suggest RecEndPos,
which matches the surrounding names:

    static bool ReserveXLogSwitch(XLogRecPtr *StartPos, XLogRecPtr *EndPos,
                                  XLogRecPtr *PrevPtr, XLogRecPtr
*RecEndPos);

2) Drop the NULL guard on the out-parameter. There is a single caller and
it always passes &..., exactly like the other three out-parameters, which
are dereferenced unconditionally. Guarding only this one is inconsistent:

    /* Store the end position of just the record. */
    *RecEndPos = *EndPos;

To keep that unconditional store safe, the early "already at a segment
boundary" return should set it too:

    if (XLogSegmentOffset(ptr, wal_segment_size) == 0)
    {
        SpinLockRelease(&Insert->insertpos_lck);
        *EndPos = *StartPos = ptr;
        *RecEndPos = ptr;
        return false;
    }

3) With RecEndPos always populated, the `if (inserted)` guard around the
EndPos fixup in XLogInsertRecord() is no longer needed -- when nothing was
inserted RecEndPos already equals EndPos, so the assignment is a harmless
no-op:

    /*
     * Even though we reserved the rest of the segment for us, which is
     * reflected in EndPos, we return a pointer to just the end of the
     * xlog-switch record, which is consistent with other WAL types
     * returned by XLogBytePosToEndRecPtr().  When no switch record was
     * inserted, RecEndPos already equals EndPos, so this is a no-op.
     */
    EndPos = RecEndPos;

None of this changes behavior; it just localizes the invariant inside
ReserveXLogSwitch() and makes the out-parameters uniform. (2) and (3) are
take-it-or-leave-it -- the rename is the only one I feel strongly about.
Feel free to fold in whichever you find worthwhile for the next version.

Regards,
Henson

Reply via email to