Generated by Cython 0.28.3

Yellow lines hint at Python interaction.
Click on a line that starts with a "+" to see the C code that Cython generated for it.

Raw output: cystats.c

 001: # -*- coding: utf-8 -*-
 002: # This file is part of Xpra.
 003: # Copyright (C) 2012 - 2017 Antoine Martin <antoine@devloop.org.uk>
 004: # Xpra is released under the terms of the GNU GPL v2, or, at your option, any
 005: # later version. See the file COPYING for details.
 006: 
 007: #!python
 008: #cython: boundscheck=False, wraparound=False, cdivision=True
 009: from __future__ import absolute_import
 010: 
+011: import time
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_time, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_time, __pyx_t_1) < 0) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 012: from xpra.monotonic_time cimport monotonic_time
 013: 
 014: cdef extern from "math.h":
 015:     double log(double x)
 016: 
+017: from math import sqrt
  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_INCREF(__pyx_n_s_sqrt);
  __Pyx_GIVEREF(__pyx_n_s_sqrt);
  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_sqrt);
  __pyx_t_2 = __Pyx_Import(__pyx_n_s_math, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 17, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_sqrt); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_sqrt, __pyx_t_1) < 0) __PYX_ERR(0, 17, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+018: def logp(double x):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_7cystats_1logp(PyObject *__pyx_self, PyObject *__pyx_arg_x); /*proto*/
static PyMethodDef __pyx_mdef_4xpra_6server_7cystats_1logp = {"logp", (PyCFunction)__pyx_pw_4xpra_6server_7cystats_1logp, METH_O, 0};
static PyObject *__pyx_pw_4xpra_6server_7cystats_1logp(PyObject *__pyx_self, PyObject *__pyx_arg_x) {
  double __pyx_v_x;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("logp (wrapper)", 0);
  assert(__pyx_arg_x); {
    __pyx_v_x = __pyx_PyFloat_AsDouble(__pyx_arg_x); if (unlikely((__pyx_v_x == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 18, __pyx_L3_error)
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.cystats.logp", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_7cystats_logp(__pyx_self, ((double)__pyx_v_x));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_7cystats_logp(CYTHON_UNUSED PyObject *__pyx_self, double __pyx_v_x) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("logp", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_AddTraceback("xpra.server.cystats.logp", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__3 = PyTuple_Pack(2, __pyx_n_s_x, __pyx_n_s_x); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 18, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__3);
  __Pyx_GIVEREF(__pyx_tuple__3);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_7cystats_1logp, NULL, __pyx_n_s_xpra_server_cystats); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 18, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_logp, __pyx_t_2) < 0) __PYX_ERR(0, 18, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__4 = (PyObject*)__Pyx_PyCode_New(1, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__3, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_xpra_server_cystats_pyx, __pyx_n_s_logp, 18, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__4)) __PYX_ERR(0, 18, __pyx_L1_error)
+019:     return log(1.0+x)*1.4426950408889634
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = PyFloat_FromDouble((log((1.0 + __pyx_v_x)) * 1.4426950408889634)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;
 020: 
+021: cdef inline double clogp(double x):
static CYTHON_INLINE double __pyx_f_4xpra_6server_7cystats_clogp(double __pyx_v_x) {
  double __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("clogp", 0);
/* … */
  /* function exit code */
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+022:     return log(1.0+x)*1.4426950408889634
  __pyx_r = (log((1.0 + __pyx_v_x)) * 1.4426950408889634);
  goto __pyx_L0;
 023: 
+024: SMOOTHING_NAMES = {sqrt: "sqrt", logp: "logp"}
  __pyx_t_2 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_sqrt); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_2, __pyx_t_1, __pyx_n_s_sqrt) < 0) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_logp); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_2, __pyx_t_1, __pyx_n_s_logp) < 0) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SMOOTHING_NAMES, __pyx_t_2) < 0) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+025: def smn(fn):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_7cystats_3smn(PyObject *__pyx_self, PyObject *__pyx_v_fn); /*proto*/
static PyMethodDef __pyx_mdef_4xpra_6server_7cystats_3smn = {"smn", (PyCFunction)__pyx_pw_4xpra_6server_7cystats_3smn, METH_O, 0};
static PyObject *__pyx_pw_4xpra_6server_7cystats_3smn(PyObject *__pyx_self, PyObject *__pyx_v_fn) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("smn (wrapper)", 0);
  __pyx_r = __pyx_pf_4xpra_6server_7cystats_2smn(__pyx_self, ((PyObject *)__pyx_v_fn));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_7cystats_2smn(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_fn) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("smn", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_AddTraceback("xpra.server.cystats.smn", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_n_s_fn); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 25, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__5);
  __Pyx_GIVEREF(__pyx_tuple__5);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_7cystats_3smn, NULL, __pyx_n_s_xpra_server_cystats); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_smn, __pyx_t_2) < 0) __PYX_ERR(0, 25, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__6 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__5, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_xpra_server_cystats_pyx, __pyx_n_s_smn, 25, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__6)) __PYX_ERR(0, 25, __pyx_L1_error)
+026:     return str(SMOOTHING_NAMES.get(fn, fn))
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SMOOTHING_NAMES); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 26, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_get); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 26, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = NULL;
  __pyx_t_4 = 0;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_2)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_2);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
      __pyx_t_4 = 1;
    }
  }
  #if CYTHON_FAST_PYCALL
  if (PyFunction_Check(__pyx_t_3)) {
    PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_v_fn, __pyx_v_fn};
    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_4, 2+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 26, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_GOTREF(__pyx_t_1);
  } else
  #endif
  #if CYTHON_FAST_PYCCALL
  if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
    PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_v_fn, __pyx_v_fn};
    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_4, 2+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 26, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_GOTREF(__pyx_t_1);
  } else
  #endif
  {
    __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 26, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    if (__pyx_t_2) {
      __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __pyx_t_2 = NULL;
    }
    __Pyx_INCREF(__pyx_v_fn);
    __Pyx_GIVEREF(__pyx_v_fn);
    PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, __pyx_v_fn);
    __Pyx_INCREF(__pyx_v_fn);
    __Pyx_GIVEREF(__pyx_v_fn);
    PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_v_fn);
    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 26, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyString_Type)), __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 26, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_r = __pyx_t_3;
  __pyx_t_3 = 0;
  goto __pyx_L0;
 027: 
 028: 
+029: def calculate_time_weighted_average(data):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_7cystats_5calculate_time_weighted_average(PyObject *__pyx_self, PyObject *__pyx_v_data); /*proto*/
static char __pyx_doc_4xpra_6server_7cystats_4calculate_time_weighted_average[] = "\n        Given a list of items of the form [(event_time, value)],\n        this method calculates a time-weighted average where\n        recent values matter a lot more than more ancient ones.\n    ";
static PyMethodDef __pyx_mdef_4xpra_6server_7cystats_5calculate_time_weighted_average = {"calculate_time_weighted_average", (PyCFunction)__pyx_pw_4xpra_6server_7cystats_5calculate_time_weighted_average, METH_O, __pyx_doc_4xpra_6server_7cystats_4calculate_time_weighted_average};
static PyObject *__pyx_pw_4xpra_6server_7cystats_5calculate_time_weighted_average(PyObject *__pyx_self, PyObject *__pyx_v_data) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_time_weighted_average (wrapper)", 0);
  __pyx_r = __pyx_pf_4xpra_6server_7cystats_4calculate_time_weighted_average(__pyx_self, ((PyObject *)__pyx_v_data));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_7cystats_4calculate_time_weighted_average(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data) {
  double __pyx_v_now;
  double __pyx_v_tv;
  double __pyx_v_tw;
  double __pyx_v_rv;
  double __pyx_v_rw;
  double __pyx_v_event_time;
  double __pyx_v_value;
  double __pyx_v_delta;
  double __pyx_v_w;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_time_weighted_average", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("xpra.server.cystats.calculate_time_weighted_average", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__7 = PyTuple_Pack(10, __pyx_n_s_data, __pyx_n_s_now, __pyx_n_s_tv, __pyx_n_s_tw, __pyx_n_s_rv, __pyx_n_s_rw, __pyx_n_s_event_time, __pyx_n_s_value, __pyx_n_s_delta, __pyx_n_s_w); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 29, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__7);
  __Pyx_GIVEREF(__pyx_tuple__7);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_7cystats_5calculate_time_weighted_average, NULL, __pyx_n_s_xpra_server_cystats); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 29, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_calculate_time_weighted_average, __pyx_t_2) < 0) __PYX_ERR(0, 29, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(1, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__7, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_xpra_server_cystats_pyx, __pyx_n_s_calculate_time_weighted_average, 29, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) __PYX_ERR(0, 29, __pyx_L1_error)
 030:     """
 031:         Given a list of items of the form [(event_time, value)],
 032:         this method calculates a time-weighted average where
 033:         recent values matter a lot more than more ancient ones.
 034:     """
+035:     assert len(data)>0
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    __pyx_t_1 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 35, __pyx_L1_error)
    if (unlikely(!((__pyx_t_1 > 0) != 0))) {
      PyErr_SetNone(PyExc_AssertionError);
      __PYX_ERR(0, 35, __pyx_L1_error)
    }
  }
  #endif
+036:     cdef double now = monotonic_time()
  __pyx_v_now = __pyx_f_4xpra_14monotonic_time_monotonic_time();
+037:     cdef double tv = 0.0
  __pyx_v_tv = 0.0;
+038:     cdef double tw = 0.0
  __pyx_v_tw = 0.0;
+039:     cdef double rv = 0.0
  __pyx_v_rv = 0.0;
+040:     cdef double rw = 0.0
  __pyx_v_rw = 0.0;
 041:     cdef double event_time
 042:     cdef double value
 043:     cdef double delta
 044:     cdef double w
