option.go raw

   1  /*
   2   * Copyright 2021 ByteDance Inc.
   3   *
   4   * Licensed under the Apache License, Version 2.0 (the "License");
   5   * you may not use this file except in compliance with the License.
   6   * You may obtain a copy of the License at
   7   *
   8   *     http://www.apache.org/licenses/LICENSE-2.0
   9   *
  10   * Unless required by applicable law or agreed to in writing, software
  11   * distributed under the License is distributed on an "AS IS" BASIS,
  12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13   * See the License for the specific language governing permissions and
  14   * limitations under the License.
  15   */
  16  
  17  package option
  18  
  19  var (
  20      // DefaultDecoderBufferSize is the initial buffer size of StreamDecoder
  21      DefaultDecoderBufferSize  uint = 4 * 1024
  22  
  23      // DefaultEncoderBufferSize is the initial buffer size of Encoder
  24      DefaultEncoderBufferSize  uint = 4 * 1024
  25  
  26      // DefaultAstBufferSize is the initial buffer size of ast.Node.MarshalJSON()
  27      DefaultAstBufferSize  uint = 4 * 1024
  28  
  29      // LimitBufferSize indicates the max pool buffer size, in case of OOM.
  30      // See issue https://github.com/bytedance/sonic/issues/614
  31      LimitBufferSize uint = 1024 * 1024
  32  )
  33  
  34  // CompileOptions includes all options for encoder or decoder compiler.
  35  type CompileOptions struct {
  36      // the maximum depth for compilation inline
  37      MaxInlineDepth int
  38  
  39      // the loop times for recursively pretouch
  40      RecursiveDepth int
  41  }
  42  
  43  var (
  44      // Default value(3) means the compiler only inline 3 layers of nested struct. 
  45      // when the depth exceeds, the compiler will recurse 
  46      // and compile subsequent structs when they are decoded 
  47      DefaultMaxInlineDepth = 3
  48  
  49      // Default value(1) means `Pretouch()` will be recursively executed once,
  50      // if any nested struct is left (depth exceeds MaxInlineDepth)
  51      DefaultRecursiveDepth = 1
  52  )
  53  
  54  // DefaultCompileOptions set default compile options.
  55  func DefaultCompileOptions() CompileOptions {
  56      return CompileOptions{
  57          RecursiveDepth: DefaultRecursiveDepth,
  58          MaxInlineDepth: DefaultMaxInlineDepth,
  59      }
  60  }
  61  
  62  // CompileOption is a function used to change DefaultCompileOptions.
  63  type CompileOption func(o *CompileOptions)
  64  
  65  // WithCompileRecursiveDepth sets the loop times of recursive pretouch 
  66  // in both decoder and encoder,
  67  // for both concrete type and its pointer type.
  68  //
  69  // For deep nested struct (depth exceeds MaxInlineDepth), 
  70  // try to set more loops to completely compile, 
  71  // thus reduce JIT instability in the first hit.
  72  func WithCompileRecursiveDepth(loop int) CompileOption {
  73      return func(o *CompileOptions) {
  74              if loop < 0 {
  75                  panic("loop must be >= 0")
  76              }
  77              o.RecursiveDepth = loop
  78          }
  79  }
  80  
  81  // WithCompileMaxInlineDepth sets the max depth of inline compile 
  82  // in decoder and encoder.
  83  //
  84  // For large nested struct, try to set smaller depth to reduce compiling time.
  85  func WithCompileMaxInlineDepth(depth int) CompileOption {
  86      return func(o *CompileOptions) {
  87              if depth <= 0 {
  88                  panic("depth must be > 0")
  89              }
  90              o.MaxInlineDepth = depth
  91          }
  92  }
  93