more work in progress

threading
Laurent 3 years ago
parent dc90960bcb
commit c08396b638
  1. 12
      app/build.gradle
  2. 3
      app/src/androidTest/java/net/pokeranalytics/android/components/RealmInstrumentedUnitTest.kt
  3. 6
      app/src/androidTest/java/net/pokeranalytics/android/model/CriteriaTest.kt
  4. 5
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt
  5. 20
      app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatsInstrumentedUnitTest.kt
  6. 18
      app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt
  7. 6
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  8. 6
      app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt
  9. 10
      app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollCalculator.kt
  10. 4
      app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt
  11. 10
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  12. 118
      app/src/main/java/net/pokeranalytics/android/model/utils/TimeManager.kt
  13. 5
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
  14. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt
  15. 4
      app/src/main/java/net/pokeranalytics/android/ui/modules/feed/FeedFragment.kt
  16. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/feed/FeedSessionRowRepresentableAdapter.kt
  17. 2
      app/src/main/res/values/strings.xml

@ -145,15 +145,15 @@ dependencies {
implementation 'com.android.volley:volley:1.2.1' implementation 'com.android.volley:volley:1.2.1'
// Instrumented Tests // Instrumented Tests
androidTestImplementation 'androidx.test:core:1.3.0' androidTestImplementation 'androidx.test:core:1.5.0'
androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test:rules:1.3.0' androidTestImplementation 'androidx.test:rules:1.5.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
// Test // Test
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
testImplementation 'com.android.support.test:runner:1.0.2' testImplementation 'androidx.test.ext:junit:1.1.5'
testImplementation 'com.android.support.test:rules:1.0.2' testImplementation 'androidx.test:rules:1.5.0'
// gross, somehow needed to make the stop notif work // gross, somehow needed to make the stop notif work
implementation 'com.google.guava:guava:27.0.1-android' implementation 'com.google.guava:guava:27.0.1-android'

@ -20,8 +20,9 @@ open class RealmInstrumentedUnitTest {
fun newSessionInstance(realm: Realm, isCashGame: Boolean = true) : Session { fun newSessionInstance(realm: Realm, isCashGame: Boolean = true) : Session {
val session = realm.createObject(Session::class.java, UUID.randomUUID().toString()) val session = realm.createObject(Session::class.java, UUID.randomUUID().toString())
session.startDate = Date() session.startDate = Date()
session.endDate = Date()
session.type = if (isCashGame) Session.Type.CASH_GAME.ordinal else Session.Type.TOURNAMENT.ordinal session.type = if (isCashGame) Session.Type.CASH_GAME.ordinal else Session.Type.TOURNAMENT.ordinal
session.result = realm.createObject(Result::class.java) session.result = realm.createObject(Result::class.java, UUID.randomUUID().toString())
return session return session
} }

@ -34,7 +34,7 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val yearQueries = Criteria.Years.queryConditions val yearQueries = Criteria.Years.queryConditions(realm)
assertEquals(16, yearQueries.size) assertEquals(16, yearQueries.size)
@ -57,7 +57,7 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() {
fun combined() { fun combined() {
val criterias = listOf(Criteria.MonthsOfYear, Criteria.DaysOfWeek) val criterias = listOf(Criteria.MonthsOfYear, Criteria.DaysOfWeek)
val combined = criterias.combined() val combined = criterias.combined(this.mockRealm)
val context = InstrumentationRegistry.getInstrumentation().context val context = InstrumentationRegistry.getInstrumentation().context
combined.forEach { combined.forEach {
@ -92,7 +92,7 @@ class CriteriaTest : BaseFilterInstrumentedUnitTest() {
realm.commitTransaction() realm.commitTransaction()
val context = InstrumentationRegistry.getInstrumentation().context val context = InstrumentationRegistry.getInstrumentation().context
val allMonths = Criteria.AllMonthsUpToNow.queries val allMonths = Criteria.AllMonthsUpToNow.queries(realm)
allMonths.forEach { allMonths.forEach {
it.conditions.forEach { qc-> it.conditions.forEach { qc->
println("<<<<< ${qc.getDisplayName(context)}") println("<<<<< ${qc.getDisplayName(context)}")

@ -16,7 +16,7 @@ import java.util.*
class BankrollInstrumentedUnitTest : SessionInstrumentedUnitTest() { class BankrollInstrumentedUnitTest : SessionInstrumentedUnitTest() {
private fun createDefaultTransactionTypes(realm: Realm) { private fun createDefaultTransactionTypes(realm: Realm) {
TransactionType.Value.values().forEachIndexed { index, value -> TransactionType.Value.values().forEachIndexed { _, value ->
val type = TransactionType() val type = TransactionType()
type.additive = value.additive type.additive = value.additive
type.kind = value.uniqueIdentifier type.kind = value.uniqueIdentifier
@ -64,10 +64,12 @@ class BankrollInstrumentedUnitTest : SessionInstrumentedUnitTest() {
val s1 = newSessionInstance(realm) val s1 = newSessionInstance(realm)
s1.bankroll = br1 s1.bankroll = br1
s1.result?.cashout = 200.0 s1.result?.cashout = 200.0
s1.preCompute()
val s2 = newSessionInstance(realm) val s2 = newSessionInstance(realm)
s2.bankroll = br2 s2.bankroll = br2
s2.result?.cashout = 500.0 s2.result?.cashout = 500.0
s2.preCompute()
} }
@ -113,6 +115,7 @@ class BankrollInstrumentedUnitTest : SessionInstrumentedUnitTest() {
val s1 = newSessionInstance(realm) val s1 = newSessionInstance(realm)
s1.bankroll = br1 s1.bankroll = br1
s1.result?.cashout = 200.0 s1.result?.cashout = 200.0
s1.endDate = Date()
} }

@ -65,6 +65,9 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() {
s1.location = l1 s1.location = l1
s2.location = l1 s2.location = l1
s1.preCompute()
s2.preCompute()
realm.commitTransaction() realm.commitTransaction()
assertEquals(2, computableResults.size) assertEquals(2, computableResults.size)
@ -249,6 +252,9 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() {
// netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800 // netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800
// netDuration = 4h, hourly = 100, bb100 = 150 / 75 * 100 = +200 // netDuration = 4h, hourly = 100, bb100 = 150 / 75 * 100 = +200
s1.preCompute()
s2.preCompute()
} }
val stats: List<Stat> = listOf(Stat.NET_RESULT, Stat.AVERAGE) val stats: List<Stat> = listOf(Stat.NET_RESULT, Stat.AVERAGE)
@ -316,6 +322,10 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() {
realm.copyToRealmOrUpdate(s2) realm.copyToRealmOrUpdate(s2)
realm.copyToRealmOrUpdate(s3) realm.copyToRealmOrUpdate(s3)
s1.preCompute()
s2.preCompute()
s3.preCompute()
realm.commitTransaction() realm.commitTransaction()
val stats: List<Stat> = listOf(Stat.NET_RESULT, Stat.AVERAGE) val stats: List<Stat> = listOf(Stat.NET_RESULT, Stat.AVERAGE)
@ -454,6 +464,9 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() {
s1.endDate = ed1 s1.endDate = ed1
realm.copyToRealmOrUpdate(s1) realm.copyToRealmOrUpdate(s1)
s1.preCompute()
realm.commitTransaction() realm.commitTransaction()
val sets = realm.where(SessionSet::class.java).findAll() val sets = realm.where(SessionSet::class.java).findAll()
@ -498,6 +511,9 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() {
realm.copyToRealmOrUpdate(s1) realm.copyToRealmOrUpdate(s1)
realm.copyToRealmOrUpdate(s2) realm.copyToRealmOrUpdate(s2)
s1.preCompute()
s2.preCompute()
realm.commitTransaction() realm.commitTransaction()
val sets = realm.where(SessionSet::class.java).findAll() val sets = realm.where(SessionSet::class.java).findAll()
@ -731,6 +747,10 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() {
s2.startDate = sd2 s2.startDate = sd2
s2.endDate = ed2 s2.endDate = ed2
s1.preCompute()
s2.preCompute()
} }
val group = ComputableGroup(Query(), listOf()) val group = ComputableGroup(Query(), listOf())

@ -21,7 +21,7 @@ import net.pokeranalytics.android.model.migrations.PokerAnalyticsMigration
import net.pokeranalytics.android.model.realm.FlatTimeInterval import net.pokeranalytics.android.model.realm.FlatTimeInterval
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.utils.Seed import net.pokeranalytics.android.model.utils.Seed
import net.pokeranalytics.android.model.utils.SessionSetManager import net.pokeranalytics.android.model.utils.TimeManager
import net.pokeranalytics.android.util.CrashLogging import net.pokeranalytics.android.util.CrashLogging
import net.pokeranalytics.android.util.FakeDataManager import net.pokeranalytics.android.util.FakeDataManager
import net.pokeranalytics.android.util.PokerAnalyticsLogs import net.pokeranalytics.android.util.PokerAnalyticsLogs
@ -96,7 +96,7 @@ class PokerAnalyticsApplication : Application() {
// Reports // Reports
this.reportWhistleBlower = ReportWhistleBlower(this.applicationContext) this.reportWhistleBlower = ReportWhistleBlower(this.applicationContext)
SessionSetManager.configure() TimeManager.configure()
// Infos // Infos
val locale = Locale.getDefault() val locale = Locale.getDefault()
@ -107,10 +107,10 @@ class PokerAnalyticsApplication : Application() {
val emptyFTI = realm.where(FlatTimeInterval::class.java).isEmpty("sessions").findAll() val emptyFTI = realm.where(FlatTimeInterval::class.java).isEmpty("sessions").findAll()
if (emptyFTI.isNotEmpty()) { if (emptyFTI.isNotEmpty()) {
Timber.w(">>> WARNING: There are ${emptyFTI.size} FTIs without sessions") Timber.w(">>> WARNING: There are ${emptyFTI.size} FTIs without sessions")
Timber.w(">>> DELETING THE EMPTY FTIs") // Timber.w(">>> DELETING THE EMPTY FTIs")
realm.executeTransactionAsync { // realm.executeTransactionAsync {
it.where(FlatTimeInterval::class.java).isEmpty("sessions").findAll().deleteAllFromRealm() // it.where(FlatTimeInterval::class.java).isEmpty("sessions").findAll().deleteAllFromRealm()
} // }
} }
val ftis = realm.where(FlatTimeInterval::class.java).sort("startDate").findAll() val ftis = realm.where(FlatTimeInterval::class.java).sort("startDate").findAll()
@ -119,6 +119,12 @@ class PokerAnalyticsApplication : Application() {
Timber.d("fti > ${it.startDate} / ${it.endDate}") Timber.d("fti > ${it.startDate} / ${it.endDate}")
} }
Timber.d("================")
val sessions = realm.where<Session>().findAll()
sessions.forEach {
Timber.d("Session FTI count = ${it.flatTimeIntervals.size}")
}
} }
/** Defines callbacks for service binding, passed to bindService() */ /** Defines callbacks for service binding, passed to bindService() */

@ -11,7 +11,6 @@ import net.pokeranalytics.android.model.filter.filter
import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.utils.SessionInterval import net.pokeranalytics.android.model.utils.SessionInterval
import net.pokeranalytics.android.util.extensions.startOfDay import net.pokeranalytics.android.util.extensions.startOfDay
import timber.log.Timber
import java.util.* import java.util.*
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@ -75,7 +74,6 @@ class Calculator {
} }
} }
/** /**
* The type of evolution numericValues * The type of evolution numericValues
*/ */
@ -249,7 +247,6 @@ class Calculator {
// Timber.d(">>> group ${group.name} in $duration seconds") // Timber.d(">>> group ${group.name} in $duration seconds")
} }
return report return report
} }
@ -277,6 +274,9 @@ class Calculator {
// Timber.d("$$$ buyin = ${it.ratedBuyin} $$$ net result = ${it.ratedNet}") // Timber.d("$$$ buyin = ${it.ratedBuyin} $$$ net result = ${it.ratedNet}")
// } // }
val ftis = realm.where(FlatTimeInterval::class.java).findAll()
results.addStat(FTI_COUNT, ftis.size.toDouble())
var ratedNet = computables.sum(ComputableResult.Field.RATED_NET.identifier).toDouble() var ratedNet = computables.sum(ComputableResult.Field.RATED_NET.identifier).toDouble()
if (options.includedTransactions.isNotEmpty()) { if (options.includedTransactions.isNotEmpty()) {
for (transactionType in options.includedTransactions) { for (transactionType in options.includedTransactions) {

@ -55,7 +55,8 @@ enum class Stat(override var uniqueIdentifier: Int) : IntIdentifiable, RowRepres
RISK_OF_RUIN(28), RISK_OF_RUIN(28),
STANDARD_DEVIATION_BB(29), STANDARD_DEVIATION_BB(29),
TOURNAMENT_ITM_RATIO(30), TOURNAMENT_ITM_RATIO(30),
TOTAL_TIPS(31) TOTAL_TIPS(31),
FTI_COUNT(32)
; ;
companion object : IntSearchable<Stat> { companion object : IntSearchable<Stat> {
@ -136,6 +137,7 @@ enum class Stat(override var uniqueIdentifier: Int) : IntIdentifiable, RowRepres
TOTAL_BUYIN -> R.string.total_buyin TOTAL_BUYIN -> R.string.total_buyin
TOURNAMENT_ITM_RATIO -> R.string.itm_ratio TOURNAMENT_ITM_RATIO -> R.string.itm_ratio
TOTAL_TIPS -> R.string.total_tips TOTAL_TIPS -> R.string.total_tips
FTI_COUNT -> R.string.players_count
else -> throw PAIllegalStateException("Stat ${this.name} name required but undefined") else -> throw PAIllegalStateException("Stat ${this.name} name required but undefined")
} }
} }
@ -162,7 +164,7 @@ enum class Stat(override var uniqueIdentifier: Int) : IntIdentifiable, RowRepres
return TextFormat(value.formatted, color) return TextFormat(value.formatted, color)
} }
// white integers // white integers
NUMBER_OF_SETS, NUMBER_OF_GAMES, HANDS_PLAYED, LOCATIONS_PLAYED, DAYS_PLAYED -> { NUMBER_OF_SETS, NUMBER_OF_GAMES, HANDS_PLAYED, LOCATIONS_PLAYED, DAYS_PLAYED, FTI_COUNT -> {
return TextFormat("${value.toInt()}") return TextFormat("${value.toInt()}")
} // white durations } // white durations
HOURLY_DURATION, AVERAGE_HOURLY_DURATION, MAXIMUM_DURATION -> { HOURLY_DURATION, AVERAGE_HOURLY_DURATION, MAXIMUM_DURATION -> {

@ -31,7 +31,7 @@ class BankrollCalculator {
var initialValue = 0.0 var initialValue = 0.0
var transactionNet = 0.0 var transactionNet = 0.0
bankrolls.forEach { bankroll -> for (bankroll in bankrolls) {
val rate = if (setup.virtualBankroll) bankroll.rate else 1.0 val rate = if (setup.virtualBankroll) bankroll.rate else 1.0
@ -70,8 +70,8 @@ class BankrollCalculator {
val transactions = Filter.queryOn<Transaction>(realm, baseQuery) val transactions = Filter.queryOn<Transaction>(realm, baseQuery)
report.addDatedItems(transactions) report.addDatedItems(transactions)
transactions.forEach { for (transaction in transactions) {
report.addTransaction(it) report.addTransaction(transaction)
} }
val sessionQuery = Query(QueryCondition.DateNotNull).merge(baseQuery) val sessionQuery = Query(QueryCondition.DateNotNull).merge(baseQuery)
@ -83,8 +83,8 @@ class BankrollCalculator {
val options = Calculator.Options(stats = listOf(Stat.NET_RESULT, Stat.HOURLY_RATE, Stat.STANDARD_DEVIATION_HOURLY)) val options = Calculator.Options(stats = listOf(Stat.NET_RESULT, Stat.HOURLY_RATE, Stat.STANDARD_DEVIATION_HOURLY))
val group = ComputableGroup(baseQuery) val group = ComputableGroup(baseQuery)
val result = Calculator.compute(realm, group, options) val result = Calculator.compute(realm, group, options)
result.computedStat(Stat.NET_RESULT)?.let { result.computedStat(Stat.NET_RESULT)?.let { computedStat ->
report.netResult = it.value report.netResult = computedStat.value
} }
this.computeRiskOfRuin(report, result) this.computeRiskOfRuin(report, result)

@ -9,7 +9,7 @@ import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.model.utils.Seed import net.pokeranalytics.android.model.utils.Seed
import net.pokeranalytics.android.model.utils.SessionSetManager import net.pokeranalytics.android.model.utils.TimeManager
import net.pokeranalytics.android.util.BLIND_SEPARATOR import net.pokeranalytics.android.util.BLIND_SEPARATOR
import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.Preferences
import java.text.NumberFormat import java.text.NumberFormat
@ -173,7 +173,7 @@ class Patcher {
asyncRealm.where(SessionSet::class.java).findAll().deleteAllFromRealm() asyncRealm.where(SessionSet::class.java).findAll().deleteAllFromRealm()
val sessions = asyncRealm.where(Session::class.java).isNotNull("startDate").isNotNull("endDate").findAll() val sessions = asyncRealm.where(Session::class.java).isNotNull("startDate").isNotNull("endDate").findAll()
sessions.forEach { session -> sessions.forEach { session ->
SessionSetManager.updateTimeline(session) TimeManager.updateTimeline(session)
} }
} }
realm.close() realm.close()

@ -27,7 +27,7 @@ import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.filter.QueryCondition.* import net.pokeranalytics.android.model.filter.QueryCondition.*
import net.pokeranalytics.android.model.interfaces.* import net.pokeranalytics.android.model.interfaces.*
import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.model.utils.SessionSetManager import net.pokeranalytics.android.model.utils.TimeManager
import net.pokeranalytics.android.ui.adapter.UnmanagedRowRepresentableException import net.pokeranalytics.android.ui.adapter.UnmanagedRowRepresentableException
import net.pokeranalytics.android.ui.graph.Graph import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.ui.view.* import net.pokeranalytics.android.ui.view.*
@ -216,7 +216,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
this.endDate = null this.endDate = null
} }
SessionSetManager.startChanged(this, min(previous, value)) TimeManager.startChanged(this, min(previous, value))
// this.computeStats() // this.computeStats()
} }
@ -238,7 +238,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
} }
this.computeNetDuration() this.computeNetDuration()
SessionSetManager.endChanged(this, max(previous, value)) TimeManager.endChanged(this, max(previous, value))
this.defineDefaultTournamentBuyinIfNecessary() this.defineDefaultTournamentBuyinIfNecessary()
// this.computeStats() // this.computeStats()
} }
@ -711,10 +711,10 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
// Updates the timeline // Updates the timeline
this.sessionSet?.let { this.sessionSet?.let {
SessionSetManager.removeFromTimeline(this) TimeManager.removeFromTimeline(this)
} }
SessionSetManager.sessionDateChanged(this) TimeManager.sessionDateChanged(this)
// cleanup unnecessary related objects // cleanup unnecessary related objects
this.flatTimeIntervals.deleteAllFromRealm() this.flatTimeIntervals.deleteAllFromRealm()

@ -17,10 +17,13 @@ import java.util.*
class CorruptSessionSetException(message: String) : Exception(message) class CorruptSessionSetException(message: String) : Exception(message)
/** /**
* The manager is in charge of updating the concept of timeline, * The TimeManager pre-computes time related data:
* representing the time frames where the user plays. * - SessionSet: All overlapping sessions are grouped into a SessionSet,
* used to calculate the number of sessions and break durations
* - FlatTimeInterval: Sessions time intervals are breaked down into smaller intervals
* when overlapping occurs to get faster duration calculations
*/ */
object SessionSetManager { object TimeManager {
var sessions: RealmResults<Session>? = null var sessions: RealmResults<Session>? = null
@ -55,29 +58,82 @@ object SessionSetManager {
sessions = realm.where(Session::class.java).findAllAsync() sessions = realm.where(Session::class.java).findAllAsync()
sessions?.addChangeListener { _, _ -> sessions?.addChangeListener { _, _ ->
if (this.start != null && this.end != null) {
realm.executeTransactionAsync { asyncRealm -> if (sessionIdsToProcess.isNotEmpty()) {
processSessions(asyncRealm)
cleanUp() realm.executeTransactionAsync({ asyncRealm ->
val sessions = sessionIdsToProcess.mapNotNull { asyncRealm.findById<Session>(it) }
sessionIdsToProcess.clear()
for (session in sessions) {
Timber.d("Session id = ${session.id}")
Timber.d("Session time intervals count = ${session.flatTimeIntervals.size}")
session.flatTimeIntervals.deleteAllFromRealm()
val fti = FlatTimeInterval()
session.flatTimeIntervals.add(fti)
asyncRealm.insertOrUpdate(session)
} }
}, {
Timber.d("executeTransactionAsync onSuccess listener...")
val timeIntervals = realm.where(FlatTimeInterval::class.java).findAll()
Timber.d("Total timeIntervals count = ${timeIntervals.size}")
timeIntervals.forEach {
Timber.d(">>> Time interval session count = ${it.sessions?.size}, session id = ${it.sessions?.firstOrNull()?.id}")
} }
}, {})
}
} }
// sessions?.addChangeListener { _, _ ->
//
// Timber.d("...sessions change at ${Date().time}")
//
// val start = this.start
// val end = this.end
// if (start != null && end != null) {
//
// Timber.d("...process date changes from $start to $end")
//
// this.start = null
// this.end = null
//
// realm.executeTransactionAsync ({ asyncRealm ->
// processSessions(asyncRealm, start, end)
// cleanUp()
// }, {
// Timber.d(">>>>> ON SUCCESS")
//
// realm.where(FlatTimeInterval::class.java).findAll().forEach {
// Timber.d("######## sessions count = ${it.sessions?.size}")
// }
//
// }, {
// Timber.d("Transaction failed : $it")
// })
// }
// }
realm.close() realm.close()
} }
private fun cleanUp() { private fun cleanUp() {
this.start = null this.start = null
this.end = null this.end = null
// this.sessionIdsToProcess.clear() this.sessionIdsToProcess.clear()
} }
private fun processSessions(realm: Realm) { private fun processSessions(realm: Realm, start: Date, end: Date) {
Timber.d("***** processSessions, process count = ${sessionIdsToProcess.size}") Timber.d("***** processSessions, process count = ${sessionIdsToProcess.size}")
val start = this.start // val start = this.start
val end = this.end // val end = this.end
val sessions = sessionIdsToProcess.mapNotNull { realm.findById<Session>(it) } val sessions = sessionIdsToProcess.mapNotNull { realm.findById<Session>(it) }
for (session in sessions) { for (session in sessions) {
@ -94,9 +150,7 @@ object SessionSetManager {
} }
// FlatTimeIntervals // FlatTimeIntervals
if (start != null && end != null) {
processFlatTimeInterval(realm, sessions.toSet(), start, end) processFlatTimeInterval(realm, sessions.toSet(), start, end)
}
val ftis = realm.where(FlatTimeInterval::class.java).findAll() val ftis = realm.where(FlatTimeInterval::class.java).findAll()
Timber.d("*** FTIs count = ${ftis.size}") Timber.d("*** FTIs count = ${ftis.size}")
@ -306,16 +360,21 @@ object SessionSetManager {
private fun processFlatTimeInterval(realm: Realm, changedSessions: Set<Session>, start: Date, end: Date) { private fun processFlatTimeInterval(realm: Realm, changedSessions: Set<Session>, start: Date, end: Date) {
Timber.d("***************************************************") // Timber.d("***************************************************")
Timber.d("*** processFlatTimeInterval, from: $start, to $end") // Timber.d("*** processFlatTimeInterval, from: $start, to $end")
Timber.d("***************************************************") // Timber.d("***************************************************")
val sessions = matchingData<Session>(realm, start, end) val sessions = matchingData<Session>(realm, start, end)
Timber.d("*** matching sessions: ${sessions.size}")
val intervalsStore = IntervalsStore(sessions.toSet()) val intervalsStore = IntervalsStore(sessions.toSet())
intervalsStore.processSessions(changedSessions) intervalsStore.processSessions(changedSessions)
intervalsStore.intervals.forEach { it.deleteFromRealm() } Timber.d("*** sessions count = ${intervalsStore.sessions.size}")
Timber.d("*** ftis to delete: ${intervalsStore.intervals.size}")
for (fti in intervalsStore.intervals) {
fti.deleteFromRealm()
}
// intervalsStore.intervals.forEach { it.deleteFromRealm() }
val intervals = SessionInterval.intervalMap(intervalsStore.sessions) val intervals = SessionInterval.intervalMap(intervalsStore.sessions)
@ -333,17 +392,25 @@ object SessionSetManager {
(sd != null && ed != null && sd <= s && ed >= e) (sd != null && ed != null && sd <= s && ed >= e)
} }
if (matchingSessions.isNotEmpty()) { if (matchingSessions.isNotEmpty()) {
Timber.d("**** Create FTI: $s - $e") // Timber.d("**** Create FTI: $s - $e")
val fti = FlatTimeInterval() val fti = FlatTimeInterval()
fti.startDate = s fti.startDate = s
fti.endDate = e fti.endDate = e
matchingSessions.forEach { it.flatTimeIntervals.add(fti) } for (session in matchingSessions) {
session.flatTimeIntervals.add(fti)
realm.insertOrUpdate(session)
}
realm.insertOrUpdate(fti) realm.insertOrUpdate(fti)
} else { } else {
Timber.w("The FTI has no sessions") Timber.w("The FTI has no sessions")
} }
} }
} }
sessions.forEach {
Timber.d("ending process...session FTI count = ${it.flatTimeIntervals.size}")
}
} }
} }
@ -366,7 +433,7 @@ class IntervalsStore(sessionSet: Set<Session>) {
fun processSessions(sessions: Set<Session>) { fun processSessions(sessions: Set<Session>) {
this.sessions.addAll(sessions) this.sessions.addAll(sessions)
for (session in sessions) { for (session in sessions) {
Timber.d("PROCESS > s = ${session.startDate} / e = ${session.endDate} ") // Timber.d("PROCESS > s = ${session.startDate} / e = ${session.endDate} ")
loadIntervals(session) loadIntervals(session)
} }
} }
@ -382,6 +449,7 @@ class IntervalsStore(sessionSet: Set<Session>) {
this.sessionIds.add(session.id) this.sessionIds.add(session.id)
Timber.d("session FTI count = ${session.flatTimeIntervals.size}")
for (fti in session.flatTimeIntervals) { for (fti in session.flatTimeIntervals) {
this.intervals.add(fti) this.intervals.add(fti)
@ -411,7 +479,7 @@ class SessionInterval(session: Session) {
this.start = session.startDate!! this.start = session.startDate!!
this.end = session.endDate this.end = session.endDate
Timber.d("INTERVAL init: s = $start, e = $end") // Timber.d("INTERVAL init: s = $start, e = $end")
this.addSession(session) this.addSession(session)
} }
@ -454,9 +522,9 @@ class SessionInterval(session: Session) {
} }
} }
intervals.forEach { // intervals.forEach {
Timber.d("s = ${it.start}, e = ${it.end}") // Timber.d("s = ${it.start}, e = ${it.end}")
} // }
return intervals return intervals
} }

@ -179,7 +179,7 @@ class StatisticsFragment : FilterableFragment(), RealmAsyncListener {
val e = Date() val e = Date()
val duration = (e.time - s.time) / 1000.0 val duration = (e.time - s.time) / 1000.0
Timber.d(">>> computations took $duration seconds") // Timber.d(">>> computations took $duration seconds")
} }
async.await() async.await()
@ -197,7 +197,7 @@ class StatisticsFragment : FilterableFragment(), RealmAsyncListener {
*/ */
private fun createSessionGroupsAndStartCompute(realm: Realm): Report { private fun createSessionGroupsAndStartCompute(realm: Realm): Report {
Timber.d(">>> Launch statistics computations") // Timber.d(">>> Launch statistics computations")
val filter: Filter? = this.currentFilter(this.requireContext(), realm)?.let { val filter: Filter? = this.currentFilter(this.requireContext(), realm)?.let {
if (it.filterableType == currentFilterable) { it } else { null } if (it.filterableType == currentFilterable) { it } else { null }
@ -210,6 +210,7 @@ class StatisticsFragment : FilterableFragment(), RealmAsyncListener {
Stat.NUMBER_OF_SETS, Stat.NUMBER_OF_SETS,
Stat.AVERAGE_HOURLY_DURATION, Stat.AVERAGE_HOURLY_DURATION,
Stat.HOURLY_DURATION, Stat.HOURLY_DURATION,
Stat.FTI_COUNT,
Stat.HANDS_PLAYED Stat.HANDS_PLAYED
) )

@ -399,7 +399,7 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource,
val e = Date() val e = Date()
val duration = (e.time - s.time) / 1000.0 val duration = (e.time - s.time) / 1000.0
Timber.d(">>> computations took $duration seconds") // Timber.d(">>> computations took $duration seconds")
} }
async.await() async.await()

@ -24,7 +24,7 @@ import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.model.utils.SessionSetManager import net.pokeranalytics.android.model.utils.TimeManager
import net.pokeranalytics.android.ui.activity.BillingActivity import net.pokeranalytics.android.ui.activity.BillingActivity
import net.pokeranalytics.android.ui.activity.components.RequestCode import net.pokeranalytics.android.ui.activity.components.RequestCode
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
@ -481,7 +481,7 @@ class FeedFragment : FilterableFragment(), RowRepresentableDelegate, PurchaseLis
for (id in sessions) { for (id in sessions) {
r.findById<Session>(id)?.let { s -> r.findById<Session>(id)?.let { s ->
s.tableSize = 6 s.tableSize = 6
SessionSetManager.sessionDateChanged(s) TimeManager.sessionDateChanged(s)
} }
} }
} }

@ -210,7 +210,7 @@ class FeedSessionRowRepresentableAdapter(
} }
sortedHeaders = headersPositions.toSortedMap() sortedHeaders = headersPositions.toSortedMap()
Timber.d("Create viewTypesPositions in: ${System.currentTimeMillis() - start}ms") // Timber.d("Create viewTypesPositions in: ${System.currentTimeMillis() - start}ms")
} }
/** /**

@ -432,7 +432,7 @@
<string name="place">Place</string> <string name="place">Place</string>
<string name="player">Player</string> <string name="player">Player</string>
<string name="players">Players</string> <string name="players">Players</string>
<string name="players_count">Player\'s count</string> <string name="players_count">Players count</string>
<string name="please_check_if_your_values_are_valid">Please check if your values are valid</string> <string name="please_check_if_your_values_are_valid">Please check if your values are valid</string>
<string name="please_confirm_the_import_start_">Please confirm the import of \'%s\'?</string> <string name="please_confirm_the_import_start_">Please confirm the import of \'%s\'?</string>
<string name="please_report_a_bug">An internal issue has occurred. We would be glad if you could report a bug with the steps to reproduce the bug. Thank you!</string> <string name="please_report_a_bug">An internal issue has occurred. We would be glad if you could report a bug with the steps to reproduce the bug. Thank you!</string>

Loading…
Cancel
Save