Merge branch 'main' of ssh://git.jaytux.com:35000/jay-tux/simd.jaytux.com
This commit is contained in:
@ -76,12 +76,14 @@ Gets a (paginated) list of all C/C++(-like) types used by the intrinsics. The ty
|
||||
Searches the database using the given filters. The filters are passed as query parameters, and can be combined. All filters are optional. The following filters are available:
|
||||
- `name=[string]`: searches based on the name of the intrinsic; employs fuzzy-search (using `LIKE %it%`)
|
||||
- `return=[string]`: searches based on the return type of the intrinsic; exact search only
|
||||
- `cpuid=[string]`: searches based on the CPUID of the intrinsic; exact search only
|
||||
- `tech=[string]`: searches based on the technology of the intrinsic; exact search only
|
||||
- `category=[string]`: searches based on the category of the intrinsic; exact search only
|
||||
- `cpuid=[*]`: searches based on the CPUID of the intrinsic; exact search only
|
||||
- `tech=[*]`: searches based on the technology of the intrinsic; exact search only
|
||||
- `category=[*]`: searches based on the category of the intrinsic; exact search only
|
||||
- `desc=[string]`: searches based on the description of the intrinsic; employs fuzzy-search (using `LIKE %it%`)
|
||||
- `page=[int]`: specifies the page number to return (default is 0)
|
||||
|
||||
Parameters marked by `[*]` are JSON-lists (so you should pass them as `cpuid=["PREFETCHI", "SSE2"]`). They are considered to be OR-ed together (i.e. the results will contain a mix of all intrinsics matching either of the CPUIDs (from the example)).
|
||||
|
||||
Passing no filters is equivalent to using `GET /all`, and data is returned in the same format:
|
||||
```json
|
||||
{
|
||||
@ -130,4 +132,14 @@ Gets the details for a single, specific intrinsic. The following data is returne
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### `GET /version`
|
||||
Gets version information for the data. The following data is returned:
|
||||
```json
|
||||
{
|
||||
"intelVersion": "M.m.p (Major.minor.patch version as reported by Intel)",
|
||||
"intelUpdate": "yyyy-MM-dd (date of Intel's last update prior to scraping)",
|
||||
"scrapeDate": "yyyy-MM-dd (date of last update)"
|
||||
}
|
||||
```
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.jaytux.simd.data
|
||||
|
||||
import com.fleeksoft.ksoup.Ksoup
|
||||
import com.fleeksoft.ksoup.parser.Parser
|
||||
import com.jaytux.simd.data.IntrinsicInstructions.xed
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.datetime.*
|
||||
@ -84,6 +85,7 @@ object Loader {
|
||||
|
||||
suspend fun loadXml(xmlFile: String): XmlData = coroutineScope {
|
||||
val xml = Ksoup.parseXml(File(xmlFile).readText(Charsets.UTF_8))
|
||||
Parser.xmlParser()
|
||||
|
||||
val cppTypes = mutableSetOf<String>()
|
||||
val techs = mutableSetOf<String>()
|
||||
@ -158,13 +160,13 @@ object Loader {
|
||||
args += argName to type
|
||||
}
|
||||
|
||||
val desc = it.getElementsByTag("description").firstOrNull()?.text()
|
||||
val desc = it.getElementsByTag("description").firstOrNull()?.wholeText()?.trim()
|
||||
if(desc == null) {
|
||||
errors += "Missing description element for intrinsic $name"
|
||||
return@forEachIndexed
|
||||
}
|
||||
|
||||
val op = it.getElementsByTag("operation").firstOrNull()?.text()
|
||||
val op = it.getElementsByTag("operation").firstOrNull()?.wholeText()?.trim()
|
||||
|
||||
val insn = mutableListOf<Triple<String, String, String?>>()
|
||||
it.getElementsByTag("instruction").forEachIndexed { i, ins ->
|
||||
|
@ -4,13 +4,17 @@ import com.jaytux.simd.data.*
|
||||
import com.jaytux.simd.server.RouteCache.register
|
||||
import io.ktor.http.*
|
||||
import io.ktor.http.content.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.jetbrains.exposed.dao.UUIDEntity
|
||||
import org.jetbrains.exposed.dao.id.EntityID
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import java.util.*
|
||||
|
||||
@ -60,32 +64,46 @@ fun Routing.installGetAll() {
|
||||
|
||||
fun Routing.installSearch() {
|
||||
getPagedRequest("/search", "Search for intrinsics matching certain filters", { 100 }, { IntrinsicSummary(it[Intrinsics.id].value, it[Intrinsics.mnemonic]) }) {
|
||||
fun <T : UUIDEntity> resolveAny(key: String, finder: (String) -> SizedIterable<T>): List<EntityID<UUID>>? {
|
||||
return call.request.queryParameters[key]?.let {
|
||||
try {
|
||||
val list = Json.decodeFromString<List<String>>(it)
|
||||
list.map {
|
||||
finder(it).firstOrNull()?.id
|
||||
?: throw HttpError("Unknown $key: ${list.joinToString(", ")}")
|
||||
}
|
||||
}
|
||||
catch(e: HttpError) {
|
||||
throw e
|
||||
}
|
||||
catch(e: Exception) {
|
||||
throw HttpError("Malformed $key parameter: $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val name = call.request.queryParameters["name"]
|
||||
val returnType = call.request.queryParameters["return"]?.let {
|
||||
CppType.find { CppTypes.name eq it }.firstOrNull()
|
||||
?: throw HttpError("Unknown return type: $it")
|
||||
}
|
||||
val cpuid = call.request.queryParameters["cpuid"]?.let {
|
||||
CPUID.find { CPUIDs.name eq it }.firstOrNull()
|
||||
?: throw HttpError("Unknown CPUID: $it")
|
||||
}
|
||||
val tech = call.request.queryParameters["tech"]?.let {
|
||||
Tech.find { Techs.name eq it }.firstOrNull()
|
||||
?: throw HttpError("Unknown tech: $it")
|
||||
}
|
||||
val category = call.request.queryParameters["category"]?.let {
|
||||
Category.find { Categories.name eq it }.firstOrNull()
|
||||
?: throw HttpError("Unknown category: $it")
|
||||
}
|
||||
val anyCpuid = resolveAny("cpuid") { CPUID.find { CPUIDs.name eq it } }
|
||||
val anyTech = resolveAny("tech") { Tech.find { Techs.name eq it } }
|
||||
val anyCat = resolveAny("category") { Category.find { Categories.name eq it } }
|
||||
val desc = call.request.queryParameters["desc"]
|
||||
|
||||
var results = Intrinsics.selectAll()
|
||||
name?.let { results = results.where { Intrinsics.mnemonic like "%$it%" } }
|
||||
returnType?.let { results = results.where { Intrinsics.returnType eq it.id } }
|
||||
cpuid?.let { results = results.where { Intrinsics.cpuid eq it.id } }
|
||||
tech?.let { results = results.where { Intrinsics.tech eq it.id } }
|
||||
category?.let { results = results.where { Intrinsics.category eq it.id } }
|
||||
desc?.let { results = results.where { Intrinsics.description like "%$it%" } }
|
||||
var results = Intrinsics.selectAll().where {
|
||||
val build = listOf(
|
||||
name?.let { Intrinsics.mnemonic like "%$it%" },
|
||||
returnType?.let { Intrinsics.returnType eq it.id },
|
||||
anyCpuid?.let { Intrinsics.cpuid inList it },
|
||||
anyTech?.let { Intrinsics.tech inList it },
|
||||
anyCat?.let { Intrinsics.category inList it },
|
||||
desc?.let { Intrinsics.description like "%$it%" }
|
||||
).filterNotNull()
|
||||
|
||||
build.fold(Op.TRUE as Op<Boolean>, { acc, op -> op and acc })
|
||||
}
|
||||
|
||||
results.orderAsc(Intrinsics.mnemonic)
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
<logger name="io.netty" level="warn" />
|
||||
<logger name="ch.qos.logback" level="warn" />
|
||||
|
||||
<root level="trace">
|
||||
<root level="warn">
|
||||
<appender-ref ref="APPENDER"/>
|
||||
</root>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
Reference in New Issue
Block a user