+045:     for event_time, value in data:
  if (likely(PyList_CheckExact(__pyx_v_data)) || PyTuple_CheckExact(__pyx_v_data)) {
    __pyx_t_2 = __pyx_v_data; __Pyx_INCREF(__pyx_t_2); __pyx_t_1 = 0;
    __pyx_t_3 = NULL;
  } else {
    __pyx_t_1 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_data); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 45, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 45, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_3)) {
      if (likely(PyList_CheckExact(__pyx_t_2))) {
        if (__pyx_t_1 >= PyList_GET_SIZE(__pyx_t_2)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_1); __Pyx_INCREF(__pyx_t_4); __pyx_t_1++; if (unlikely(0 < 0)) __PYX_ERR(0, 45, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 45, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      } else {
        if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_1); __Pyx_INCREF(__pyx_t_4); __pyx_t_1++; if (unlikely(0 < 0)) __PYX_ERR(0, 45, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 45, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      }
    } else {
      __pyx_t_4 = __pyx_t_3(__pyx_t_2);
      if (unlikely(!__pyx_t_4)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 45, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_4);
    }
    if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
      PyObject* sequence = __pyx_t_4;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 2)) {
        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 45, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
      } else {
        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
      }
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      #else
      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 45, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 45, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      #endif
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 45, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext;
      index = 0; __pyx_t_5 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_5)) goto __pyx_L5_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_5);
      index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L5_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_6);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 45, __pyx_L1_error)
      __pyx_t_8 = NULL;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      goto __pyx_L6_unpacking_done;
      __pyx_L5_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_8 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 45, __pyx_L1_error)
      __pyx_L6_unpacking_done:;
    }
    __pyx_t_9 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_9 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 45, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_10 = __pyx_PyFloat_AsDouble(__pyx_t_6); if (unlikely((__pyx_t_10 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 45, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_v_event_time = __pyx_t_9;
    __pyx_v_value = __pyx_t_10;
/* … */
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 046:         #newer matter more:
+047:         delta = now-event_time
    __pyx_v_delta = (__pyx_v_now - __pyx_v_event_time);
+048:         w = 1.0/(1.0+delta)
    __pyx_v_w = (1.0 / (1.0 + __pyx_v_delta));
+049:         tv += value*w
    __pyx_v_tv = (__pyx_v_tv + (__pyx_v_value * __pyx_v_w));
+050:         tw += w
    __pyx_v_tw = (__pyx_v_tw + __pyx_v_w);
+051:         w = 1.0/(0.1+delta**2)
    __pyx_v_w = (1.0 / (0.1 + pow(__pyx_v_delta, 2.0)));
+052:         rv += value*w
    __pyx_v_rv = (__pyx_v_rv + (__pyx_v_value * __pyx_v_w));
+053:         rw += w
    __pyx_v_rw = (__pyx_v_rw + __pyx_v_w);
+054:     return tv / tw, rv / rw
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_2 = PyFloat_FromDouble((__pyx_v_tv / __pyx_v_tw)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 54, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = PyFloat_FromDouble((__pyx_v_rv / __pyx_v_rw)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 54, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 54, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_2);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_4);
  __pyx_t_2 = 0;
  __pyx_t_4 = 0;
  __pyx_r = __pyx_t_6;
  __pyx_t_6 = 0;
  goto __pyx_L0;
 055: 
+056: def time_weighted_average(data, double min_offset=0.1, double rpow=2.0):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_7cystats_7time_weighted_average(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_4xpra_6server_7cystats_6time_weighted_average[] = "\n        Given a list of items of the form [(event_time, value)],\n        this method calculates a time-weighted average where\n        recent values matter a lot more than more ancient ones.\n        We take the \"rpow\" power of the time offset.\n        (defaults to 2, which means we square it)\n    ";
static PyMethodDef __pyx_mdef_4xpra_6server_7cystats_7time_weighted_average = {"time_weighted_average", (PyCFunction)__pyx_pw_4xpra_6server_7cystats_7time_weighted_average, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4xpra_6server_7cystats_6time_weighted_average};
static PyObject *__pyx_pw_4xpra_6server_7cystats_7time_weighted_average(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_data = 0;
  double __pyx_v_min_offset;
  double __pyx_v_rpow;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("time_weighted_average (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_offset,&__pyx_n_s_rpow,0};
    PyObject* values[3] = {0,0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_min_offset);
          if (value) { values[1] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rpow);
          if (value) { values[2] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "time_weighted_average") < 0)) __PYX_ERR(0, 56, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_data = values[0];
    if (values[1]) {
      __pyx_v_min_offset = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_min_offset == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L3_error)
    } else {
      __pyx_v_min_offset = ((double)0.1);
    }
    if (values[2]) {
      __pyx_v_rpow = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_rpow == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 56, __pyx_L3_error)
    } else {
      __pyx_v_rpow = ((double)2.0);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("time_weighted_average", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 56, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.cystats.time_weighted_average", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_7cystats_6time_weighted_average(__pyx_self, __pyx_v_data, __pyx_v_min_offset, __pyx_v_rpow);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_7cystats_6time_weighted_average(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, double __pyx_v_min_offset, double __pyx_v_rpow) {
  double __pyx_v_now;
  double __pyx_v_tv;
  double __pyx_v_tw;
  double __pyx_v_w;
  double __pyx_v_delta;
  PyObject *__pyx_v_event_time = NULL;
  PyObject *__pyx_v_value = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("time_weighted_average", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("xpra.server.cystats.time_weighted_average", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_event_time);
  __Pyx_XDECREF(__pyx_v_value);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__9 = PyTuple_Pack(10, __pyx_n_s_data, __pyx_n_s_min_offset, __pyx_n_s_rpow, __pyx_n_s_now, __pyx_n_s_tv, __pyx_n_s_tw, __pyx_n_s_w, __pyx_n_s_delta, __pyx_n_s_event_time, __pyx_n_s_value); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(0, 56, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__9);
  __Pyx_GIVEREF(__pyx_tuple__9);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_7cystats_7time_weighted_average, NULL, __pyx_n_s_xpra_server_cystats); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 56, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_time_weighted_average, __pyx_t_2) < 0) __PYX_ERR(0, 56, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__10 = (PyObject*)__Pyx_PyCode_New(3, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__9, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_xpra_server_cystats_pyx, __pyx_n_s_time_weighted_average, 56, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__10)) __PYX_ERR(0, 56, __pyx_L1_error)
 057:     """
 058:         Given a list of items of the form [(event_time, value)],
 059:         this method calculates a time-weighted average where
 060:         recent values matter a lot more than more ancient ones.
 061:         We take the "rpow" power of the time offset.
 062:         (defaults to 2, which means we square it)
 063:     """
+064:     assert len(data)>0
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    __pyx_t_1 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 64, __pyx_L1_error)
    if (unlikely(!((__pyx_t_1 > 0) != 0))) {
      PyErr_SetNone(PyExc_AssertionError);
      __PYX_ERR(0, 64, __pyx_L1_error)
    }
  }
  #endif
+065:     cdef double now = monotonic_time()              #@DuplicatedSignature
  __pyx_v_now = __pyx_f_4xpra_14monotonic_time_monotonic_time();
+066:     cdef double tv = 0.0                            #@DuplicatedSignature
  __pyx_v_tv = 0.0;
+067:     cdef double tw = 0.0                            #@DuplicatedSignature
  __pyx_v_tw = 0.0;
 068:     cdef double w                                   #@DuplicatedSignature
 069:     cdef double delta                               #@DuplicatedSignature
+070:     for event_time, value in data:
  if (likely(PyList_CheckExact(__pyx_v_data)) || PyTuple_CheckExact(__pyx_v_data)) {
    __pyx_t_2 = __pyx_v_data; __Pyx_INCREF(__pyx_t_2); __pyx_t_1 = 0;
    __pyx_t_3 = NULL;
  } else {
    __pyx_t_1 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_data); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 70, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_3)) {
      if (likely(PyList_CheckExact(__pyx_t_2))) {
        if (__pyx_t_1 >= PyList_GET_SIZE(__pyx_t_2)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_1); __Pyx_INCREF(__pyx_t_4); __pyx_t_1++; if (unlikely(0 < 0)) __PYX_ERR(0, 70, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      } else {
        if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_1); __Pyx_INCREF(__pyx_t_4); __pyx_t_1++; if (unlikely(0 < 0)) __PYX_ERR(0, 70, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_2, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      }
    } else {
      __pyx_t_4 = __pyx_t_3(__pyx_t_2);
      if (unlikely(!__pyx_t_4)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 70, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_4);
    }
    if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
      PyObject* sequence = __pyx_t_4;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 2)) {
        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 70, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
      } else {
        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
      }
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      #else
      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 70, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 70, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      #endif
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_7 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 70, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext;
      index = 0; __pyx_t_5 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_5)) goto __pyx_L5_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_5);
      index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L5_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_6);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 70, __pyx_L1_error)
      __pyx_t_8 = NULL;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      goto __pyx_L6_unpacking_done;
      __pyx_L5_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_8 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 70, __pyx_L1_error)
      __pyx_L6_unpacking_done:;
    }
    __Pyx_XDECREF_SET(__pyx_v_event_time, __pyx_t_5);
    __pyx_t_5 = 0;
    __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_6);
    __pyx_t_6 = 0;
/* … */
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+071:         delta = now-event_time
    __pyx_t_4 = PyFloat_FromDouble(__pyx_v_now); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 71, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_6 = PyNumber_Subtract(__pyx_t_4, __pyx_v_event_time); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 71, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_9 = __pyx_PyFloat_AsDouble(__pyx_t_6); if (unlikely((__pyx_t_9 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 71, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_v_delta = __pyx_t_9;
+072:         assert delta>=0, "invalid event_time=%s, now=%s, delta=%s" % (event_time, now, delta)
    #ifndef CYTHON_WITHOUT_ASSERTIONS
    if (unlikely(!Py_OptimizeFlag)) {
      if (unlikely(!((__pyx_v_delta >= 0.0) != 0))) {
        __pyx_t_6 = PyFloat_FromDouble(__pyx_v_now); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 72, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __pyx_t_4 = PyFloat_FromDouble(__pyx_v_delta); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 72, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 72, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __Pyx_INCREF(__pyx_v_event_time);
        __Pyx_GIVEREF(__pyx_v_event_time);
        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_event_time);
        __Pyx_GIVEREF(__pyx_t_6);
        PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6);
        __Pyx_GIVEREF(__pyx_t_4);
        PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_4);
        __pyx_t_6 = 0;
        __pyx_t_4 = 0;
        __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_invalid_event_time_s_now_s_delta, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 72, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        PyErr_SetObject(PyExc_AssertionError, __pyx_t_4);
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
        __PYX_ERR(0, 72, __pyx_L1_error)
      }
    }
    #endif
+073:         w = 1.0/(min_offset+delta**rpow)
    __pyx_v_w = (1.0 / (__pyx_v_min_offset + pow(__pyx_v_delta, __pyx_v_rpow)));
