func (p *partitionImpl) AppendRowData(row sif.Row) error {
	if err := p.CanInsertRowData(row); err != nil {
		return err
	}
	iRow := row.(*rowImpl)
	err := p.schema.ForEachColumn(func(name string, col sif.Column) error {
		p.deserializeColumn(name)
		p.setColumnDirty(name)  
		iRow.partition.deserializeColumn(name)
		if sif.IsVariableLength(col.Type()) {
			source := iRow.partition.activeVarLengthData[name]
			dest := p.activeVarLengthData[name]
			dest[p.internalData.NumRows] = source[iRow.rowNum]
		} else {
			source := iRow.partition.activeColData[name]
			dest := p.activeColData[name]
			size := col.Type().Size()
			value := source[iRow.rowNum*size : (iRow.rowNum+1)*size]
			copy(dest[int(p.internalData.NumRows)*size:(int(p.internalData.NumRows)+1)*size], value)
		}
		sourceMeta := iRow.partition.internalData.ColData[name].Meta
		p.internalData.ColData[name].Meta[p.internalData.NumRows] = sourceMeta[iRow.rowNum]
		return nil
	})
	if err != nil {
		return err
	}
	if p.IsKeyed() && iRow.partition.IsKeyed() {
		p.internalData.Keys[p.internalData.NumRows] = iRow.partition.internalData.Keys[iRow.rowNum]
	} else if p.IsKeyed() && !iRow.partition.IsKeyed() {
		return fmt.Errorf("unable to append unkeyed row to a keyed partition")
	}
	p.internalData.NumRows++
	return nil
}
AppendRowData adds a Row to the end of this Partition, if it isn't full and if the Row fits within the schema
package partition
import (
	"fmt"
	"github.com/go-sif/sif"
	errors "github.com/go-sif/sif/errors"
)
func CreateBuildablePartition(maxRows int, schema sif.Schema) sif.BuildablePartition {
	return createPartitionImpl(maxRows, maxRows, schema)
}
func (p *partitionImpl) growPartition() {
	newCapacity := p.internalData.Capacity * 2
	if newCapacity > p.internalData.MaxRows {
		newCapacity = p.internalData.MaxRows
	}
	numRows := int(p.internalData.NumRows)
	err := p.schema.ForEachColumn(func(name string, col sif.Column) error {
		if p.columnIsDeserialized(name) {
			if !sif.IsVariableLength(col.Type()) {
				newActiveColData := make([]byte, col.Type().Size()*int(newCapacity))
				copy(newActiveColData, p.activeColData[name][0:numRows*col.Type().Size()])
				p.activeColData[name] = newActiveColData
			} else {
				newActiveVarLengthData := make([]interface{}, int(newCapacity))
				oldActiveVarLengthData := p.activeVarLengthData[name]
				copy(newActiveVarLengthData, oldActiveVarLengthData[0:numRows])
				p.activeVarLengthData[name] = newActiveVarLengthData
			}
		}
		newMeta := make([]byte, newCapacity)
		copy(newMeta, p.internalData.ColData[name].Meta[0:numRows])
		p.internalData.ColData[name].Meta = newMeta
		return nil
	})
	if err != nil {
		panic(err)
	}
	if p.IsKeyed() {
		newKeys := make([]uint64, newCapacity)
		copy(newKeys, p.internalData.Keys[0:numRows])
		p.internalData.Keys = newKeys
	}
	p.internalData.Capacity = newCapacity
}
func (p *partitionImpl) CanInsertRowData(row sif.Row) error {
	iRow := row.(*rowImpl)
	if p.internalData.NumRows >= p.internalData.MaxRows {
		return errors.PartitionFullError{}
	}
	if err := iRow.partition.schema.Equals(p.schema); err != nil {
		return err
	}
	if p.internalData.NumRows >= p.internalData.Capacity {
		p.growPartition()
		return nil
	}
	return nil
}
func (p *partitionImpl) AppendEmptyRowData(tempRow sif.Row) (sif.Row, error) {
	if p.internalData.NumRows >= p.internalData.MaxRows {
		return nil, errors.PartitionFullError{}
	} else if p.internalData.NumRows >= p.internalData.Capacity {
		p.growPartition()
	}
	p.internalData.NumRows++
	return p.getRow(tempRow.(*rowImpl), int(p.internalData.NumRows)-1), nil
}