92 lines
2.3 KiB
Go
92 lines
2.3 KiB
Go
// Licensed to Elasticsearch B.V. under one or more contributor
|
|
// license agreements. See the NOTICE file distributed with
|
|
// this work for additional information regarding copyright
|
|
// ownership. Elasticsearch B.V. licenses this file to you under
|
|
// the Apache License, Version 2.0 (the "License"); you may
|
|
// not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
package logstash
|
|
|
|
import (
|
|
"math"
|
|
"sync/atomic"
|
|
)
|
|
|
|
type window struct {
|
|
windowSize int32
|
|
maxOkWindowSize int // max window size sending was successful for
|
|
maxWindowSize int
|
|
}
|
|
|
|
func newWindower(start, max int) *window {
|
|
w := &window{}
|
|
w.init(start, max)
|
|
return w
|
|
}
|
|
|
|
func (w *window) init(start, max int) {
|
|
*w = window{
|
|
windowSize: int32(start),
|
|
maxWindowSize: max,
|
|
}
|
|
}
|
|
|
|
func (w *window) get() int {
|
|
return int(atomic.LoadInt32(&w.windowSize))
|
|
}
|
|
|
|
// Increase window size by factor 1.5 until max window size
|
|
// (window size grows exponentially)
|
|
// TODO: use duration until ACK to estimate an ok max window size value
|
|
func (w *window) tryGrowWindow(batchSize int) {
|
|
windowSize := w.get()
|
|
|
|
if windowSize <= batchSize {
|
|
if w.maxOkWindowSize < windowSize {
|
|
w.maxOkWindowSize = windowSize
|
|
|
|
newWindowSize := int(math.Ceil(1.5 * float64(windowSize)))
|
|
|
|
if windowSize <= batchSize && batchSize < newWindowSize {
|
|
newWindowSize = batchSize
|
|
}
|
|
if newWindowSize > w.maxWindowSize {
|
|
newWindowSize = int(w.maxWindowSize)
|
|
}
|
|
|
|
windowSize = newWindowSize
|
|
} else if windowSize < w.maxOkWindowSize {
|
|
windowSize = int(math.Ceil(1.5 * float64(windowSize)))
|
|
if windowSize > w.maxOkWindowSize {
|
|
windowSize = w.maxOkWindowSize
|
|
}
|
|
}
|
|
|
|
atomic.StoreInt32(&w.windowSize, int32(windowSize))
|
|
}
|
|
}
|
|
|
|
func (w *window) shrinkWindow() {
|
|
windowSize := w.get()
|
|
orig := windowSize
|
|
|
|
windowSize = windowSize / 2
|
|
if windowSize < minWindowSize {
|
|
windowSize = minWindowSize
|
|
if windowSize == orig {
|
|
return
|
|
}
|
|
}
|
|
|
|
atomic.StoreInt32(&w.windowSize, int32(windowSize))
|
|
}
|