+074:         tv += value*w
    __pyx_t_4 = PyFloat_FromDouble(__pyx_v_tv); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 74, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_5 = PyFloat_FromDouble(__pyx_v_w); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 74, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = PyNumber_Multiply(__pyx_v_value, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 74, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_5 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 74, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_t_9 = __pyx_PyFloat_AsDouble(__pyx_t_5); if (unlikely((__pyx_t_9 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 74, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_v_tv = __pyx_t_9;
+075:         tw += w
    __pyx_v_tw = (__pyx_v_tw + __pyx_v_w);
+076:     return tv / tw
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_2 = PyFloat_FromDouble((__pyx_v_tv / __pyx_v_tw)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 76, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_r = __pyx_t_2;
  __pyx_t_2 = 0;
  goto __pyx_L0;
 077: 
+078: def calculate_timesize_weighted_average_score(data):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_7cystats_9calculate_timesize_weighted_average_score(PyObject *__pyx_self, PyObject *__pyx_v_data); /*proto*/
static char __pyx_doc_4xpra_6server_7cystats_8calculate_timesize_weighted_average_score[] = "\n        This is a time weighted average where the size\n        of each record also gives it a weight boost.\n        This is to prevent small packets from skewing the average.\n        Data format: (event_time, size, value)\n    ";
static PyMethodDef __pyx_mdef_4xpra_6server_7cystats_9calculate_timesize_weighted_average_score = {"calculate_timesize_weighted_average_score", (PyCFunction)__pyx_pw_4xpra_6server_7cystats_9calculate_timesize_weighted_average_score, METH_O, __pyx_doc_4xpra_6server_7cystats_8calculate_timesize_weighted_average_score};
static PyObject *__pyx_pw_4xpra_6server_7cystats_9calculate_timesize_weighted_average_score(PyObject *__pyx_self, PyObject *__pyx_v_data) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_timesize_weighted_average_score (wrapper)", 0);
  __pyx_r = __pyx_pf_4xpra_6server_7cystats_8calculate_timesize_weighted_average_score(__pyx_self, ((PyObject *)__pyx_v_data));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
static PyObject *__pyx_gb_4xpra_6server_7cystats_41calculate_timesize_weighted_average_score_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
/* … */
static PyObject *__pyx_pf_4xpra_6server_7cystats_8calculate_timesize_weighted_average_score(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data) {
  struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct__calculate_timesize_weighted_average_score *__pyx_cur_scope;
  double __pyx_v_size_avg;
  double __pyx_v_now;
  double __pyx_v_tv;
  double __pyx_v_tw;
  double __pyx_v_rv;
  double __pyx_v_rw;
  double __pyx_v_event_time;
  int __pyx_v_size;
  int __pyx_v_value;
  double __pyx_v_pw;
  double __pyx_v_w;
  double __pyx_v_delta;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_timesize_weighted_average_score", 0);
  __pyx_cur_scope = (struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct__calculate_timesize_weighted_average_score *)__pyx_tp_new_4xpra_6server_7cystats___pyx_scope_struct__calculate_timesize_weighted_average_score(__pyx_ptype_4xpra_6server_7cystats___pyx_scope_struct__calculate_timesize_weighted_average_score, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct__calculate_timesize_weighted_average_score *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 78, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_v_data = __pyx_v_data;
  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_data);
  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_data);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_AddTraceback("xpra.server.cystats.calculate_timesize_weighted_average_score", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__11 = PyTuple_Pack(15, __pyx_n_s_data, __pyx_n_s_size_avg, __pyx_n_s_now, __pyx_n_s_tv, __pyx_n_s_tw, __pyx_n_s_rv, __pyx_n_s_rw, __pyx_n_s_event_time, __pyx_n_s_size, __pyx_n_s_value, __pyx_n_s_pw, __pyx_n_s_w, __pyx_n_s_delta, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(0, 78, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__11);
  __Pyx_GIVEREF(__pyx_tuple__11);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_7cystats_9calculate_timesize_weighted_average_score, NULL, __pyx_n_s_xpra_server_cystats); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 78, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_calculate_timesize_weighted_aver_3, __pyx_t_2) < 0) __PYX_ERR(0, 78, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__12 = (PyObject*)__Pyx_PyCode_New(1, 0, 15, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_xpra_server_cystats_pyx, __pyx_n_s_calculate_timesize_weighted_aver_3, 78, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__12)) __PYX_ERR(0, 78, __pyx_L1_error)
/* … */
struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct__calculate_timesize_weighted_average_score {
  PyObject_HEAD
  PyObject *__pyx_v_data;
};

 079:     """
 080:         This is a time weighted average where the size
 081:         of each record also gives it a weight boost.
 082:         This is to prevent small packets from skewing the average.
 083:         Data format: (event_time, size, value)
 084:     """
+085:     cdef double size_avg = sum(x for _, x, _ in data)/len(data)
static PyObject *__pyx_pf_4xpra_6server_7cystats_41calculate_timesize_weighted_average_score_genexpr(PyObject *__pyx_self) {
  struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_1_genexpr *__pyx_cur_scope;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_cur_scope = (struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_1_genexpr *)__pyx_tp_new_4xpra_6server_7cystats___pyx_scope_struct_1_genexpr(__pyx_ptype_4xpra_6server_7cystats___pyx_scope_struct_1_genexpr, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_1_genexpr *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 85, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct__calculate_timesize_weighted_average_score *) __pyx_self;
  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
  {
    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_4xpra_6server_7cystats_41calculate_timesize_weighted_average_score_2generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_calculate_timesize_weighted_aver, __pyx_n_s_xpra_server_cystats); if (unlikely(!gen)) __PYX_ERR(0, 85, __pyx_L1_error)
    __Pyx_DECREF(__pyx_cur_scope);
    __Pyx_RefNannyFinishContext();
    return (PyObject *) gen;
  }

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_AddTraceback("xpra.server.cystats.calculate_timesize_weighted_average_score.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_gb_4xpra_6server_7cystats_41calculate_timesize_weighted_average_score_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */
{
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_L3_first_run:;
  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 85, __pyx_L1_error)
  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data)) { __Pyx_RaiseClosureNameError("data"); __PYX_ERR(0, 85, __pyx_L1_error) }
  if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data)) {
    __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_data; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
    __pyx_t_3 = NULL;
  } else {
    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 85, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 85, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_3)) {
      if (likely(PyList_CheckExact(__pyx_t_1))) {
        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 85, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 85, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      } else {
        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 85, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 85, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      }
    } else {
      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
      if (unlikely(!__pyx_t_4)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 85, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_4);
    }
    if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
      PyObject* sequence = __pyx_t_4;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 3)) {
        if (size > 3) __Pyx_RaiseTooManyValuesError(3);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 85, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
        __pyx_t_7 = PyTuple_GET_ITEM(sequence, 2); 
      } else {
        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
        __pyx_t_7 = PyList_GET_ITEM(sequence, 2); 
      }
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(__pyx_t_7);
      #else
      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 85, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 85, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_7 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 85, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      #endif
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_8 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 85, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext;
      index = 0; __pyx_t_5 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_5);
      index = 1; __pyx_t_6 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_6)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_6);
      index = 2; __pyx_t_7 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_7)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_7);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 3) < 0) __PYX_ERR(0, 85, __pyx_L1_error)
      __pyx_t_9 = NULL;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      goto __pyx_L7_unpacking_done;
      __pyx_L6_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_t_9 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 85, __pyx_L1_error)
      __pyx_L7_unpacking_done:;
    }
    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v__);
    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v__, __pyx_t_5);
    __Pyx_GIVEREF(__pyx_t_5);
    __pyx_t_5 = 0;
    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_x);
    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_x, __pyx_t_6);
    __Pyx_GIVEREF(__pyx_t_6);
    __pyx_t_6 = 0;
    __Pyx_GOTREF(__pyx_cur_scope->__pyx_v__);
    __Pyx_DECREF_SET(__pyx_cur_scope->__pyx_v__, __pyx_t_7);
    __Pyx_GIVEREF(__pyx_t_7);
    __pyx_t_7 = 0;
    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_x);
    __pyx_r = __pyx_cur_scope->__pyx_v_x;
    __Pyx_XGIVEREF(__pyx_t_1);
    __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
    __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
    __pyx_cur_scope->__pyx_t_2 = __pyx_t_3;
    __Pyx_XGIVEREF(__pyx_r);
    __Pyx_RefNannyFinishContext();
    __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
    /* return from generator, yielding value */
    __pyx_generator->resume_label = 1;
    return __pyx_r;
    __pyx_L8_resume_from_yield:;
    __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
    __pyx_cur_scope->__pyx_t_0 = 0;
    __Pyx_XGOTREF(__pyx_t_1);
    __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
    __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 85, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);

  /* function exit code */
  PyErr_SetNone(PyExc_StopIteration);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_r); __pyx_r = 0;
  __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
  __pyx_generator->resume_label = -1;
  __Pyx_Coroutine_clear((PyObject*)__pyx_generator);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_t_1 = __pyx_pf_4xpra_6server_7cystats_41calculate_timesize_weighted_average_score_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 85, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_sum, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 85, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __pyx_cur_scope->__pyx_v_data;
  __Pyx_INCREF(__pyx_t_1);
  __pyx_t_3 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(0, 85, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 85, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_4 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 85, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_5 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_5 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 85, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_size_avg = __pyx_t_5;
/* … */
struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_1_genexpr {
  PyObject_HEAD
  struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct__calculate_timesize_weighted_average_score *__pyx_outer_scope;
  PyObject *__pyx_v__;
  PyObject *__pyx_v_x;
  PyObject *__pyx_t_0;
  Py_ssize_t __pyx_t_1;
  PyObject *(*__pyx_t_2)(PyObject *);
};

+086:     cdef double now = monotonic_time()              #@DuplicatedSignature
  __pyx_v_now = __pyx_f_4xpra_14monotonic_time_monotonic_time();
+087:     cdef double tv = 0.0                            #@DuplicatedSignature
  __pyx_v_tv = 0.0;
+088:     cdef double tw = 0.0                            #@DuplicatedSignature
  __pyx_v_tw = 0.0;
+089:     cdef double rv = 0.0                            #@DuplicatedSignature
  __pyx_v_rv = 0.0;
+090:     cdef double rw = 0.0                            #@DuplicatedSignature
  __pyx_v_rw = 0.0;
 091:     cdef double event_time                          #@DuplicatedSignature
 092:     cdef int size
 093:     cdef int value
 094:     cdef double pw
 095:     cdef double w                                   #@DuplicatedSignature
 096:     cdef double delta                               #@DuplicatedSignature
+097:     for event_time, size, value in data:
  if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_v_data)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_data)) {
    __pyx_t_4 = __pyx_cur_scope->__pyx_v_data; __Pyx_INCREF(__pyx_t_4); __pyx_t_3 = 0;
    __pyx_t_6 = NULL;
  } else {
    __pyx_t_3 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_data); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 97, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 97, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_6)) {
      if (likely(PyList_CheckExact(__pyx_t_4))) {
        if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_4)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 97, __pyx_L1_error)
        #else
        __pyx_t_1 = PySequence_ITEM(__pyx_t_4, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 97, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        #endif
      } else {
        if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 97, __pyx_L1_error)
        #else
        __pyx_t_1 = PySequence_ITEM(__pyx_t_4, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 97, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        #endif
      }
    } else {
      __pyx_t_1 = __pyx_t_6(__pyx_t_4);
      if (unlikely(!__pyx_t_1)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 97, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_1);
    }
    if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
      PyObject* sequence = __pyx_t_1;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 3)) {
        if (size > 3) __Pyx_RaiseTooManyValuesError(3);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 97, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); 
        __pyx_t_8 = PyTuple_GET_ITEM(sequence, 2); 
      } else {
        __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_7 = PyList_GET_ITEM(sequence, 1); 
        __pyx_t_8 = PyList_GET_ITEM(sequence, 2); 
      }
      __Pyx_INCREF(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_7);
      __Pyx_INCREF(__pyx_t_8);
      #else
      __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 97, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 97, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __pyx_t_8 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 97, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      #endif
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_9 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 97, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_10 = Py_TYPE(__pyx_t_9)->tp_iternext;
      index = 0; __pyx_t_2 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_2);
      index = 1; __pyx_t_7 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_7)) goto __pyx_L5_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_7);
      index = 2; __pyx_t_8 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L5_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_8);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 3) < 0) __PYX_ERR(0, 97, __pyx_L1_error)
      __pyx_t_10 = NULL;
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      goto __pyx_L6_unpacking_done;
      __pyx_L5_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __pyx_t_10 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 97, __pyx_L1_error)
      __pyx_L6_unpacking_done:;
    }
    __pyx_t_5 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_5 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_t_8); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    __pyx_v_event_time = __pyx_t_5;
    __pyx_v_size = __pyx_t_11;
    __pyx_v_value = __pyx_t_12;
/* … */
    __pyx_L3_continue:;
  }
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+098:         if value<0:
    __pyx_t_13 = ((__pyx_v_value < 0) != 0);
    if (__pyx_t_13) {
/* … */
    }
+099:             continue        #invalid record
      goto __pyx_L3_continue;
+100:         delta = now-event_time
    __pyx_v_delta = (__pyx_v_now - __pyx_v_event_time);
+101:         pw = clogp(size/size_avg)
    __pyx_v_pw = __pyx_f_4xpra_6server_7cystats_clogp((__pyx_v_size / __pyx_v_size_avg));
+102:         w = pw/(1.0+delta)*size
    __pyx_v_w = ((__pyx_v_pw / (1.0 + __pyx_v_delta)) * __pyx_v_size);
+103:         tv += w*value
    __pyx_v_tv = (__pyx_v_tv + (__pyx_v_w * __pyx_v_value));
+104:         tw += w
    __pyx_v_tw = (__pyx_v_tw + __pyx_v_w);
