// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.

//go:build (freebsd && amd64) || (linux && amd64) || (linux && arm64) || (linux && loong64) || (linux && ppc64le) || (linux && riscv64) || (linux && s390x) || (netbsd && amd64) || (openbsd && amd64) || (openbsd && arm64)

package sqlite3

import (
	"unsafe"

	"modernc.org/libc"
)

// C documentation
//
//	/*
//	** Implementation of bm25() function.
//	*/
func _fts5Bm25Function(tls *libc.TLS, pApi uintptr, pFts uintptr, pCtx uintptr, nVal int32, apVal uintptr) {
	bp := tls.Alloc(32)
	defer tls.Free(32)
	var D, b, k1, score, w, v2 float64
	var aFreq uintptr
	var i, rc int32
	var _ /* ic at bp+16 */ int32
	var _ /* io at bp+20 */ int32
	var _ /* ip at bp+12 */ int32
	var _ /* nInst at bp+8 */ int32
	var _ /* nTok at bp+24 */ int32
	var _ /* pData at bp+0 */ uintptr
	_, _, _, _, _, _, _, _, _ = D, aFreq, b, i, k1, rc, score, w, v2
	k1 = float64(1.2)                  /* Constant "k1" from BM25 formula */
	b = float64(0.75)                  /* Error code */
	score = float64(0)                 /* Iterator variable */
	**(**int32)(__ccgo_up(bp + 8)) = 0 /* Value returned by xInstCount() */
	D = float64(0)                     /* Total number of tokens in row */
	aFreq = uintptr(0)                 /* Array of phrase freq. for current row */
	/* Calculate the phrase frequency (symbol "f(qi,D)" in the documentation)
	 ** for each phrase in the query for the current row. */
	rc = _fts5Bm25GetData(tls, pApi, pFts, bp)
	if rc == SQLITE_OK {
		aFreq = (*TFts5Bm25Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaFreq
		libc.Xmemset(tls, aFreq, 0, uint64(8)*libc.Uint64FromInt32((*TFts5Bm25Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnPhrase))
		rc = (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxInstCount})))(tls, pFts, bp+8)
	}
	i = 0
	for {
		if !(rc == SQLITE_OK && i < **(**int32)(__ccgo_up(bp + 8))) {
			break
		}
		rc = (*(*func(*libc.TLS, uintptr, int32, uintptr, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxInst})))(tls, pFts, i, bp+12, bp+16, bp+20)
		if rc == SQLITE_OK {
			if nVal > **(**int32)(__ccgo_up(bp + 16)) {
				v2 = Xsqlite3_value_double(tls, **(**uintptr)(__ccgo_up(apVal + uintptr(**(**int32)(__ccgo_up(bp + 16)))*8)))
			} else {
				v2 = float64(1)
			}
			w = v2
			**(**float64)(__ccgo_up(aFreq + uintptr(**(**int32)(__ccgo_up(bp + 12)))*8)) += w
		}
		goto _1
	_1:
		;
		i = i + 1
	}
	/* Figure out the total size of the current row in tokens. */
	if rc == SQLITE_OK {
		rc = (*(*func(*libc.TLS, uintptr, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{(*TFts5ExtensionApi)(unsafe.Pointer(pApi)).FxColumnSize})))(tls, pFts, -int32(1), bp+24)
		D = float64(**(**int32)(__ccgo_up(bp + 24)))
	}
	/* Determine and return the BM25 score for the current row. Or, if an
	 ** error has occurred, throw an exception. */
	if rc == SQLITE_OK {
		i = 0
		for {
			if !(i < (*TFts5Bm25Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FnPhrase) {
				break
			}
			score = score + float64(**(**float64)(__ccgo_up((*TFts5Bm25Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).FaIDF + uintptr(i)*8))*(float64(**(**float64)(__ccgo_up(aFreq + uintptr(i)*8))*(k1+libc.Float64FromFloat64(1)))/(**(**float64)(__ccgo_up(aFreq + uintptr(i)*8))+float64(k1*(libc.Float64FromInt32(1)-b+float64(b*D)/(*TFts5Bm25Data)(unsafe.Pointer(**(**uintptr)(__ccgo_up(bp)))).Favgdl)))))
			goto _3
		_3:
			;
			i = i + 1
		}
		Xsqlite3_result_double(tls, pCtx, float64(-libc.Float64FromFloat64(1)*score))
	} else {
		Xsqlite3_result_error_code(tls, pCtx, rc)
	}
}

