示例#1
0
// NewRowContainer allocates a new row container.
//
// The acc argument indicates where to register memory allocations by
// this row container. Should probably be created by
// Session.makeSessionBoundAccount() or Session.makeTxnBoundAccount().
//
// The rowCapacity argument indicates how many rows are to be
// expected; it is used to pre-allocate the outer array of row
// references, in the fashion of Go's capacity argument to the make()
// function.
//
// Note that we could, but do not (yet), report the size of the row
// container itself to the monitor in this constructor. This is
// because the various planNodes are not (yet) equipped to call
// Close() upon encountering errors in their constructor (all nodes
// initializing a RowContainer there) and SetLimitHint() (for sortNode
// which initializes a RowContainer there). This would be rather
// error-prone to implement consistently and hellishly difficult to
// test properly.  The trade-off is that very large table schemas or
// column selections could cause unchecked and potentially dangerous
// memory growth.
func (p *planner) NewRowContainer(
	acc mon.BoundAccount, h ResultColumns, rowCapacity int,
) *RowContainer {
	nCols := len(h)

	res := &RowContainer{
		rows:            make([]parser.DTuple, 0, rowCapacity),
		numCols:         nCols,
		varSizedColumns: make([]int, 0, nCols),
		memAcc:          acc,
	}

	for i := 0; i < nCols; i++ {
		sz, variable := h[i].Typ.Size()
		if variable {
			res.varSizedColumns = append(res.varSizedColumns, i)
		} else {
			res.fixedColsSize += int64(sz)
		}
	}
	res.fixedColsSize += int64(unsafe.Sizeof(parser.Datum(nil)) * uintptr(nCols))

	return res
}
示例#2
0
// NewRowContainer allocates a new row container.
//
// The acc argument indicates where to register memory allocations by
// this row container. Should probably be created by
// Session.makeBoundAccount() or Session.TxnState.makeBoundAccount().
//
// The rowCapacity argument indicates how many rows are to be
// expected; it is used to pre-allocate the outer array of row
// references, in the fashion of Go's capacity argument to the make()
// function.
//
// Note that we could, but do not (yet), report the size of the row
// container itself to the monitor in this constructor. This is
// because the various planNodes are not (yet) equipped to call
// Close() upon encountering errors in their constructor (all nodes
// initializing a RowContainer there) and SetLimitHint() (for sortNode
// which initializes a RowContainer there). This would be rather
// error-prone to implement consistently and hellishly difficult to
// test properly.  The trade-off is that very large table schemas or
// column selections could cause unchecked and potentially dangerous
// memory growth.
func NewRowContainer(acc mon.BoundAccount, h ResultColumns, rowCapacity int) *RowContainer {
	nCols := len(h)

	c := &RowContainer{
		numCols:        nCols,
		memAcc:         acc,
		preallocChunks: 1,
	}

	if nCols != 0 {
		c.rowsPerChunk = (targetChunkSize + nCols - 1) / nCols
		if rowCapacity > 0 {
			c.preallocChunks = (rowCapacity + c.rowsPerChunk - 1) / c.rowsPerChunk
		}
	}

	for i := 0; i < nCols; i++ {
		sz, variable := h[i].Typ.Size()
		if variable {
			if c.varSizedColumns == nil {
				// Only allocate varSizedColumns if necessary.
				c.varSizedColumns = make([]int, 0, nCols)
			}
			c.varSizedColumns = append(c.varSizedColumns, i)
		} else {
			c.fixedColsSize += int64(sz)
		}
	}

	// Precalculate the memory used for a chunk, specifically by the Datums in the
	// chunk and the slice pointing at the chunk.
	c.chunkMemSize = int64(unsafe.Sizeof(parser.Datum(nil))) * int64(c.rowsPerChunk*c.numCols)
	c.chunkMemSize += int64(unsafe.Sizeof([]parser.Datum(nil)))

	return c
}
示例#3
0
// Author: Irfan Sharif ([email protected])

package sql

import (
	"fmt"
	"unsafe"

	"github.com/cockroachdb/cockroach/pkg/sql/mon"
	"github.com/cockroachdb/cockroach/pkg/sql/parser"
)

const (
	// targetChunkSize is the target number of Datums in a RowContainer chunk.
	targetChunkSize = 64
	sizeOfDatum     = int64(unsafe.Sizeof(parser.Datum(nil)))
	sizeOfDTuple    = int64(unsafe.Sizeof(parser.DTuple(nil)))
)

// RowContainer is a container for rows of DTuples which tracks the
// approximate amount of memory allocated for row data.
// Rows must be added using AddRow(); once the work is done
// the Close() method must be called to release the allocated memory.
//
// TODO(knz): this does not currently track the amount of memory used
// for the outer array of DTuple references.
type RowContainer struct {
	numCols int

	// rowsPerChunk is the number of rows in a chunk; we pack multiple rows in a
	// single []Datum to reduce the overhead of the slice if we have few columns.