+105:         w = pw/(0.1+delta**2)*size
    __pyx_v_w = ((__pyx_v_pw / (0.1 + pow(__pyx_v_delta, 2.0))) * __pyx_v_size);
+106:         rv += w*value
    __pyx_v_rv = (__pyx_v_rv + (__pyx_v_w * __pyx_v_value));
+107:         rw += w
    __pyx_v_rw = (__pyx_v_rw + __pyx_v_w);
+108:     return int(tv / tw), int(rv / rw)
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_4 = __Pyx_PyInt_FromDouble((__pyx_v_tv / __pyx_v_tw)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 108, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = __Pyx_PyInt_FromDouble((__pyx_v_rv / __pyx_v_rw)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 108, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_8);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_1);
  __pyx_t_4 = 0;
  __pyx_t_1 = 0;
  __pyx_r = __pyx_t_8;
  __pyx_t_8 = 0;
  goto __pyx_L0;
 109: 
+110: def calculate_timesize_weighted_average(data, float unit=1.0):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_7cystats_11calculate_timesize_weighted_average(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_4xpra_6server_7cystats_11calculate_timesize_weighted_average = {"calculate_timesize_weighted_average", (PyCFunction)__pyx_pw_4xpra_6server_7cystats_11calculate_timesize_weighted_average, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_4xpra_6server_7cystats_11calculate_timesize_weighted_average(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_data = 0;
  float __pyx_v_unit;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_timesize_weighted_average (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_unit,0};
    PyObject* values[2] = {0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_unit);
          if (value) { values[1] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "calculate_timesize_weighted_average") < 0)) __PYX_ERR(0, 110, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_data = values[0];
    if (values[1]) {
      __pyx_v_unit = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_unit == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 110, __pyx_L3_error)
    } else {
      __pyx_v_unit = ((float)1.0);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("calculate_timesize_weighted_average", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 110, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.cystats.calculate_timesize_weighted_average", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_7cystats_10calculate_timesize_weighted_average(__pyx_self, __pyx_v_data, __pyx_v_unit);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
static PyObject *__pyx_gb_4xpra_6server_7cystats_35calculate_timesize_weighted_average_2generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
/* … */
static PyObject *__pyx_pf_4xpra_6server_7cystats_10calculate_timesize_weighted_average(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, float __pyx_v_unit) {
  struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_2_calculate_timesize_weighted_average *__pyx_cur_scope;
  PyObject *__pyx_v_recs = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_timesize_weighted_average", 0);
  __pyx_cur_scope = (struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_2_calculate_timesize_weighted_average *)__pyx_tp_new_4xpra_6server_7cystats___pyx_scope_struct_2_calculate_timesize_weighted_average(__pyx_ptype_4xpra_6server_7cystats___pyx_scope_struct_2_calculate_timesize_weighted_average, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_2_calculate_timesize_weighted_average *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 110, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_v_data = __pyx_v_data;
  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_data);
  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_data);
  __pyx_cur_scope->__pyx_v_unit = __pyx_v_unit;
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_AddTraceback("xpra.server.cystats.calculate_timesize_weighted_average", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_recs);
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__13 = PyTuple_Pack(5, __pyx_n_s_data, __pyx_n_s_unit, __pyx_n_s_recs, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 110, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__13);
  __Pyx_GIVEREF(__pyx_tuple__13);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_7cystats_11calculate_timesize_weighted_average, NULL, __pyx_n_s_xpra_server_cystats); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 110, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_calculate_timesize_weighted_aver_4, __pyx_t_2) < 0) __PYX_ERR(0, 110, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_xpra_server_cystats_pyx, __pyx_n_s_calculate_timesize_weighted_aver_4, 110, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) __PYX_ERR(0, 110, __pyx_L1_error)
/* … */
struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_2_calculate_timesize_weighted_average {
  PyObject_HEAD
  PyObject *__pyx_v_data;
  float __pyx_v_unit;
};

 111:     #the value is elapsed time,
 112:     #so we want to divide by the value:
+113:     recs = tuple((a,b,unit/c) for a,b,c in data)
static PyObject *__pyx_pf_4xpra_6server_7cystats_35calculate_timesize_weighted_average_genexpr(PyObject *__pyx_self) {
  struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_3_genexpr *__pyx_cur_scope;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_cur_scope = (struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_3_genexpr *)__pyx_tp_new_4xpra_6server_7cystats___pyx_scope_struct_3_genexpr(__pyx_ptype_4xpra_6server_7cystats___pyx_scope_struct_3_genexpr, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_3_genexpr *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 113, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_2_calculate_timesize_weighted_average *) __pyx_self;
  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
  {
    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_4xpra_6server_7cystats_35calculate_timesize_weighted_average_2generator1, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_calculate_timesize_weighted_aver_2, __pyx_n_s_xpra_server_cystats); if (unlikely(!gen)) __PYX_ERR(0, 113, __pyx_L1_error)
    __Pyx_DECREF(__pyx_cur_scope);
    __Pyx_RefNannyFinishContext();
    return (PyObject *) gen;
  }

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_AddTraceback("xpra.server.cystats.calculate_timesize_weighted_average.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_gb_4xpra_6server_7cystats_35calculate_timesize_weighted_average_2generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */
{
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_L3_first_run:;
  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 113, __pyx_L1_error)
  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data)) { __Pyx_RaiseClosureNameError("data"); __PYX_ERR(0, 113, __pyx_L1_error) }
  if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data)) {
    __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_data; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
    __pyx_t_3 = NULL;
  } else {
    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 113, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 113, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_3)) {
      if (likely(PyList_CheckExact(__pyx_t_1))) {
        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 113, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 113, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      } else {
        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 113, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 113, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      }
    } else {
      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
      if (unlikely(!__pyx_t_4)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 113, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_4);
    }
    if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
      PyObject* sequence = __pyx_t_4;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 3)) {
        if (size > 3) __Pyx_RaiseTooManyValuesError(3);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 113, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
        __pyx_t_7 = PyTuple_GET_ITEM(sequence, 2); 
      } else {
        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
        __pyx_t_7 = PyList_GET_ITEM(sequence, 2); 
      }
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(__pyx_t_7);
      #else
      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 113, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 113, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_7 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 113, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      #endif
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_8 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 113, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext;
      index = 0; __pyx_t_5 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_5);
      index = 1; __pyx_t_6 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_6)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_6);
      index = 2; __pyx_t_7 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_7)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_7);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 3) < 0) __PYX_ERR(0, 113, __pyx_L1_error)
      __pyx_t_9 = NULL;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      goto __pyx_L7_unpacking_done;
      __pyx_L6_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_t_9 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 113, __pyx_L1_error)
      __pyx_L7_unpacking_done:;
    }
    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_a);
    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_a, __pyx_t_5);
    __Pyx_GIVEREF(__pyx_t_5);
    __pyx_t_5 = 0;
    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_b);
    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_b, __pyx_t_6);
    __Pyx_GIVEREF(__pyx_t_6);
    __pyx_t_6 = 0;
    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_c);
    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_c, __pyx_t_7);
    __Pyx_GIVEREF(__pyx_t_7);
    __pyx_t_7 = 0;
    __pyx_t_4 = PyFloat_FromDouble(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_unit); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 113, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_7 = __Pyx_PyNumber_Divide(__pyx_t_4, __pyx_cur_scope->__pyx_v_c); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 113, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 113, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_a);
    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_a);
    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_cur_scope->__pyx_v_a);
    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_b);
    __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_b);
    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_cur_scope->__pyx_v_b);
    __Pyx_GIVEREF(__pyx_t_7);
    PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_7);
    __pyx_t_7 = 0;
    __pyx_r = __pyx_t_4;
    __pyx_t_4 = 0;
    __Pyx_XGIVEREF(__pyx_t_1);
    __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
    __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
    __pyx_cur_scope->__pyx_t_2 = __pyx_t_3;
    __Pyx_XGIVEREF(__pyx_r);
    __Pyx_RefNannyFinishContext();
    __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
    /* return from generator, yielding value */
    __pyx_generator->resume_label = 1;
    return __pyx_r;
    __pyx_L8_resume_from_yield:;
    __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
    __pyx_cur_scope->__pyx_t_0 = 0;
    __Pyx_XGOTREF(__pyx_t_1);
    __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
    __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 113, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);

  /* function exit code */
  PyErr_SetNone(PyExc_StopIteration);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_r); __pyx_r = 0;
  __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
  __pyx_generator->resume_label = -1;
  __Pyx_Coroutine_clear((PyObject*)__pyx_generator);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_t_1 = __pyx_pf_4xpra_6server_7cystats_35calculate_timesize_weighted_average_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 113, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PySequence_Tuple(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 113, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_recs = ((PyObject*)__pyx_t_2);
  __pyx_t_2 = 0;
/* … */
struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_3_genexpr {
  PyObject_HEAD
  struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_2_calculate_timesize_weighted_average *__pyx_outer_scope;
  PyObject *__pyx_v_a;
  PyObject *__pyx_v_b;
  PyObject *__pyx_v_c;
  PyObject *__pyx_t_0;
  Py_ssize_t __pyx_t_1;
  PyObject *(*__pyx_t_2)(PyObject *);
};

+114:     return calculate_size_weighted_average(recs)
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_calculate_size_weighted_average); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 114, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
    }
  }
  if (!__pyx_t_3) {
    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_recs); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_1)) {
      PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_v_recs};
      __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_1, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_GOTREF(__pyx_t_2);
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_1)) {
      PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_v_recs};
      __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_1, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_GOTREF(__pyx_t_2);
    } else
    #endif
    {
      __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __pyx_t_3 = NULL;
      __Pyx_INCREF(__pyx_v_recs);
      __Pyx_GIVEREF(__pyx_v_recs);
      PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_recs);
      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_4, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_r = __pyx_t_2;
  __pyx_t_2 = 0;
  goto __pyx_L0;
 115: 
+116: def calculate_size_weighted_average(data):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_7cystats_13calculate_size_weighted_average(PyObject *__pyx_self, PyObject *__pyx_v_data); /*proto*/
static char __pyx_doc_4xpra_6server_7cystats_12calculate_size_weighted_average[] = "\n        This is a time weighted average where the size\n        of each record also gives it a weight boost.\n        This is to prevent small packets from skewing the average.\n        Data format: (event_time, size, value)\n    ";
static PyMethodDef __pyx_mdef_4xpra_6server_7cystats_13calculate_size_weighted_average = {"calculate_size_weighted_average", (PyCFunction)__pyx_pw_4xpra_6server_7cystats_13calculate_size_weighted_average, METH_O, __pyx_doc_4xpra_6server_7cystats_12calculate_size_weighted_average};
static PyObject *__pyx_pw_4xpra_6server_7cystats_13calculate_size_weighted_average(PyObject *__pyx_self, PyObject *__pyx_v_data) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_size_weighted_average (wrapper)", 0);
  __pyx_r = __pyx_pf_4xpra_6server_7cystats_12calculate_size_weighted_average(__pyx_self, ((PyObject *)__pyx_v_data));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
