Better sort implementation

This commit is contained in:
J-Jamet
2019-08-17 15:15:21 +02:00
parent 173dd5b59b
commit 3d53c31680

View File

@@ -20,11 +20,9 @@
package com.kunzisoft.keepass.database package com.kunzisoft.keepass.database
import com.kunzisoft.keepass.database.element.EntryVersioned
import com.kunzisoft.keepass.database.element.GroupVersioned
import com.kunzisoft.keepass.database.element.NodeVersioned import com.kunzisoft.keepass.database.element.NodeVersioned
import com.kunzisoft.keepass.database.element.Type
import java.util.Comparator import java.util.*
enum class SortNodeEnum { enum class SortNodeEnum {
DB, TITLE, USERNAME, CREATION_TIME, LAST_MODIFY_TIME, LAST_ACCESS_TIME; DB, TITLE, USERNAME, CREATION_TIME, LAST_MODIFY_TIME, LAST_ACCESS_TIME;
@@ -40,21 +38,26 @@ enum class SortNodeEnum {
} }
} }
abstract class NodeComparator(internal var ascending: Boolean, private var groupsBefore: Boolean) : Comparator<NodeVersioned> { abstract class NodeComparator(var ascending: Boolean, var groupsBefore: Boolean) : Comparator<NodeVersioned> {
internal fun compareWith(comparatorGroup: Comparator<GroupVersioned>, abstract fun compareBySpecificOrder(object1: NodeVersioned, object2: NodeVersioned): Int
comparatorEntry: Comparator<EntryVersioned>,
object1: NodeVersioned, private fun specificOrderOrHashIfEquals(object1: NodeVersioned, object2: NodeVersioned): Int {
object2: NodeVersioned, val specificOrderComp = compareBySpecificOrder(object1, object2)
resultOfNodeMethodCompare: Int): Int {
return if (specificOrderComp == 0) {
object1.hashCode() - object2.hashCode()
} else if (!ascending) -specificOrderComp else specificOrderComp // If descending, revert
}
override fun compare(object1: NodeVersioned,object2: NodeVersioned): Int {
if (object1 == object2) if (object1 == object2)
return 0 return 0
if (object1 is GroupVersioned) { if (object1.type == Type.GROUP) {
return if (object2 is GroupVersioned) { return if (object2.type == Type.GROUP) {
comparatorGroup specificOrderOrHashIfEquals(object1, object2)
.compare(object1, object2) } else if (object2.type == Type.ENTRY) {
} else if (object2 is EntryVersioned) {
if (groupsBefore) if (groupsBefore)
-1 -1
else else
@@ -62,11 +65,10 @@ enum class SortNodeEnum {
} else { } else {
-1 -1
} }
} else if (object1 is EntryVersioned) { } else if (object1.type == Type.ENTRY) {
return if (object2 is EntryVersioned) { return if (object2.type == Type.ENTRY) {
comparatorEntry specificOrderOrHashIfEquals(object1, object2)
.compare(object1, object2) } else if (object2.type == Type.GROUP) {
} else if (object2 is GroupVersioned) {
if (groupsBefore) if (groupsBefore)
1 1
else else
@@ -76,8 +78,8 @@ enum class SortNodeEnum {
} }
} }
// If same name, can be different // Type not known
return if (resultOfNodeMethodCompare == 0) object1.hashCode() - object2.hashCode() else resultOfNodeMethodCompare return -1
} }
} }
@@ -86,15 +88,8 @@ enum class SortNodeEnum {
*/ */
class NodeNaturalComparator(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) { class NodeNaturalComparator(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) {
override fun compare(object1: NodeVersioned, object2: NodeVersioned): Int { override fun compareBySpecificOrder(object1: NodeVersioned, object2: NodeVersioned): Int {
return object1.nodePositionInParent.compareTo(object2.nodePositionInParent)
return compareWith(
GroupNaturalOrderComparator(ascending),
EntryNaturalOrderComparator(ascending),
object1,
object2,
object1.creationTime.date
?.compareTo(object2.creationTime.date) ?: 0)
} }
} }
@@ -103,15 +98,8 @@ enum class SortNodeEnum {
*/ */
class NodeTitleComparator(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) { class NodeTitleComparator(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) {
override fun compare(object1: NodeVersioned, object2: NodeVersioned): Int { override fun compareBySpecificOrder(object1: NodeVersioned, object2: NodeVersioned): Int {
return object1.title.compareTo(object2.title, ignoreCase = true)
return compareWith(
GroupNameComparator(ascending),
EntryNameComparator(ascending),
object1,
object2,
object1.title
.compareTo(object2.title, ignoreCase = true))
} }
} }
@@ -120,15 +108,9 @@ enum class SortNodeEnum {
*/ */
class NodeCreationComparator(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) { class NodeCreationComparator(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) {
override fun compare(object1: NodeVersioned, object2: NodeVersioned): Int { override fun compareBySpecificOrder(object1: NodeVersioned, object2: NodeVersioned): Int {
return object1.creationTime.date
return compareWith( ?.compareTo(object2.creationTime.date) ?: 0
GroupCreationComparator(ascending),
EntryCreationComparator(ascending),
object1,
object2,
object1.creationTime.date
?.compareTo(object2.creationTime.date) ?: 0)
} }
} }
@@ -137,15 +119,9 @@ enum class SortNodeEnum {
*/ */
class NodeLastModificationComparator(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) { class NodeLastModificationComparator(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) {
override fun compare(object1: NodeVersioned, object2: NodeVersioned): Int { override fun compareBySpecificOrder(object1: NodeVersioned, object2: NodeVersioned): Int {
return object1.lastModificationTime.date
return compareWith( ?.compareTo(object2.lastModificationTime.date) ?: 0
GroupLastModificationComparator(ascending),
EntryLastModificationComparator(ascending),
object1,
object2,
object1.lastModificationTime.date
?.compareTo(object2.lastModificationTime.date) ?: 0)
} }
} }
@@ -154,129 +130,7 @@ enum class SortNodeEnum {
*/ */
class NodeLastAccessComparator(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) { class NodeLastAccessComparator(ascending: Boolean, groupsBefore: Boolean) : NodeComparator(ascending, groupsBefore) {
override fun compare(object1: NodeVersioned, object2: NodeVersioned): Int { override fun compareBySpecificOrder(object1: NodeVersioned, object2: NodeVersioned): Int {
return compareWith(
GroupLastAccessComparator(ascending),
EntryLastAccessComparator(ascending),
object1,
object2,
object1.lastAccessTime.date
?.compareTo(object2.lastAccessTime.date) ?: 0)
}
}
abstract class AscendingComparator<Node>(private val ascending: Boolean) : Comparator<Node> {
private fun compareWithAscending(specificOrderComp: Int): Int {
// If descending, revert
return if (!ascending) -specificOrderComp else specificOrderComp
}
abstract fun compareBySecificOrder(object1: Node, object2: Node): Int
override fun compare(object1: Node, object2: Node): Int {
if (object1 == object2)
return 0
val specificOrderComp = compareBySecificOrder(object1, object2)
return if (specificOrderComp == 0) {
object1.hashCode() - object2.hashCode()
} else compareWithAscending(specificOrderComp)
}
}
/**
* Group comparator by natural order
*/
class GroupNaturalOrderComparator(ascending: Boolean) : AscendingComparator<GroupVersioned>(ascending) {
override fun compareBySecificOrder(object1: GroupVersioned, object2: GroupVersioned): Int {
return object1.nodePositionInParent.compareTo(object2.nodePositionInParent)
}
}
/**
* Group comparator by name
*/
class GroupNameComparator(ascending: Boolean) : AscendingComparator<GroupVersioned>(ascending) {
override fun compareBySecificOrder(object1: GroupVersioned, object2: GroupVersioned): Int {
return object1.title.compareTo(object2.title, ignoreCase = true)
}
}
/**
* Group comparator by name
*/
class GroupCreationComparator(ascending: Boolean) : AscendingComparator<GroupVersioned>(ascending) {
override fun compareBySecificOrder(object1: GroupVersioned, object2: GroupVersioned): Int {
return object1.creationTime.date
?.compareTo(object2.creationTime.date) ?: 0
}
}
/**
* Group comparator by last modification
*/
class GroupLastModificationComparator(ascending: Boolean) : AscendingComparator<GroupVersioned>(ascending) {
override fun compareBySecificOrder(object1: GroupVersioned, object2: GroupVersioned): Int {
return object1.lastModificationTime.date
?.compareTo(object2.lastModificationTime.date) ?: 0
}
}
/**
* Group comparator by last access
*/
class GroupLastAccessComparator(ascending: Boolean) : AscendingComparator<GroupVersioned>(ascending) {
override fun compareBySecificOrder(object1: GroupVersioned, object2: GroupVersioned): Int {
return object1.lastAccessTime.date
?.compareTo(object2.lastAccessTime.date) ?: 0
}
}
/**
* Comparator of Entry by Name
*/
class EntryNaturalOrderComparator(ascending: Boolean) : AscendingComparator<EntryVersioned>(ascending) {
override fun compareBySecificOrder(object1: EntryVersioned, object2: EntryVersioned): Int {
return object1.nodePositionInParent.compareTo(object2.nodePositionInParent)
}
}
/**
* Comparator of Entry by Name
*/
class EntryNameComparator(ascending: Boolean) : AscendingComparator<EntryVersioned>(ascending) {
override fun compareBySecificOrder(object1: EntryVersioned, object2: EntryVersioned): Int {
return object1.title.compareTo(object2.title, ignoreCase = true)
}
}
/**
* Comparator of Entry by Creation
*/
class EntryCreationComparator(ascending: Boolean) : AscendingComparator<EntryVersioned>(ascending) {
override fun compareBySecificOrder(object1: EntryVersioned, object2: EntryVersioned): Int {
return object1.creationTime.date
?.compareTo(object2.creationTime.date) ?: 0
}
}
/**
* Comparator of Entry by Last Modification
*/
class EntryLastModificationComparator(ascending: Boolean) : AscendingComparator<EntryVersioned>(ascending) {
override fun compareBySecificOrder(object1: EntryVersioned, object2: EntryVersioned): Int {
return object1.lastModificationTime.date
?.compareTo(object2.lastModificationTime.date) ?: 0
}
}
/**
* Comparator of Entry by Last Access
*/
class EntryLastAccessComparator(ascending: Boolean) : AscendingComparator<EntryVersioned>(ascending) {
override fun compareBySecificOrder(object1: EntryVersioned, object2: EntryVersioned): Int {
return object1.lastAccessTime.date return object1.lastAccessTime.date
?.compareTo(object2.lastAccessTime.date) ?: 0 ?.compareTo(object2.lastAccessTime.date) ?: 0
} }