static void Stat3Init_(FuncContext fctx, int argc, Mem[][] argv) { tRowcnt rows = (tRowcnt)Vdbe.Value_Int64(argv[0]); int maxSamples = Vdbe.Value_Int(argv[1]); int n = maxSamples; Stat3Accum p = new Stat3Accum { a = new array_t <Stat3Accum.Stat3Sample>(new Stat3Accum.Stat3Sample[n]), Rows = rows, MaxSamples = maxSamples, PSamples = (uint)(rows / (maxSamples / 3 + 1) + 1), }; if (p == null) { Vdbe.Result_ErrorNoMem(fctx); return; } SysEx.Randomness(-1, p.Prn); Vdbe.Result_Blob(fctx, p, -1, C._free); }
static void Stat3Push_(FuncContext fctx, int argc, Mem[] argv) { tRowcnt eq = (tRowcnt)Vdbe.Value_Int64(argv[0]); if (eq == 0) { return; } tRowcnt lt = (tRowcnt)Vdbe.Value_Int64(argv[1]); tRowcnt dLt = (tRowcnt)Vdbe.Value_Int64(argv[2]); long rowid = Vdbe.Value_Int64(argv[3]); Stat3Accum p = (Stat3Accum)Vdbe.Value_Blob(argv[4]); bool isPSample = false; bool doInsert = false; int min = p.Min; uint h = p.Prn = p.Prn * 1103515245 + 12345; if ((lt / p.PSamples) != ((eq + lt) / p.PSamples)) { doInsert = isPSample = true; } else if (p.a.length < p.MaxSamples) { doInsert = true; } else if (eq > p.a[min].Eq || (eq == p.a[min].Eq && h > p.a[min].Hash)) { doInsert = true; } if (!doInsert) { return; } Stat3Accum.Stat3Sample sample; if (p.a.length == p.MaxSamples) { Debug.Assert(p.a.length - min - 1 >= 0); C._memmove(p.a[min], p.a[min + 1], sizeof(p.a[0]) * (p.a.length - min - 1)); sample = p.a[p.a.length - 1]; } else { sample = p.a[p.a.length++]; } sample.Rowid = rowid; sample.Eq = eq; sample.Lt = lt; sample.DLt = dLt; sample.Hash = h; sample.IsPSample = isPSample; // Find the new minimum if (p.a.length == p.MaxSamples) { int sampleIdx = 0; sample = p.a[sampleIdx]; int i = 0; while (sample.IsPSample) { i++; sampleIdx++; sample = p.a[sampleIdx]; Debug.Assert(i < p.a.length); } eq = sample.Eq; h = sample.Hash; min = i; for (i++, sampleIdx++; i < p.a.length; i++, sampleIdx++) { sample = p.a[sampleIdx]; if (sample.IsPSample) { continue; } if (sample.Eq < eq || (sample.Eq == eq && sample.Hash < h)) { min = i; eq = sample.Eq; h = sample.Hash; } } p.Min = min; } }