static PyObject *__pyx_gb_4xpra_6server_7cystats_31calculate_size_weighted_average_2generator2(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
/* … */
static PyObject *__pyx_pf_4xpra_6server_7cystats_12calculate_size_weighted_average(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data) {
  struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_4_calculate_size_weighted_average *__pyx_cur_scope;
  double __pyx_v_size_avg;
  double __pyx_v_now;
  double __pyx_v_tv;
  double __pyx_v_tw;
  double __pyx_v_rv;
  double __pyx_v_rw;
  double __pyx_v_event_time;
  double __pyx_v_size;
  double __pyx_v_size_ps;
  double __pyx_v_value;
  double __pyx_v_pw;
  double __pyx_v_w;
  double __pyx_v_delta;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_size_weighted_average", 0);
  __pyx_cur_scope = (struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_4_calculate_size_weighted_average *)__pyx_tp_new_4xpra_6server_7cystats___pyx_scope_struct_4_calculate_size_weighted_average(__pyx_ptype_4xpra_6server_7cystats___pyx_scope_struct_4_calculate_size_weighted_average, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_4_calculate_size_weighted_average *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 116, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_v_data = __pyx_v_data;
  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_data);
  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_data);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_AddTraceback("xpra.server.cystats.calculate_size_weighted_average", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__15 = PyTuple_Pack(16, __pyx_n_s_data, __pyx_n_s_size_avg, __pyx_n_s_now, __pyx_n_s_tv, __pyx_n_s_tw, __pyx_n_s_rv, __pyx_n_s_rw, __pyx_n_s_event_time, __pyx_n_s_size, __pyx_n_s_size_ps, __pyx_n_s_value, __pyx_n_s_pw, __pyx_n_s_w, __pyx_n_s_delta, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(0, 116, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__15);
  __Pyx_GIVEREF(__pyx_tuple__15);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_7cystats_13calculate_size_weighted_average, NULL, __pyx_n_s_xpra_server_cystats); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 116, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_calculate_size_weighted_average, __pyx_t_2) < 0) __PYX_ERR(0, 116, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__16 = (PyObject*)__Pyx_PyCode_New(1, 0, 16, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__15, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_xpra_server_cystats_pyx, __pyx_n_s_calculate_size_weighted_average, 116, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__16)) __PYX_ERR(0, 116, __pyx_L1_error)
/* … */
struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_4_calculate_size_weighted_average {
  PyObject_HEAD
  PyObject *__pyx_v_data;
};

 117:     """
 118:         This is a time weighted average where the size
 119:         of each record also gives it a weight boost.
 120:         This is to prevent small packets from skewing the average.
 121:         Data format: (event_time, size, value)
 122:     """
+123:     cdef double size_avg = sum(x for _, x, _ in data)/len(data)
static PyObject *__pyx_pf_4xpra_6server_7cystats_31calculate_size_weighted_average_genexpr(PyObject *__pyx_self) {
  struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_5_genexpr *__pyx_cur_scope;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_cur_scope = (struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_5_genexpr *)__pyx_tp_new_4xpra_6server_7cystats___pyx_scope_struct_5_genexpr(__pyx_ptype_4xpra_6server_7cystats___pyx_scope_struct_5_genexpr, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_5_genexpr *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 123, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_4xpra_6server_7cystats___pyx_scope_struct_4_calculate_size_weighted_average *) __pyx_self;
  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
  {
    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_4xpra_6server_7cystats_31calculate_size_weighted_average_2generator2, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_calculate_size_weighted_average_2, __pyx_n_s_xpra_server_cystats); if (unlikely(!gen)) __PYX_ERR(0, 123, __pyx_L1_error)
    __Pyx_DECREF(__pyx_cur_scope);
    __Pyx_RefNannyFinishContext();
    return (PyObject *) gen;
  }

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_AddTraceback("xpra.server.cystats.calculate_size_weighted_average.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_gb_4xpra_6server_7cystats_31calculate_size_weighted_average_2generator2(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */
{
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_L3_first_run:;
  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 123, __pyx_L1_error)
  if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data)) { __Pyx_RaiseClosureNameError("data"); __PYX_ERR(0, 123, __pyx_L1_error) }
  if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data)) {
    __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_data; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
    __pyx_t_3 = NULL;
  } else {
    __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_data); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 123, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 123, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_3)) {
      if (likely(PyList_CheckExact(__pyx_t_1))) {
        if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 123, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 123, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      } else {
        if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 123, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 123, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      }
    } else {
      __pyx_t_4 = __pyx_t_3(__pyx_t_1);
      if (unlikely(!__pyx_t_4)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 123, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_4);
    }
    if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
      PyObject* sequence = __pyx_t_4;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 3)) {
        if (size > 3) __Pyx_RaiseTooManyValuesError(3);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 123, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
        __pyx_t_7 = PyTuple_GET_ITEM(sequence, 2); 
      } else {
        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
        __pyx_t_7 = PyList_GET_ITEM(sequence, 2); 
      }
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(__pyx_t_7);
      #else
      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 123, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 123, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_7 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 123, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      #endif
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_8 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 123, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_9 = Py_TYPE(__pyx_t_8)->tp_iternext;
      index = 0; __pyx_t_5 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_5);
      index = 1; __pyx_t_6 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_6)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_6);
      index = 2; __pyx_t_7 = __pyx_t_9(__pyx_t_8); if (unlikely(!__pyx_t_7)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_7);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_9(__pyx_t_8), 3) < 0) __PYX_ERR(0, 123, __pyx_L1_error)
      __pyx_t_9 = NULL;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      goto __pyx_L7_unpacking_done;
      __pyx_L6_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_t_9 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 123, __pyx_L1_error)
      __pyx_L7_unpacking_done:;
    }
    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v__);
    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v__, __pyx_t_5);
    __Pyx_GIVEREF(__pyx_t_5);
    __pyx_t_5 = 0;
    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_x);
    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_x, __pyx_t_6);
    __Pyx_GIVEREF(__pyx_t_6);
    __pyx_t_6 = 0;
    __Pyx_GOTREF(__pyx_cur_scope->__pyx_v__);
    __Pyx_DECREF_SET(__pyx_cur_scope->__pyx_v__, __pyx_t_7);
    __Pyx_GIVEREF(__pyx_t_7);
    __pyx_t_7 = 0;
    __Pyx_INCREF(__pyx_cur_scope->__pyx_v_x);
    __pyx_r = __pyx_cur_scope->__pyx_v_x;
    __Pyx_XGIVEREF(__pyx_t_1);
    __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
    __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
    __pyx_cur_scope->__pyx_t_2 = __pyx_t_3;
    __Pyx_XGIVEREF(__pyx_r);
    __Pyx_RefNannyFinishContext();
    __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
    /* return from generator, yielding value */
    __pyx_generator->resume_label = 1;
    return __pyx_r;
    __pyx_L8_resume_from_yield:;
    __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
    __pyx_cur_scope->__pyx_t_0 = 0;
    __Pyx_XGOTREF(__pyx_t_1);
    __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
    __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 123, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);

  /* function exit code */
  PyErr_SetNone(PyExc_StopIteration);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_r); __pyx_r = 0;
  __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
  __pyx_generator->resume_label = -1;
  __Pyx_Coroutine_clear((PyObject*)__pyx_generator);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_t_1 = __pyx_pf_4xpra_6server_7cystats_31calculate_size_weighted_average_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_sum, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __pyx_cur_scope->__pyx_v_data;
  __Pyx_INCREF(__pyx_t_1);
  __pyx_t_3 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_4 = __Pyx_PyNumber_Divide(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_5 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_5 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_size_avg = __pyx_t_5;
+124:     if size_avg<=0:
  __pyx_t_6 = ((__pyx_v_size_avg <= 0.0) != 0);
  if (__pyx_t_6) {
/* … */
  }
+125:         size_avg = 1
    __pyx_v_size_avg = 1.0;
+126:     cdef double now = monotonic_time()              #@DuplicatedSignature
  __pyx_v_now = __pyx_f_4xpra_14monotonic_time_monotonic_time();
+127:     cdef double tv = 0.0                            #@DuplicatedSignature
  __pyx_v_tv = 0.0;
+128:     cdef double tw = 0.0                            #@DuplicatedSignature
  __pyx_v_tw = 0.0;
+129:     cdef double rv = 0.0                            #@DuplicatedSignature
  __pyx_v_rv = 0.0;
+130:     cdef double rw = 0.0                            #@DuplicatedSignature
  __pyx_v_rw = 0.0;
 131:     cdef double event_time                          #@DuplicatedSignature
 132:     cdef double size
 133:     cdef double size_ps
 134:     cdef double value
 135:     cdef double pw
 136:     cdef double w                                   #@DuplicatedSignature
 137:     cdef double delta                               #@DuplicatedSignature
+138:     for event_time, size, value in data:
  if (likely(PyList_CheckExact(__pyx_cur_scope->__pyx_v_data)) || PyTuple_CheckExact(__pyx_cur_scope->__pyx_v_data)) {
    __pyx_t_4 = __pyx_cur_scope->__pyx_v_data; __Pyx_INCREF(__pyx_t_4); __pyx_t_3 = 0;
    __pyx_t_7 = NULL;
  } else {
    __pyx_t_3 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_cur_scope->__pyx_v_data); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 138, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_7 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 138, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_7)) {
      if (likely(PyList_CheckExact(__pyx_t_4))) {
        if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_4)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 138, __pyx_L1_error)
        #else
        __pyx_t_1 = PySequence_ITEM(__pyx_t_4, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 138, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        #endif
      } else {
        if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 138, __pyx_L1_error)
        #else
        __pyx_t_1 = PySequence_ITEM(__pyx_t_4, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 138, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        #endif
      }
    } else {
      __pyx_t_1 = __pyx_t_7(__pyx_t_4);
      if (unlikely(!__pyx_t_1)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 138, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_1);
    }
    if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
      PyObject* sequence = __pyx_t_1;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 3)) {
        if (size > 3) __Pyx_RaiseTooManyValuesError(3);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 138, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1); 
        __pyx_t_9 = PyTuple_GET_ITEM(sequence, 2); 
      } else {
        __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_8 = PyList_GET_ITEM(sequence, 1); 
        __pyx_t_9 = PyList_GET_ITEM(sequence, 2); 
      }
      __Pyx_INCREF(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_8);
      __Pyx_INCREF(__pyx_t_9);
      #else
      __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 138, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 138, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __pyx_t_9 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 138, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      #endif
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 138, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_11 = Py_TYPE(__pyx_t_10)->tp_iternext;
      index = 0; __pyx_t_2 = __pyx_t_11(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_2);
      index = 1; __pyx_t_8 = __pyx_t_11(__pyx_t_10); if (unlikely(!__pyx_t_8)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_8);
      index = 2; __pyx_t_9 = __pyx_t_11(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L6_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_9);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_10), 3) < 0) __PYX_ERR(0, 138, __pyx_L1_error)
      __pyx_t_11 = NULL;
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      goto __pyx_L7_unpacking_done;
      __pyx_L6_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __pyx_t_11 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 138, __pyx_L1_error)
      __pyx_L7_unpacking_done:;
    }
    __pyx_t_5 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_5 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 138, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_12 = __pyx_PyFloat_AsDouble(__pyx_t_8); if (unlikely((__pyx_t_12 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 138, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    __pyx_t_13 = __pyx_PyFloat_AsDouble(__pyx_t_9); if (unlikely((__pyx_t_13 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 138, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
    __pyx_v_event_time = __pyx_t_5;
    __pyx_v_size = __pyx_t_12;
    __pyx_v_value = __pyx_t_13;
/* … */
    __pyx_L4_continue:;
  }
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+139:         if value<=0:
    __pyx_t_6 = ((__pyx_v_value <= 0.0) != 0);
    if (__pyx_t_6) {
/* … */
    }
+140:             continue        #invalid record
      goto __pyx_L4_continue;
+141:         delta = now-event_time
    __pyx_v_delta = (__pyx_v_now - __pyx_v_event_time);
+142:         pw = clogp(size/size_avg)
    __pyx_v_pw = __pyx_f_4xpra_6server_7cystats_clogp((__pyx_v_size / __pyx_v_size_avg));
+143:         size_ps = max(1, size*value)
    __pyx_t_13 = (__pyx_v_size * __pyx_v_value);
    __pyx_t_14 = 1;
    if (((__pyx_t_13 > __pyx_t_14) != 0)) {
      __pyx_t_12 = __pyx_t_13;
    } else {
      __pyx_t_12 = __pyx_t_14;
    }
    __pyx_v_size_ps = __pyx_t_12;
+144:         w = pw/(1.0+delta)
    __pyx_v_w = (__pyx_v_pw / (1.0 + __pyx_v_delta));
+145:         tv += w*size_ps
    __pyx_v_tv = (__pyx_v_tv + (__pyx_v_w * __pyx_v_size_ps));
+146:         tw += w*size
    __pyx_v_tw = (__pyx_v_tw + (__pyx_v_w * __pyx_v_size));
+147:         w = pw/(0.1+delta**2)
    __pyx_v_w = (__pyx_v_pw / (0.1 + pow(__pyx_v_delta, 2.0)));
+148:         rv += w*size_ps
    __pyx_v_rv = (__pyx_v_rv + (__pyx_v_w * __pyx_v_size_ps));
+149:         rw += w*size
    __pyx_v_rw = (__pyx_v_rw + (__pyx_v_w * __pyx_v_size));
+150:     if tw<=0:
  __pyx_t_6 = ((__pyx_v_tw <= 0.0) != 0);
  if (__pyx_t_6) {
/* … */
  }
+151:         tw = 1
    __pyx_v_tw = 1.0;
+152:     if rw<=0:
  __pyx_t_6 = ((__pyx_v_rw <= 0.0) != 0);
  if (__pyx_t_6) {
/* … */
  }
+153:         rw = 1
    __pyx_v_rw = 1.0;
+154:     return float(tv / tw), float(rv / rw)
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_4 = PyFloat_FromDouble((__pyx_v_tv / __pyx_v_tw)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 154, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = PyFloat_FromDouble((__pyx_v_rv / __pyx_v_rw)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 154, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 154, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_9);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_1);
  __pyx_t_4 = 0;
  __pyx_t_1 = 0;
  __pyx_r = __pyx_t_9;
  __pyx_t_9 = 0;
  goto __pyx_L0;
 155: 
+156: def calculate_for_target(metric, float target_value, float avg_value, float recent_value, float aim=0.5, float div=1.0, float slope=0.1, smoothing=logp, float weight_multiplier=1.0):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_7cystats_15calculate_for_target(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_4xpra_6server_7cystats_14calculate_for_target[] = "\n        Calculates factor and weight to try to bring us closer to 'target_value'.\n\n        The factor is a function of how far the 'recent_value' is from it,\n        and of how things are progressing (better or worse than average),\n        'aim' controls the proportion of each. (at 0.5 it is an average of both,\n        the closer to 0 the more target matters, the closer to 1.0 the more average matters)\n    ";
static PyMethodDef __pyx_mdef_4xpra_6server_7cystats_15calculate_for_target = {"calculate_for_target", (PyCFunction)__pyx_pw_4xpra_6server_7cystats_15calculate_for_target, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4xpra_6server_7cystats_14calculate_for_target};
static PyObject *__pyx_pw_4xpra_6server_7cystats_15calculate_for_target(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_metric = 0;
  float __pyx_v_target_value;
  float __pyx_v_avg_value;
  float __pyx_v_recent_value;
  float __pyx_v_aim;
  float __pyx_v_div;
  float __pyx_v_slope;
  PyObject *__pyx_v_smoothing = 0;
  float __pyx_v_weight_multiplier;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_for_target (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_metric,&__pyx_n_s_target_value,&__pyx_n_s_avg_value,&__pyx_n_s_recent_value,&__pyx_n_s_aim,&__pyx_n_s_div,&__pyx_n_s_slope,&__pyx_n_s_smoothing,&__pyx_n_s_weight_multiplier,0};
    PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
    values[7] = __pyx_k_;
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
        CYTHON_FALLTHROUGH;
        case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
        CYTHON_FALLTHROUGH;
        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
        CYTHON_FALLTHROUGH;
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_metric)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_target_value)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("calculate_for_target", 0, 4, 9, 1); __PYX_ERR(0, 156, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_avg_value)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("calculate_for_target", 0, 4, 9, 2); __PYX_ERR(0, 156, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_recent_value)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("calculate_for_target", 0, 4, 9, 3); __PYX_ERR(0, 156, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_aim);
          if (value) { values[4] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  5:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_div);
          if (value) { values[5] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  6:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_slope);
          if (value) { values[6] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  7:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_smoothing);
          if (value) { values[7] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  8:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_weight_multiplier);
          if (value) { values[8] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "calculate_for_target") < 0)) __PYX_ERR(0, 156, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
        CYTHON_FALLTHROUGH;
        case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
        CYTHON_FALLTHROUGH;
        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
        CYTHON_FALLTHROUGH;
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_metric = values[0];
    __pyx_v_target_value = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_target_value == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 156, __pyx_L3_error)
    __pyx_v_avg_value = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_avg_value == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 156, __pyx_L3_error)
    __pyx_v_recent_value = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_recent_value == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 156, __pyx_L3_error)
    if (values[4]) {
      __pyx_v_aim = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_aim == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 156, __pyx_L3_error)
    } else {
      __pyx_v_aim = ((float)0.5);
    }
    if (values[5]) {
      __pyx_v_div = __pyx_PyFloat_AsFloat(values[5]); if (unlikely((__pyx_v_div == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 156, __pyx_L3_error)
    } else {
      __pyx_v_div = ((float)1.0);
    }
    if (values[6]) {
      __pyx_v_slope = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_slope == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 156, __pyx_L3_error)
    } else {
      __pyx_v_slope = ((float)0.1);
    }
    __pyx_v_smoothing = values[7];
    if (values[8]) {
      __pyx_v_weight_multiplier = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_weight_multiplier == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 156, __pyx_L3_error)
    } else {
      __pyx_v_weight_multiplier = ((float)1.0);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("calculate_for_target", 0, 4, 9, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 156, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.cystats.calculate_for_target", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_7cystats_14calculate_for_target(__pyx_self, __pyx_v_metric, __pyx_v_target_value, __pyx_v_avg_value, __pyx_v_recent_value, __pyx_v_aim, __pyx_v_div, __pyx_v_slope, __pyx_v_smoothing, __pyx_v_weight_multiplier);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_7cystats_14calculate_for_target(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_metric, float __pyx_v_target_value, float __pyx_v_avg_value, float __pyx_v_recent_value, float __pyx_v_aim, float __pyx_v_div, float __pyx_v_slope, PyObject *__pyx_v_smoothing, float __pyx_v_weight_multiplier) {
  double __pyx_v_d;
  double __pyx_v_target_factor;
  double __pyx_v_avg_factor;
  double __pyx_v_aimed_average;
  PyObject *__pyx_v_factor = NULL;
  PyObject *__pyx_v_weight = NULL;
  PyObject *__pyx_v_info = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_for_target", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_AddTraceback("xpra.server.cystats.calculate_for_target", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_factor);
  __Pyx_XDECREF(__pyx_v_weight);
  __Pyx_XDECREF(__pyx_v_info);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logp); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_k_ = __pyx_t_2;
  __Pyx_GIVEREF(__pyx_t_2);
  __pyx_t_2 = 0;
/* … */
  __pyx_tuple__17 = PyTuple_Pack(16, __pyx_n_s_metric, __pyx_n_s_target_value, __pyx_n_s_avg_value, __pyx_n_s_recent_value, __pyx_n_s_aim, __pyx_n_s_div, __pyx_n_s_slope, __pyx_n_s_smoothing, __pyx_n_s_weight_multiplier, __pyx_n_s_d, __pyx_n_s_target_factor, __pyx_n_s_avg_factor, __pyx_n_s_aimed_average, __pyx_n_s_factor, __pyx_n_s_weight, __pyx_n_s_info); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__17);
  __Pyx_GIVEREF(__pyx_tuple__17);
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_7cystats_15calculate_for_target, NULL, __pyx_n_s_xpra_server_cystats); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_calculate_for_target, __pyx_t_2) < 0) __PYX_ERR(0, 156, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__18 = (PyObject*)__Pyx_PyCode_New(9, 0, 16, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__17, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_xpra_server_cystats_pyx, __pyx_n_s_calculate_for_target, 156, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__18)) __PYX_ERR(0, 156, __pyx_L1_error)
 157:     """
 158:         Calculates factor and weight to try to bring us closer to 'target_value'.
 159: 
 160:         The factor is a function of how far the 'recent_value' is from it,
 161:         and of how things are progressing (better or worse than average),
 162:         'aim' controls the proportion of each. (at 0.5 it is an average of both,
 163:         the closer to 0 the more target matters, the closer to 1.0 the more average matters)
 164:     """
