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 }