// C documentation
//
//	/*
//	** Determine the overlap between two polygons
//	*/
func _geopolyOverlap(tls *libc.TLS, p1 uintptr, p2 uintptr) (r int32) {
	bp := tls.Alloc(16)
	defer tls.Free(16)
	var iMask, needSort, rc, v1 int32
	var nByte, nVertex Tsqlite3_int64
	var p, pActive, pPrev, pSeg, pThisEvent, v5 uintptr
	var rX, y, v2 float64
	var _ /* aOverlap at bp+0 */ [4]uint8
	_, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = iMask, nByte, nVertex, needSort, p, pActive, pPrev, pSeg, pThisEvent, rX, rc, y, v1, v2, v5
	nVertex = int64((*TGeoPoly)(unsafe.Pointer(p1)).FnVertex + (*TGeoPoly)(unsafe.Pointer(p2)).FnVertex + int32(2))
	rc = 0
	needSort = 0
	pActive = uintptr(0)
	nByte = libc.Int64FromUint64(uint64(32)*libc.Uint64FromInt64(nVertex)*uint64(2) + uint64(48)*libc.Uint64FromInt64(nVertex) + uint64(24))
	p = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nByte))
	if p == uintptr(0) {
		return -int32(1)
	}
	(*TGeoOverlap)(unsafe.Pointer(p)).FaEvent = p + 1*24
	(*TGeoOverlap)(unsafe.Pointer(p)).FaSegment = (*TGeoOverlap)(unsafe.Pointer(p)).FaEvent + uintptr(nVertex*int64(2))*32
	v1 = libc.Int32FromInt32(0)
	(*TGeoOverlap)(unsafe.Pointer(p)).FnSegment = v1
	(*TGeoOverlap)(unsafe.Pointer(p)).FnEvent = v1
	_geopolyAddSegments(tls, p, p1, uint8(1))
	_geopolyAddSegments(tls, p, p2, uint8(2))
	pThisEvent = _geopolySortEventsByX(tls, (*TGeoOverlap)(unsafe.Pointer(p)).FaEvent, (*TGeoOverlap)(unsafe.Pointer(p)).FnEvent)
	if pThisEvent != 0 && (*TGeoEvent)(unsafe.Pointer(pThisEvent)).Fx == float64(0) {
		v2 = -libc.Float64FromFloat64(1)
	} else {
		v2 = float64(0)
	}
	rX = v2
	libc.Xmemset(tls, bp, 0, uint64(4))
	for pThisEvent != 0 {
		if (*TGeoEvent)(unsafe.Pointer(pThisEvent)).Fx != rX {
			pPrev = uintptr(0)
			iMask = 0
			rX = (*TGeoEvent)(unsafe.Pointer(pThisEvent)).Fx
			if needSort != 0 {
				pActive = _geopolySortSegmentsByYAndC(tls, pActive)
				needSort = 0
			}
			pSeg = pActive
			for {
				if !(pSeg != 0) {
					break
				}
				if pPrev != 0 {
					if (*TGeoSegment)(unsafe.Pointer(pPrev)).Fy != (*TGeoSegment)(unsafe.Pointer(pSeg)).Fy {
						(**(**[4]uint8)(__ccgo_up(bp)))[iMask] = uint8(1)
					}
				}
				iMask = iMask ^ libc.Int32FromUint8((*TGeoSegment)(unsafe.Pointer(pSeg)).Fside)
				pPrev = pSeg
				goto _3
			_3:
				;
				pSeg = (*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext
			}
			pPrev = uintptr(0)
			pSeg = pActive
			for {
				if !(pSeg != 0) {
					break
				}
				y = float64((*TGeoSegment)(unsafe.Pointer(pSeg)).FC*rX) + (*TGeoSegment)(unsafe.Pointer(pSeg)).FB
				(*TGeoSegment)(unsafe.Pointer(pSeg)).Fy = y
				if pPrev != 0 {
					if (*TGeoSegment)(unsafe.Pointer(pPrev)).Fy > (*TGeoSegment)(unsafe.Pointer(pSeg)).Fy && libc.Int32FromUint8((*TGeoSegment)(unsafe.Pointer(pPrev)).Fside) != libc.Int32FromUint8((*TGeoSegment)(unsafe.Pointer(pSeg)).Fside) {
						rc = int32(1)
						goto geopolyOverlapDone
					} else {
						if (*TGeoSegment)(unsafe.Pointer(pPrev)).Fy != (*TGeoSegment)(unsafe.Pointer(pSeg)).Fy {
							(**(**[4]uint8)(__ccgo_up(bp)))[iMask] = uint8(1)
						}
					}
				}
				iMask = iMask ^ libc.Int32FromUint8((*TGeoSegment)(unsafe.Pointer(pSeg)).Fside)
				pPrev = pSeg
				goto _4
			_4:
				;
				pSeg = (*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext
			}
		}
		if (*TGeoEvent)(unsafe.Pointer(pThisEvent)).FeType == 0 {
			/* Add a segment */
			pSeg = (*TGeoEvent)(unsafe.Pointer(pThisEvent)).FpSeg
			(*TGeoSegment)(unsafe.Pointer(pSeg)).Fy = float64((*TGeoSegment)(unsafe.Pointer(pSeg)).Fy0)
			(*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext = pActive
			pActive = pSeg
			needSort = int32(1)
		} else {
			/* Remove a segment */
			if pActive == (*TGeoEvent)(unsafe.Pointer(pThisEvent)).FpSeg {
				if pActive != 0 {
					v5 = (*TGeoSegment)(unsafe.Pointer(pActive)).FpNext
				} else {
					v5 = uintptr(0)
				}
				pActive = v5
			} else {
				pSeg = pActive
				for {
					if !(pSeg != 0) {
						break
					}
					if (*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext == (*TGeoEvent)(unsafe.Pointer(pThisEvent)).FpSeg {
						if (*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext != 0 {
							v5 = (*TGeoSegment)(unsafe.Pointer((*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext)).FpNext
						} else {
							v5 = uintptr(0)
						}
						(*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext = v5
						break
					}
					goto _6
				_6:
					;
					pSeg = (*TGeoSegment)(unsafe.Pointer(pSeg)).FpNext
				}
			}
		}
		pThisEvent = (*TGeoEvent)(unsafe.Pointer(pThisEvent)).FpNext
	}
	if libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(3)]) == 0 {
		rc = 0
	} else {
		if libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(1)]) != 0 && libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(2)]) == 0 {
			rc = int32(3)
		} else {
			if libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(1)]) == 0 && libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(2)]) != 0 {
				rc = int32(2)
			} else {
				if libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(1)]) == 0 && libc.Int32FromUint8((**(**[4]uint8)(__ccgo_up(bp)))[int32(2)]) == 0 {
					rc = int32(4)
				} else {
					rc = int32(1)
				}
			}
		}
	}
	goto geopolyOverlapDone
geopolyOverlapDone:
	;
	Xsqlite3_free(tls, p)
	return rc
}