+165:     assert aim>0.0 and aim<1.0
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    __pyx_t_2 = ((__pyx_v_aim > 0.0) != 0);
    if (__pyx_t_2) {
    } else {
      __pyx_t_1 = __pyx_t_2;
      goto __pyx_L3_bool_binop_done;
    }
    __pyx_t_2 = ((__pyx_v_aim < 1.0) != 0);
    __pyx_t_1 = __pyx_t_2;
    __pyx_L3_bool_binop_done:;
    if (unlikely(!__pyx_t_1)) {
      PyErr_SetNone(PyExc_AssertionError);
      __PYX_ERR(0, 165, __pyx_L1_error)
    }
  }
  #endif
 166:     #target factor: how far are we from 'target'
+167:     cdef double d = float(div)
  __pyx_v_d = ((double)__pyx_v_div);
+168:     cdef double target_factor = (float(recent_value)/d)/(slope+float(target_value)/d)
  __pyx_v_target_factor = ((((double)__pyx_v_recent_value) / __pyx_v_d) / (__pyx_v_slope + (((double)__pyx_v_target_value) / __pyx_v_d)));
 169:     #average factor: how far are we from the 'average'
+170:     cdef double avg_factor = (float(recent_value)/d)/(slope+float(avg_value)/d)
  __pyx_v_avg_factor = ((((double)__pyx_v_recent_value) / __pyx_v_d) / (__pyx_v_slope + (((double)__pyx_v_avg_value) / __pyx_v_d)));
 171:     #aimed average: combine the two factors above with the 'aim' weight distribution:
+172:     cdef double aimed_average = target_factor*(1.0-aim) + avg_factor*aim
  __pyx_v_aimed_average = ((__pyx_v_target_factor * (1.0 - __pyx_v_aim)) + (__pyx_v_avg_factor * __pyx_v_aim));
+173:     factor = smoothing(aimed_average)
  __pyx_t_4 = PyFloat_FromDouble(__pyx_v_aimed_average); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 173, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_INCREF(__pyx_v_smoothing);
  __pyx_t_5 = __pyx_v_smoothing; __pyx_t_6 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
    }
  }
  if (!__pyx_t_6) {
    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 173, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_GOTREF(__pyx_t_3);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_5)) {
      PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_4};
      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 173, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
      PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_4};
      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 173, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else
    #endif
    {
      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 173, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_4);
      __pyx_t_4 = 0;
      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 173, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_factor = __pyx_t_3;
  __pyx_t_3 = 0;
