Skip to content

Commit

Permalink
Index attributes and order support in sql query
Browse files Browse the repository at this point in the history
  • Loading branch information
amankgo committed Jan 8, 2022
1 parent 86f84b7 commit bb1e642
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 145 deletions.
1 change: 1 addition & 0 deletions src/main/kotlin/models/LogItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ data class LogItem(
companion object {
private const val serialVersionUID = 1L
val EVENT_NAME = attribute("eventName", LogItem::eventName)
val ATTR_TIME = attribute("localTime", LogItem::localTime)

fun noContent(msg: String) = LogItem(SourceInternalContent, "No Logs", internalContent = NoLogsContent(msg))
fun errorContent(error: String) = LogItem(SourceInternalContent, "Error", internalContent = ErrorContent(error))
Expand Down
21 changes: 17 additions & 4 deletions src/main/kotlin/models/ParameterFormats.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
package models

sealed class ParameterFormats(val key: String, val text: String)
object FormatJsonPretty : ParameterFormats("jsonpretty", "Json with pretty print")
object FormatJsonCompact : ParameterFormats("json", "Compact Json")
object FormatYaml : ParameterFormats("yaml", "Yaml")
sealed class ParameterFormats(val key: String, val text: String, val subText: String)
object FormatJsonPretty :
ParameterFormats(
"jsonpretty", "Json with pretty print",
"Long string with multiple lines with json format"
)

object FormatJsonCompact :
ParameterFormats(
"json", "Compact Json",
"Small json string without any formatting in a single line"
)

object FormatYaml : ParameterFormats(
"yaml", "Yaml",
"Human friendly formatted string with indentation as formatting and multi-lines"
)

val DefaultFormats = listOf(FormatJsonPretty, FormatJsonCompact, FormatYaml)
24 changes: 24 additions & 0 deletions src/main/kotlin/models/SocialIcons.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package models

enum class SocialIcons(val icon: String, val url: String) {
Twitter(
"icons/social/social_twitter.svg",
"https://twitter.com/Aman22Kapoor"
),
Github(
"icons/social/social_github.svg",
"https://github.com/amank22/LogVue"
),
GithubIssues(
"icons/social/social_github.svg",
"https://github.com/amank22/LogVue/issues/new"
),
Linkedin("icons/social/social_linkedIn.svg", "https://www.linkedin.com/in/amank22/"),
Email("icons/ico-email.svg", "mailto://[email protected]"),
;

companion object {
val DefaultIcons = listOf(Twitter, Github, Linkedin, Email)
}
//object SocialFacebook : SocialIcons("icons/social/social_facebook.svg", "")
}
5 changes: 3 additions & 2 deletions src/main/kotlin/processor/MainProcessor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import utils.Helpers
import utils.failureOrNull
import utils.getOrNull


class MainProcessor {

private val streamer = AndroidLogStreamer()
Expand Down Expand Up @@ -118,8 +119,8 @@ class MainProcessor {
logItemStream.collect { list ->

val filterResult = if (fQuery.isNullOrBlank() || fQuery == QUERY_PREFIX) {
registerPropertiesInParser(list, parser)
list
registerPropertiesInParser(list, parser, indexedCollection)
list.sortedBy { it.localTime }
} else {
if (!isNewStream) {
indexedCollection.clear()
Expand Down
8 changes: 6 additions & 2 deletions src/main/kotlin/processor/ParameterizedAttribute.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ class ParameterizedAttribute<T>(private val mapKey: String, private val clazz: C
override fun getValue(logItem: LogItem, queryOptions: QueryOptions?): T? {
val result = getNestedValue(logItem)
if (result == null || attributeType.isAssignableFrom(clazz)) {
return clazz.cast(result)
try {
return clazz.cast(result)
} catch (cl: ClassCastException) {
//ignore
}
}
throw ClassCastException("Cannot cast " + result.javaClass.name + " to " + attributeType.name + " for map key: " + mapKey)
throw ClassCastException("Cannot cast " + result?.javaClass?.name + " to " + attributeType.name + " for map key: " + mapKey)
}

private fun getNestedValue(logItem: LogItem): Any? {
Expand Down
85 changes: 70 additions & 15 deletions src/main/kotlin/processor/QueryHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.googlecode.cqengine.ConcurrentIndexedCollection
import com.googlecode.cqengine.ObjectLockingIndexedCollection
import com.googlecode.cqengine.attribute.support.FunctionalSimpleAttribute
import com.googlecode.cqengine.index.hash.HashIndex
import com.googlecode.cqengine.index.navigable.NavigableIndex
import com.googlecode.cqengine.index.radix.RadixTreeIndex
import com.googlecode.cqengine.index.radixinverted.InvertedRadixTreeIndex
import com.googlecode.cqengine.index.radixreversed.ReversedRadixTreeIndex
Expand All @@ -26,12 +27,15 @@ fun queryCollection(): ConcurrentIndexedCollection<LogItem> {
addIndex(RadixTreeIndex.onAttribute(LogItem.EVENT_NAME))
addIndex(InvertedRadixTreeIndex.onAttribute(LogItem.EVENT_NAME))
addIndex(ReversedRadixTreeIndex.onAttribute(LogItem.EVENT_NAME))
addIndex(HashIndex.onAttribute(LogItem.ATTR_TIME))
addIndex(NavigableIndex.onAttribute(LogItem.ATTR_TIME))
}
}

fun sqlParser(): SQLParser<LogItem> {
return SQLParser.forPojo(LogItem::class.java).apply {
registerAttribute(LogItem.EVENT_NAME)
registerAttribute(LogItem.ATTR_TIME)
}
}

Expand All @@ -43,54 +47,105 @@ fun filterLogs(
filterQuery: String?
): List<LogItem> {
indexedCollection.addAll(list)
registerPropertiesInParser(list, parser)
registerPropertiesInParser(list, parser, indexedCollection)
println("Filtering logs")
val filterResult = measureTimedValue {
parser.retrieve(indexedCollection, filterQuery)
}
if (filterResult.duration.inWholeSeconds > 2) {
AppLog.d(
"filtering", "Time taken: ${filterResult.duration} , " +
"Retrieval Cost: ${filterResult.value.retrievalCost}"
"filtering",
"Time taken: ${filterResult.duration} , " + "Retrieval Cost: ${filterResult.value.retrievalCost}"
)
}
val toList = filterResult.value.toList()
AppLog.d("filterResult", filterResult.value.toList().toString())
return toList.sortedBy { it.localTime }
return filterResult.value.toList()
}

fun registerPropertiesInParser(
list: List<LogItem>,
parser: SQLParser<LogItem>
list: List<LogItem>, parser: SQLParser<LogItem>, indexedCollection: ConcurrentIndexedCollection<LogItem>
) {
val propertySet = hashSetOf<String>()
list.forEach {
registerMapPropertiesInParser(it.properties, propertySet, parser)
registerMapPropertiesInParser(it.properties, propertySet, parser, indexedCollection)
}
}

private fun registerMapPropertiesInParser(
properties: Map<String, Any>,
propertySet: HashSet<String>,
parser: SQLParser<LogItem>,
indexedCollection: ConcurrentIndexedCollection<LogItem>,
parentKey: String = ""
) {
properties.forEach { (k, v) ->
if (!propertySet.contains(k)) {
val att: ParameterizedAttribute<Any> = ParameterizedAttribute("$parentKey$k", v.javaClass)
if (v is Map<*, *>) {
@Suppress("UNCHECKED_CAST")
registerMapPropertiesInParser(
v as Map<String, Any>, propertySet,
parser, "$parentKey$k."
@Suppress("UNCHECKED_CAST") registerMapPropertiesInParser(
v as Map<String, Any>, propertySet, parser, indexedCollection, "$parentKey$k."
)
} else {
// println("Attribute : ${att.attributeName} with first value = $v and v class = ${v.javaClass.name}")
parser.registerAttribute(att)
val key = "$parentKey$k"
registerAndAddIndex(v, key, parser, indexedCollection)
propertySet.add(k)
}
} else {
// println("Duplicate Attribute : $k = $v")
}
}
}

fun registerAndAddIndex(
value: Any, key: String,
parser: SQLParser<LogItem>,
indexedCollection: ConcurrentIndexedCollection<LogItem>
) {
with(indexedCollection) {
if (key.isBlank()) {
addGenericAttribute(key, value, parser)
}
when (value) {
is String -> {
if (value.isBlank()) {
addGenericAttribute(key, value, parser)
return
}
val att: ParameterizedAttribute<String> = ParameterizedAttribute(key, value.javaClass)
try {
addIndex(HashIndex.onAttribute(att))
addIndex(NavigableIndex.onAttribute(att))
addIndex(RadixTreeIndex.onAttribute(att))
addIndex(InvertedRadixTreeIndex.onAttribute(att))
addIndex(ReversedRadixTreeIndex.onAttribute(att))
parser.registerAttribute(att)
} catch (e: Exception) {
// TODO: Make sure to log these exceptions somewhere so that we can analyse them
addGenericAttribute(key, value, parser)
}
}
is Comparable<*> -> {
try {
val att: ParameterizedAttribute<Comparable<*>> = ParameterizedAttribute(key, value.javaClass)
addIndex(HashIndex.onAttribute(att))
addIndex(NavigableIndex.onAttribute(att))
parser.registerAttribute(att)
} catch (e: Exception) {
addGenericAttribute(key, value, parser)
}
}
else -> {
addGenericAttribute(key, value, parser)
}
}
}
}

private fun ConcurrentIndexedCollection<LogItem>.addGenericAttribute(
key: String,
value: Any,
parser: SQLParser<LogItem>
) {
val att: ParameterizedAttribute<Any> = ParameterizedAttribute(key, value.javaClass)
addIndex(HashIndex.onAttribute(att))
parser.registerAttribute(att)
}
46 changes: 39 additions & 7 deletions src/main/kotlin/ui/components/BasicComponents.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package ui.components

import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.Icon
import androidx.compose.material.RadioButton
import androidx.compose.material.Switch
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.text.AnnotatedString
Expand Down Expand Up @@ -69,10 +73,7 @@ fun SwitchItem(

@Composable
fun SimpleListItem(
title: String?,
modifier: Modifier = Modifier,
subTitle: String? = null,
icon: Painter? = null
title: String?, modifier: Modifier = Modifier, subTitle: String? = null, icon: Painter? = null
) {
Row(modifier, horizontalArrangement = Arrangement.spacedBy(16.dp)) {
if (icon != null) {
Expand Down Expand Up @@ -108,8 +109,7 @@ fun SimpleListItem(
Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(6.dp)) {
if (title != null) {
Text(
title.text, style = CustomTheme.typography.headings.h6Medium,
lineHeight = 19.sp
title.text, style = CustomTheme.typography.headings.h6Medium, lineHeight = 19.sp
)
}
if (subTitle != null) {
Expand Down Expand Up @@ -142,8 +142,40 @@ fun ClickableListItem(
}
if (subTitle != null) {
ClickableText(
subTitle, style = CustomTheme.typography.headings.semiText, onClick = onClick
)
}
}
}
}

@Composable
fun MultiLineRadioButton(
selected: Boolean,
title: String?,
modifier: Modifier = Modifier,
subTitle: String? = null,
spacing: Dp = 8.dp,
onClick: () -> Unit
) {
Row(
modifier.clickable(MutableInteractionSource(), null, onClick = { onClick() }),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(spacing)
) {
RadioButton(selected, onClick)
Column(Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(6.dp)) {
if (title != null) {
Text(
title, style = CustomTheme.typography.headings.h6Medium, lineHeight = 19.sp
)
}
if (subTitle != null) {
Text(
subTitle,
style = CustomTheme.typography.headings.semiText, onClick = onClick
style = CustomTheme.typography.headings.caption,
color = CustomTheme.colors.mediumContrast,
lineHeight = 19.sp
)
}
}
Expand Down
Loading

0 comments on commit bb1e642

Please sign in to comment.