Compress records before checking segment size
Right now a new segment might be created unnecessarily if the
uncompressed record would not fit, but after compression (typically
reducing record size in half) it would.
@@ -613,18 +613,8 @@ func (w *WAL) log(rec []byte, final bool) error {
return err
}
}
- // If the record is too big to fit within the active page in the current
- // segment, terminate the active segment and advance to the next one.
- // This ensures that records do not cross segment boundaries.
- left := w.page.remaining() - recordHeaderSize // Free space in the active page.
- left += (pageSize - recordHeaderSize) * (w.pagesPerSegment() - w.donePages - 1) // Free pages in the active segment.
-
- if len(rec) > left {
- if err := w.nextSegment(); err != nil {
- return err
- }
- }
+ // Compress the record before calculating if a new segment is needed.
compressed := false
if w.compress && len(rec) > 0 {
// The snappy library uses `len` to calculate if we need a new buffer.
@@ -638,6 +628,18 @@ func (w *WAL) log(rec []byte, final bool) error {
}
}
+ // If the record is too big to fit within the active page in the current
+ // segment, terminate the active segment and advance to the next one.
+ // This ensures that records do not cross segment boundaries.
+ left := w.page.remaining() - recordHeaderSize // Free space in the active page.
+ left += (pageSize - recordHeaderSize) * (w.pagesPerSegment() - w.donePages - 1) // Free pages in the active segment.
+
+ if len(rec) > left {
+ if err := w.nextSegment(); err != nil {
+ return err
+ }
+ }
+
// Populate as many pages as necessary to fit the record.
// Be careful to always do one pass to ensure we write zero-length records.
for i := 0; i == 0 || len(rec) > 0; i++ {