+174:     weight = smoothing(max(0.0, 1.0-factor, factor-1.0)) * weight_multiplier
  __pyx_t_5 = __Pyx_PyFloat_SubtractCObj(__pyx_float_1_0, __pyx_v_factor, 1.0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_7 = __Pyx_PyFloat_SubtractObjC(__pyx_v_factor, __pyx_float_1_0, 1.0, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __pyx_t_8 = 0.0;
  __pyx_t_6 = PyFloat_FromDouble(__pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_9 = PyObject_RichCompare(__pyx_t_5, __pyx_t_6, Py_GT); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
  if (__pyx_t_1) {
    __Pyx_INCREF(__pyx_t_5);
    __pyx_t_4 = __pyx_t_5;
  } else {
    __pyx_t_9 = PyFloat_FromDouble(__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 174, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_9);
    __pyx_t_4 = __pyx_t_9;
    __pyx_t_9 = 0;
  }
  __Pyx_INCREF(__pyx_t_4);
  __pyx_t_9 = __pyx_t_4;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_6 = PyObject_RichCompare(__pyx_t_7, __pyx_t_9, Py_GT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 174, __pyx_L1_error)
  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  if (__pyx_t_1) {
    __Pyx_INCREF(__pyx_t_7);
    __pyx_t_4 = __pyx_t_7;
  } else {
    __Pyx_INCREF(__pyx_t_9);
    __pyx_t_4 = __pyx_t_9;
  }
  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_INCREF(__pyx_v_smoothing);
  __pyx_t_5 = __pyx_v_smoothing; __pyx_t_7 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_7)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_7);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
    }
  }
  if (!__pyx_t_7) {
    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 174, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_GOTREF(__pyx_t_3);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_5)) {
      PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_4};
      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 174, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
      PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_4};
      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 174, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else
    #endif
    {
      __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 174, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL;
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_4);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 174, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = PyFloat_FromDouble(__pyx_v_weight_multiplier); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_9 = PyNumber_Multiply(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_9);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_weight = __pyx_t_9;
  __pyx_t_9 = 0;
+175:     info = {"avg"       : int(1000.0*avg_value),
  __pyx_t_9 = __Pyx_PyDict_NewPresized(8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 175, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_9);
  __pyx_t_5 = __Pyx_PyInt_FromDouble((1000.0 * __pyx_v_avg_value)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 175, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_avg, __pyx_t_5) < 0) __PYX_ERR(0, 175, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+176:             "recent"    : int(1000.0*recent_value),
  __pyx_t_5 = __Pyx_PyInt_FromDouble((1000.0 * __pyx_v_recent_value)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 176, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_recent, __pyx_t_5) < 0) __PYX_ERR(0, 175, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+177:             "target"    : int(1000.0*target_value),
  __pyx_t_5 = __Pyx_PyInt_FromDouble((1000.0 * __pyx_v_target_value)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 177, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_target, __pyx_t_5) < 0) __PYX_ERR(0, 175, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+178:             "aim"       : int(1000.0*aim),
  __pyx_t_5 = __Pyx_PyInt_FromDouble((1000.0 * __pyx_v_aim)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 178, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_aim, __pyx_t_5) < 0) __PYX_ERR(0, 175, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+179:             "aimed_avg" : int(1000.0*aimed_average),
  __pyx_t_5 = __Pyx_PyInt_FromDouble((1000.0 * __pyx_v_aimed_average)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 179, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_aimed_avg, __pyx_t_5) < 0) __PYX_ERR(0, 175, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+180:             "div"       : int(1000.0*div),
  __pyx_t_5 = __Pyx_PyInt_FromDouble((1000.0 * __pyx_v_div)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 180, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_div, __pyx_t_5) < 0) __PYX_ERR(0, 175, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+181:             "smoothing" : smn(smoothing),
  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_smn); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 181, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  if (!__pyx_t_4) {
    __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_smoothing); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 181, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_smoothing};
      __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 181, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_GOTREF(__pyx_t_5);
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_v_smoothing};
      __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 181, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_GOTREF(__pyx_t_5);
    } else
    #endif
    {
      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 181, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
      __Pyx_INCREF(__pyx_v_smoothing);
      __Pyx_GIVEREF(__pyx_v_smoothing);
      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_smoothing);
      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 181, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_smoothing, __pyx_t_5) < 0) __PYX_ERR(0, 175, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+182:             "weight_multiplier" : int(1000.0*weight_multiplier),
  __pyx_t_5 = __Pyx_PyInt_FromDouble((1000.0 * __pyx_v_weight_multiplier)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 182, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_weight_multiplier, __pyx_t_5) < 0) __PYX_ERR(0, 175, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_v_info = ((PyObject*)__pyx_t_9);
  __pyx_t_9 = 0;
 183:             }
+184:     return metric, info , factor, weight
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_9 = PyTuple_New(4); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 184, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_9);
  __Pyx_INCREF(__pyx_v_metric);
  __Pyx_GIVEREF(__pyx_v_metric);
  PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_metric);
  __Pyx_INCREF(__pyx_v_info);
  __Pyx_GIVEREF(__pyx_v_info);
  PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_info);
  __Pyx_INCREF(__pyx_v_factor);
  __Pyx_GIVEREF(__pyx_v_factor);
  PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_v_factor);
  __Pyx_INCREF(__pyx_v_weight);
  __Pyx_GIVEREF(__pyx_v_weight);
  PyTuple_SET_ITEM(__pyx_t_9, 3, __pyx_v_weight);
  __pyx_r = __pyx_t_9;
  __pyx_t_9 = 0;
  goto __pyx_L0;
 185: 
+186: def calculate_for_average(metric, float avg_value, float recent_value, float div=1.0, float weight_offset=0.5, float weight_div=1.0):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_7cystats_17calculate_for_average(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_4xpra_6server_7cystats_16calculate_for_average[] = "\n        Calculates factor and weight based on how far we are from the average value.\n        This is used by metrics for which we do not know the optimal target value.\n    ";
static PyMethodDef __pyx_mdef_4xpra_6server_7cystats_17calculate_for_average = {"calculate_for_average", (PyCFunction)__pyx_pw_4xpra_6server_7cystats_17calculate_for_average, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4xpra_6server_7cystats_16calculate_for_average};
static PyObject *__pyx_pw_4xpra_6server_7cystats_17calculate_for_average(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_metric = 0;
  float __pyx_v_avg_value;
  float __pyx_v_recent_value;
  float __pyx_v_div;
  float __pyx_v_weight_offset;
  float __pyx_v_weight_div;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_for_average (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_metric,&__pyx_n_s_avg_value,&__pyx_n_s_recent_value,&__pyx_n_s_div,&__pyx_n_s_weight_offset,&__pyx_n_s_weight_div,0};
    PyObject* values[6] = {0,0,0,0,0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_metric)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_avg_value)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("calculate_for_average", 0, 3, 6, 1); __PYX_ERR(0, 186, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_recent_value)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("calculate_for_average", 0, 3, 6, 2); __PYX_ERR(0, 186, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_div);
          if (value) { values[3] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_weight_offset);
          if (value) { values[4] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  5:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_weight_div);
          if (value) { values[5] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "calculate_for_average") < 0)) __PYX_ERR(0, 186, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_metric = values[0];
    __pyx_v_avg_value = __pyx_PyFloat_AsFloat(values[1]); if (unlikely((__pyx_v_avg_value == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 186, __pyx_L3_error)
    __pyx_v_recent_value = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_recent_value == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 186, __pyx_L3_error)
    if (values[3]) {
      __pyx_v_div = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_div == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 186, __pyx_L3_error)
    } else {
      __pyx_v_div = ((float)1.0);
    }
    if (values[4]) {
      __pyx_v_weight_offset = __pyx_PyFloat_AsFloat(values[4]); if (unlikely((__pyx_v_weight_offset == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 186, __pyx_L3_error)
    } else {
      __pyx_v_weight_offset = ((float)0.5);
    }
    if (values[5]) {
      __pyx_v_weight_div = __pyx_PyFloat_AsFloat(values[5]); if (unlikely((__pyx_v_weight_div == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 186, __pyx_L3_error)
    } else {
      __pyx_v_weight_div = ((float)1.0);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("calculate_for_average", 0, 3, 6, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 186, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.cystats.calculate_for_average", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_7cystats_16calculate_for_average(__pyx_self, __pyx_v_metric, __pyx_v_avg_value, __pyx_v_recent_value, __pyx_v_div, __pyx_v_weight_offset, __pyx_v_weight_div);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_7cystats_16calculate_for_average(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_metric, float __pyx_v_avg_value, float __pyx_v_recent_value, float __pyx_v_div, float __pyx_v_weight_offset, float __pyx_v_weight_div) {
  double __pyx_v_avg;
  double __pyx_v_recent;
  double __pyx_v_factor;
  double __pyx_v_weight;
  PyObject *__pyx_v_info = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate_for_average", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("xpra.server.cystats.calculate_for_average", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_info);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__19 = PyTuple_Pack(11, __pyx_n_s_metric, __pyx_n_s_avg_value, __pyx_n_s_recent_value, __pyx_n_s_div, __pyx_n_s_weight_offset, __pyx_n_s_weight_div, __pyx_n_s_avg, __pyx_n_s_recent, __pyx_n_s_factor, __pyx_n_s_weight, __pyx_n_s_info); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 186, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__19);
  __Pyx_GIVEREF(__pyx_tuple__19);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_7cystats_17calculate_for_average, NULL, __pyx_n_s_xpra_server_cystats); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 186, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_calculate_for_average, __pyx_t_2) < 0) __PYX_ERR(0, 186, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__20 = (PyObject*)__Pyx_PyCode_New(6, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__19, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_xpra_server_cystats_pyx, __pyx_n_s_calculate_for_average, 186, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__20)) __PYX_ERR(0, 186, __pyx_L1_error)
 187:     """
 188:         Calculates factor and weight based on how far we are from the average value.
 189:         This is used by metrics for which we do not know the optimal target value.
 190:     """
+191:     cdef double avg = avg_value/div
  __pyx_v_avg = (__pyx_v_avg_value / __pyx_v_div);
+192:     cdef double recent = recent_value/div
  __pyx_v_recent = (__pyx_v_recent_value / __pyx_v_div);
+193:     cdef double factor = clogp(recent/avg)
  __pyx_v_factor = __pyx_f_4xpra_6server_7cystats_clogp((__pyx_v_recent / __pyx_v_avg));
+194:     cdef double weight = max(0, max(factor, 1.0/factor)-1.0+weight_offset)/weight_div
  __pyx_t_1 = (1.0 / __pyx_v_factor);
  __pyx_t_2 = __pyx_v_factor;
  if (((__pyx_t_1 > __pyx_t_2) != 0)) {
    __pyx_t_3 = __pyx_t_1;
  } else {
    __pyx_t_3 = __pyx_t_2;
  }
  __pyx_t_1 = ((__pyx_t_3 - 1.0) + __pyx_v_weight_offset);
  __pyx_t_4 = 0;
  if (((__pyx_t_1 > __pyx_t_4) != 0)) {
    __pyx_t_3 = __pyx_t_1;
  } else {
    __pyx_t_3 = __pyx_t_4;
  }
  __pyx_v_weight = (__pyx_t_3 / __pyx_v_weight_div);
+195:     info = {"avg"   : int(1000.0*avg),
  __pyx_t_5 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 195, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_6 = __Pyx_PyInt_FromDouble((1000.0 * __pyx_v_avg)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 195, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_avg, __pyx_t_6) < 0) __PYX_ERR(0, 195, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+196:             "recent": int(1000.0*recent)}
  __pyx_t_6 = __Pyx_PyInt_FromDouble((1000.0 * __pyx_v_recent)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 196, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_recent, __pyx_t_6) < 0) __PYX_ERR(0, 195, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_v_info = ((PyObject*)__pyx_t_5);
  __pyx_t_5 = 0;
+197:     return  metric, info, float(factor), float(weight)
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_5 = PyFloat_FromDouble(__pyx_v_factor); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 197, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_6 = PyFloat_FromDouble(__pyx_v_weight); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 197, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_7 = PyTuple_New(4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 197, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_INCREF(__pyx_v_metric);
  __Pyx_GIVEREF(__pyx_v_metric);
  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_metric);
  __Pyx_INCREF(__pyx_v_info);
  __Pyx_GIVEREF(__pyx_v_info);
  PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_info);
  __Pyx_GIVEREF(__pyx_t_5);
  PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_t_5);
  __Pyx_GIVEREF(__pyx_t_6);
  PyTuple_SET_ITEM(__pyx_t_7, 3, __pyx_t_6);
  __pyx_t_5 = 0;
  __pyx_t_6 = 0;
  __pyx_r = __pyx_t_7;
  __pyx_t_7 = 0;
  goto __pyx_L0;
 198: 
+199: def queue_inspect(metric, time_values, float target=1.0, float div=1.0, smoothing=logp):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_7cystats_19queue_inspect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_4xpra_6server_7cystats_18queue_inspect[] = "\n        Given an historical list of values and a current value,\n        figure out if things are getting better or worse.\n    ";
static PyMethodDef __pyx_mdef_4xpra_6server_7cystats_19queue_inspect = {"queue_inspect", (PyCFunction)__pyx_pw_4xpra_6server_7cystats_19queue_inspect, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4xpra_6server_7cystats_18queue_inspect};
static PyObject *__pyx_pw_4xpra_6server_7cystats_19queue_inspect(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_metric = 0;
  PyObject *__pyx_v_time_values = 0;
  float __pyx_v_target;
  float __pyx_v_div;
  PyObject *__pyx_v_smoothing = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("queue_inspect (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_metric,&__pyx_n_s_time_values,&__pyx_n_s_target,&__pyx_n_s_div,&__pyx_n_s_smoothing,0};
    PyObject* values[5] = {0,0,0,0,0};
    values[4] = __pyx_k__2;
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_metric)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_time_values)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("queue_inspect", 0, 2, 5, 1); __PYX_ERR(0, 199, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_target);
          if (value) { values[2] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_div);
          if (value) { values[3] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_smoothing);
          if (value) { values[4] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "queue_inspect") < 0)) __PYX_ERR(0, 199, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_metric = values[0];
    __pyx_v_time_values = values[1];
    if (values[2]) {
      __pyx_v_target = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_target == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 199, __pyx_L3_error)
    } else {
      __pyx_v_target = ((float)1.0);
    }
    if (values[3]) {
      __pyx_v_div = __pyx_PyFloat_AsFloat(values[3]); if (unlikely((__pyx_v_div == (float)-1) && PyErr_Occurred())) __PYX_ERR(0, 199, __pyx_L3_error)
    } else {
      __pyx_v_div = ((float)1.0);
    }
    __pyx_v_smoothing = values[4];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("queue_inspect", 0, 2, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 199, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.cystats.queue_inspect", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_7cystats_18queue_inspect(__pyx_self, __pyx_v_metric, __pyx_v_time_values, __pyx_v_target, __pyx_v_div, __pyx_v_smoothing);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_7cystats_18queue_inspect(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_metric, PyObject *__pyx_v_time_values, float __pyx_v_target, float __pyx_v_div, PyObject *__pyx_v_smoothing) {
  PyObject *__pyx_v_avg = NULL;
  PyObject *__pyx_v_recent = NULL;
  PyObject *__pyx_v_weight_multiplier = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("queue_inspect", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_AddTraceback("xpra.server.cystats.queue_inspect", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_avg);
  __Pyx_XDECREF(__pyx_v_recent);
  __Pyx_XDECREF(__pyx_v_weight_multiplier);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logp); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 199, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_k__2 = __pyx_t_2;
  __Pyx_GIVEREF(__pyx_t_2);
  __pyx_t_2 = 0;
/* … */
  __pyx_tuple__21 = PyTuple_Pack(8, __pyx_n_s_metric, __pyx_n_s_time_values, __pyx_n_s_target, __pyx_n_s_div, __pyx_n_s_smoothing, __pyx_n_s_avg, __pyx_n_s_recent, __pyx_n_s_weight_multiplier); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 199, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__21);
  __Pyx_GIVEREF(__pyx_tuple__21);
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_7cystats_19queue_inspect, NULL, __pyx_n_s_xpra_server_cystats); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 199, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_queue_inspect, __pyx_t_2) < 0) __PYX_ERR(0, 199, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 200:     """
 201:         Given an historical list of values and a current value,
 202:         figure out if things are getting better or worse.
 203:     """
 204:     #inspect a queue size history: figure out if things are better or worse than before
+205:     if len(time_values)==0:
  __pyx_t_1 = PyObject_Length(__pyx_v_time_values); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 205, __pyx_L1_error)
  __pyx_t_2 = ((__pyx_t_1 == 0) != 0);
  if (__pyx_t_2) {
/* … */
  }
