github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sqlbase/datum_alloc.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package sqlbase
    12  
    13  import (
    14  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    15  	"github.com/cockroachdb/cockroach/pkg/util"
    16  )
    17  
    18  // DatumAlloc provides batch allocation of datum pointers, amortizing the cost
    19  // of the allocations.
    20  // NOTE: it *must* be passed in by a pointer.
    21  type DatumAlloc struct {
    22  	_ util.NoCopy
    23  
    24  	datumAlloc        []tree.Datum
    25  	dintAlloc         []tree.DInt
    26  	dfloatAlloc       []tree.DFloat
    27  	dstringAlloc      []tree.DString
    28  	dbytesAlloc       []tree.DBytes
    29  	dbitArrayAlloc    []tree.DBitArray
    30  	ddecimalAlloc     []tree.DDecimal
    31  	ddateAlloc        []tree.DDate
    32  	denumAlloc        []tree.DEnum
    33  	dgeometryAlloc    []tree.DGeometry
    34  	dgeographyAlloc   []tree.DGeography
    35  	dtimeAlloc        []tree.DTime
    36  	dtimetzAlloc      []tree.DTimeTZ
    37  	dtimestampAlloc   []tree.DTimestamp
    38  	dtimestampTzAlloc []tree.DTimestampTZ
    39  	dintervalAlloc    []tree.DInterval
    40  	duuidAlloc        []tree.DUuid
    41  	dipnetAlloc       []tree.DIPAddr
    42  	djsonAlloc        []tree.DJSON
    43  	dtupleAlloc       []tree.DTuple
    44  	doidAlloc         []tree.DOid
    45  	scratch           []byte
    46  	env               tree.CollationEnvironment
    47  }
    48  
    49  const datumAllocSize = 16      // Arbitrary, could be tuned.
    50  const datumAllocMultiplier = 4 // Arbitrary, could be tuned.
    51  
    52  // NewDatums allocates Datums of the specified size.
    53  func (a *DatumAlloc) NewDatums(num int) tree.Datums {
    54  	buf := &a.datumAlloc
    55  	if len(*buf) < num {
    56  		extensionSize := datumAllocSize
    57  		if extTupleLen := num * datumAllocMultiplier; extensionSize < extTupleLen {
    58  			extensionSize = extTupleLen
    59  		}
    60  		*buf = make(tree.Datums, extensionSize)
    61  	}
    62  	r := (*buf)[:num]
    63  	*buf = (*buf)[num:]
    64  	return r
    65  }
    66  
    67  // NewDInt allocates a DInt.
    68  func (a *DatumAlloc) NewDInt(v tree.DInt) *tree.DInt {
    69  	buf := &a.dintAlloc
    70  	if len(*buf) == 0 {
    71  		*buf = make([]tree.DInt, datumAllocSize)
    72  	}
    73  	r := &(*buf)[0]
    74  	*r = v
    75  	*buf = (*buf)[1:]
    76  	return r
    77  }
    78  
    79  // NewDFloat allocates a DFloat.
    80  func (a *DatumAlloc) NewDFloat(v tree.DFloat) *tree.DFloat {
    81  	buf := &a.dfloatAlloc
    82  	if len(*buf) == 0 {
    83  		*buf = make([]tree.DFloat, datumAllocSize)
    84  	}
    85  	r := &(*buf)[0]
    86  	*r = v
    87  	*buf = (*buf)[1:]
    88  	return r
    89  }
    90  
    91  // NewDString allocates a DString.
    92  func (a *DatumAlloc) NewDString(v tree.DString) *tree.DString {
    93  	buf := &a.dstringAlloc
    94  	if len(*buf) == 0 {
    95  		*buf = make([]tree.DString, datumAllocSize)
    96  	}
    97  	r := &(*buf)[0]
    98  	*r = v
    99  	*buf = (*buf)[1:]
   100  	return r
   101  }
   102  
   103  // NewDName allocates a DName.
   104  func (a *DatumAlloc) NewDName(v tree.DString) tree.Datum {
   105  	return tree.NewDNameFromDString(a.NewDString(v))
   106  }
   107  
   108  // NewDBytes allocates a DBytes.
   109  func (a *DatumAlloc) NewDBytes(v tree.DBytes) *tree.DBytes {
   110  	buf := &a.dbytesAlloc
   111  	if len(*buf) == 0 {
   112  		*buf = make([]tree.DBytes, datumAllocSize)
   113  	}
   114  	r := &(*buf)[0]
   115  	*r = v
   116  	*buf = (*buf)[1:]
   117  	return r
   118  }
   119  
   120  // NewDBitArray allocates a DBitArray.
   121  func (a *DatumAlloc) NewDBitArray(v tree.DBitArray) *tree.DBitArray {
   122  	buf := &a.dbitArrayAlloc
   123  	if len(*buf) == 0 {
   124  		*buf = make([]tree.DBitArray, datumAllocSize)
   125  	}
   126  	r := &(*buf)[0]
   127  	*r = v
   128  	*buf = (*buf)[1:]
   129  	return r
   130  }
   131  
   132  // NewDDecimal allocates a DDecimal.
   133  func (a *DatumAlloc) NewDDecimal(v tree.DDecimal) *tree.DDecimal {
   134  	buf := &a.ddecimalAlloc
   135  	if len(*buf) == 0 {
   136  		*buf = make([]tree.DDecimal, datumAllocSize)
   137  	}
   138  	r := &(*buf)[0]
   139  	*r = v
   140  	*buf = (*buf)[1:]
   141  	return r
   142  }
   143  
   144  // NewDDate allocates a DDate.
   145  func (a *DatumAlloc) NewDDate(v tree.DDate) *tree.DDate {
   146  	buf := &a.ddateAlloc
   147  	if len(*buf) == 0 {
   148  		*buf = make([]tree.DDate, datumAllocSize)
   149  	}
   150  	r := &(*buf)[0]
   151  	*r = v
   152  	*buf = (*buf)[1:]
   153  	return r
   154  }
   155  
   156  // NewDEnum allocates a DEnum.
   157  func (a *DatumAlloc) NewDEnum(v tree.DEnum) *tree.DEnum {
   158  	buf := &a.denumAlloc
   159  	if len(*buf) == 0 {
   160  		*buf = make([]tree.DEnum, datumAllocSize)
   161  	}
   162  	r := &(*buf)[0]
   163  	*r = v
   164  	*buf = (*buf)[1:]
   165  	return r
   166  }
   167  
   168  // NewDGeography allocates a DGeography.
   169  func (a *DatumAlloc) NewDGeography(v tree.DGeography) *tree.DGeography {
   170  	buf := &a.dgeographyAlloc
   171  	if len(*buf) == 0 {
   172  		*buf = make([]tree.DGeography, datumAllocSize)
   173  	}
   174  	r := &(*buf)[0]
   175  	*r = v
   176  	*buf = (*buf)[1:]
   177  	return r
   178  }
   179  
   180  // NewDGeometry allocates a DGeometry.
   181  func (a *DatumAlloc) NewDGeometry(v tree.DGeometry) *tree.DGeometry {
   182  	buf := &a.dgeometryAlloc
   183  	if len(*buf) == 0 {
   184  		*buf = make([]tree.DGeometry, datumAllocSize)
   185  	}
   186  	r := &(*buf)[0]
   187  	*r = v
   188  	*buf = (*buf)[1:]
   189  	return r
   190  }
   191  
   192  // NewDTime allocates a DTime.
   193  func (a *DatumAlloc) NewDTime(v tree.DTime) *tree.DTime {
   194  	buf := &a.dtimeAlloc
   195  	if len(*buf) == 0 {
   196  		*buf = make([]tree.DTime, datumAllocSize)
   197  	}
   198  	r := &(*buf)[0]
   199  	*r = v
   200  	*buf = (*buf)[1:]
   201  	return r
   202  }
   203  
   204  // NewDTimeTZ allocates a DTimeTZ.
   205  func (a *DatumAlloc) NewDTimeTZ(v tree.DTimeTZ) *tree.DTimeTZ {
   206  	buf := &a.dtimetzAlloc
   207  	if len(*buf) == 0 {
   208  		*buf = make([]tree.DTimeTZ, datumAllocSize)
   209  	}
   210  	r := &(*buf)[0]
   211  	*r = v
   212  	*buf = (*buf)[1:]
   213  	return r
   214  }
   215  
   216  // NewDTimestamp allocates a DTimestamp.
   217  func (a *DatumAlloc) NewDTimestamp(v tree.DTimestamp) *tree.DTimestamp {
   218  	buf := &a.dtimestampAlloc
   219  	if len(*buf) == 0 {
   220  		*buf = make([]tree.DTimestamp, datumAllocSize)
   221  	}
   222  	r := &(*buf)[0]
   223  	*r = v
   224  	*buf = (*buf)[1:]
   225  	return r
   226  }
   227  
   228  // NewDTimestampTZ allocates a DTimestampTZ.
   229  func (a *DatumAlloc) NewDTimestampTZ(v tree.DTimestampTZ) *tree.DTimestampTZ {
   230  	buf := &a.dtimestampTzAlloc
   231  	if len(*buf) == 0 {
   232  		*buf = make([]tree.DTimestampTZ, datumAllocSize)
   233  	}
   234  	r := &(*buf)[0]
   235  	*r = v
   236  	*buf = (*buf)[1:]
   237  	return r
   238  }
   239  
   240  // NewDInterval allocates a DInterval.
   241  func (a *DatumAlloc) NewDInterval(v tree.DInterval) *tree.DInterval {
   242  	buf := &a.dintervalAlloc
   243  	if len(*buf) == 0 {
   244  		*buf = make([]tree.DInterval, datumAllocSize)
   245  	}
   246  	r := &(*buf)[0]
   247  	*r = v
   248  	*buf = (*buf)[1:]
   249  	return r
   250  }
   251  
   252  // NewDUuid allocates a DUuid.
   253  func (a *DatumAlloc) NewDUuid(v tree.DUuid) *tree.DUuid {
   254  	buf := &a.duuidAlloc
   255  	if len(*buf) == 0 {
   256  		*buf = make([]tree.DUuid, datumAllocSize)
   257  	}
   258  	r := &(*buf)[0]
   259  	*r = v
   260  	*buf = (*buf)[1:]
   261  	return r
   262  }
   263  
   264  // NewDIPAddr allocates a DIPAddr.
   265  func (a *DatumAlloc) NewDIPAddr(v tree.DIPAddr) *tree.DIPAddr {
   266  	buf := &a.dipnetAlloc
   267  	if len(*buf) == 0 {
   268  		*buf = make([]tree.DIPAddr, datumAllocSize)
   269  	}
   270  	r := &(*buf)[0]
   271  	*r = v
   272  	*buf = (*buf)[1:]
   273  	return r
   274  }
   275  
   276  // NewDJSON allocates a DJSON.
   277  func (a *DatumAlloc) NewDJSON(v tree.DJSON) *tree.DJSON {
   278  	buf := &a.djsonAlloc
   279  	if len(*buf) == 0 {
   280  		*buf = make([]tree.DJSON, datumAllocSize)
   281  	}
   282  	r := &(*buf)[0]
   283  	*r = v
   284  	*buf = (*buf)[1:]
   285  	return r
   286  }
   287  
   288  // NewDTuple allocates a DTuple.
   289  func (a *DatumAlloc) NewDTuple(v tree.DTuple) *tree.DTuple {
   290  	buf := &a.dtupleAlloc
   291  	if len(*buf) == 0 {
   292  		*buf = make([]tree.DTuple, datumAllocSize)
   293  	}
   294  	r := &(*buf)[0]
   295  	*r = v
   296  	*buf = (*buf)[1:]
   297  	return r
   298  }
   299  
   300  // NewDOid allocates a DOid.
   301  func (a *DatumAlloc) NewDOid(v tree.DOid) tree.Datum {
   302  	buf := &a.doidAlloc
   303  	if len(*buf) == 0 {
   304  		*buf = make([]tree.DOid, datumAllocSize)
   305  	}
   306  	r := &(*buf)[0]
   307  	*r = v
   308  	*buf = (*buf)[1:]
   309  	return r
   310  }