+206:         return  metric, {}, 1.0, 0.0
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_3 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 206, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 206, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_INCREF(__pyx_v_metric);
    __Pyx_GIVEREF(__pyx_v_metric);
    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_metric);
    __Pyx_GIVEREF(__pyx_t_3);
    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
    __Pyx_INCREF(__pyx_float_1_0);
    __Pyx_GIVEREF(__pyx_float_1_0);
    PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_float_1_0);
    __Pyx_INCREF(__pyx_float_0_0);
    __Pyx_GIVEREF(__pyx_float_0_0);
    PyTuple_SET_ITEM(__pyx_t_4, 3, __pyx_float_0_0);
    __pyx_t_3 = 0;
    __pyx_r = __pyx_t_4;
    __pyx_t_4 = 0;
    goto __pyx_L0;
+207:     avg, recent = calculate_time_weighted_average(tuple(time_values))
  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_calculate_time_weighted_average); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 207, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = __Pyx_PySequence_Tuple(__pyx_v_time_values); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 207, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_6 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  if (!__pyx_t_6) {
    __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 207, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_GOTREF(__pyx_t_4);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
      __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 207, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
      __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 207, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    } else
    #endif
    {
      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 207, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
      __Pyx_GIVEREF(__pyx_t_5);
      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
      __pyx_t_5 = 0;
      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 207, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if ((likely(PyTuple_CheckExact(__pyx_t_4))) || (PyList_CheckExact(__pyx_t_4))) {
    PyObject* sequence = __pyx_t_4;
    Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
    if (unlikely(size != 2)) {
      if (size > 2) __Pyx_RaiseTooManyValuesError(2);
      else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
      __PYX_ERR(0, 207, __pyx_L1_error)
    }
    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    if (likely(PyTuple_CheckExact(sequence))) {
      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
      __pyx_t_7 = PyTuple_GET_ITEM(sequence, 1); 
    } else {
      __pyx_t_3 = PyList_GET_ITEM(sequence, 0); 
      __pyx_t_7 = PyList_GET_ITEM(sequence, 1); 
    }
    __Pyx_INCREF(__pyx_t_3);
    __Pyx_INCREF(__pyx_t_7);
    #else
    __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 207, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_7 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 207, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    #endif
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  } else {
    Py_ssize_t index = -1;
    __pyx_t_5 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 207, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_8 = Py_TYPE(__pyx_t_5)->tp_iternext;
    index = 0; __pyx_t_3 = __pyx_t_8(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L4_unpacking_failed;
    __Pyx_GOTREF(__pyx_t_3);
    index = 1; __pyx_t_7 = __pyx_t_8(__pyx_t_5); if (unlikely(!__pyx_t_7)) goto __pyx_L4_unpacking_failed;
    __Pyx_GOTREF(__pyx_t_7);
    if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_5), 2) < 0) __PYX_ERR(0, 207, __pyx_L1_error)
    __pyx_t_8 = NULL;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    goto __pyx_L5_unpacking_done;
    __pyx_L4_unpacking_failed:;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_8 = NULL;
    if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
    __PYX_ERR(0, 207, __pyx_L1_error)
    __pyx_L5_unpacking_done:;
  }
  __pyx_v_avg = __pyx_t_3;
  __pyx_t_3 = 0;
  __pyx_v_recent = __pyx_t_7;
  __pyx_t_7 = 0;
+208:     weight_multiplier = sqrt(max(avg, recent) / div / target)
  __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_sqrt); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 208, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __Pyx_INCREF(__pyx_v_recent);
  __pyx_t_3 = __pyx_v_recent;
  __Pyx_INCREF(__pyx_v_avg);
  __pyx_t_5 = __pyx_v_avg;
  __pyx_t_9 = PyObject_RichCompare(__pyx_t_3, __pyx_t_5, Py_GT); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 208, __pyx_L1_error)
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 208, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
  if (__pyx_t_2) {
    __Pyx_INCREF(__pyx_t_3);
    __pyx_t_6 = __pyx_t_3;
  } else {
    __Pyx_INCREF(__pyx_t_5);
    __pyx_t_6 = __pyx_t_5;
  }
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = PyFloat_FromDouble(__pyx_v_div); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 208, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = __Pyx_PyNumber_Divide(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 208, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = PyFloat_FromDouble(__pyx_v_target); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 208, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_6 = __Pyx_PyNumber_Divide(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 208, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_7))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_7);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_7, function);
    }
  }
  if (!__pyx_t_3) {
    __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 208, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_GOTREF(__pyx_t_4);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_7)) {
      PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_6};
      __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 208, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) {
      PyObject *__pyx_temp[2] = {__pyx_t_3, __pyx_t_6};
      __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 208, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    } else
    #endif
    {
      __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 208, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __pyx_t_3 = NULL;
      __Pyx_GIVEREF(__pyx_t_6);
      PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_6);
      __pyx_t_6 = 0;
      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 208, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  __pyx_v_weight_multiplier = __pyx_t_4;
  __pyx_t_4 = 0;
+209:     return  calculate_for_target(metric, target, avg, recent, aim=0.25, div=div, slope=1.0, smoothing=smoothing, weight_multiplier=weight_multiplier)
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_calculate_for_target); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 209, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_7 = PyFloat_FromDouble(__pyx_v_target); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 209, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 209, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_INCREF(__pyx_v_metric);
  __Pyx_GIVEREF(__pyx_v_metric);
  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_metric);
  __Pyx_GIVEREF(__pyx_t_7);
  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_7);
  __Pyx_INCREF(__pyx_v_avg);
  __Pyx_GIVEREF(__pyx_v_avg);
  PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_avg);
  __Pyx_INCREF(__pyx_v_recent);
  __Pyx_GIVEREF(__pyx_v_recent);
  PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_v_recent);
  __pyx_t_7 = 0;
  __pyx_t_7 = __Pyx_PyDict_NewPresized(5); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 209, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_aim, __pyx_float_0_25) < 0) __PYX_ERR(0, 209, __pyx_L1_error)
  __pyx_t_6 = PyFloat_FromDouble(__pyx_v_div); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 209, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_div, __pyx_t_6) < 0) __PYX_ERR(0, 209, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_slope, __pyx_float_1_0) < 0) __PYX_ERR(0, 209, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_smoothing, __pyx_v_smoothing) < 0) __PYX_ERR(0, 209, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_weight_multiplier, __pyx_v_weight_multiplier) < 0) __PYX_ERR(0, 209, __pyx_L1_error)
  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 209, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  __pyx_r = __pyx_t_6;
  __pyx_t_6 = 0;
  goto __pyx_L0;