commit stuff

realmasync
Laurent 2 years ago
parent 2a748358e2
commit 6644e71cc5
  1. 20
      app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt
  2. 56
      app/src/main/java/net/pokeranalytics/android/calculus/DataManager.kt
  3. 7
      app/src/main/java/net/pokeranalytics/android/calculus/ReportWhistleBlower.kt
  4. 6
      app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt
  5. 74
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  6. 6
      app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt
  7. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt
  8. 26
      app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt
  9. 19
      app/src/main/java/net/pokeranalytics/android/util/FakeDataManager.kt
  10. 14
      app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt

@ -6,16 +6,14 @@ import android.os.Build
import com.google.firebase.FirebaseApp
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.kotlin.where
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import net.pokeranalytics.android.calculus.DataManager
import net.pokeranalytics.android.model.migrations.Patcher
import net.pokeranalytics.android.model.migrations.PokerAnalyticsMigration
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.UserConfigObserver
import net.pokeranalytics.android.model.utils.Seed
import net.pokeranalytics.android.calculus.DataManager
import net.pokeranalytics.android.util.*
import net.pokeranalytics.android.util.billing.AppGuard
import timber.log.Timber
@ -99,6 +97,8 @@ class PokerAnalyticsApplication : Application() {
// it.delete(Performance::class.java)
// }
// createFakeSessions()
}
/**
@ -106,15 +106,15 @@ class PokerAnalyticsApplication : Application() {
*/
private fun createFakeSessions() {
val realm = Realm.getDefaultInstance()
val sessionsCount = realm.where<Session>().count()
realm.close()
// val realm = Realm.getDefaultInstance()
// val sessionsCount = realm.where<Session>().count()
// realm.close()
if (sessionsCount < 10) {
CoroutineScope(context = Dispatchers.IO).launch {
FakeDataManager.createFakeSessions(500)
// if (sessionsCount < 10) {
CoroutineScope(context = Dispatchers.Default).launch {
FakeDataManager.createFakeSessions(8000)
}
}
// }
}

@ -4,7 +4,6 @@ import android.content.Context
import io.realm.Realm
import io.realm.RealmQuery
import io.realm.RealmResults
import io.realm.kotlin.where
import net.pokeranalytics.android.exceptions.ModelException
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.realm.Currency
@ -37,18 +36,21 @@ object DataManager {
val realm = Realm.getDefaultInstance()
sessions = realm.where(Session::class.java).findAllAsync()
sessions?.addChangeListener { results ->
results.realm.writeAsync { asyncRealm ->
computeStatsIfNecessary(asyncRealm)
computeDatesIfNecessary(asyncRealm)
reportWhistleBlower?.requestReportLaunch()
}
sessions?.addChangeListener { sessions ->
// if (this.dateModifiedSessionIds.isNotEmpty() || this.statsToComputeSessionIds.isNotEmpty()) {
sessions.realm.writeAsync { asyncRealm ->
computeStatsIfNecessary(asyncRealm)
computeDatesIfNecessary(asyncRealm)
reportWhistleBlower?.requestReportLaunch()
}
// }
}
this.currencies = realm.where(Currency::class.java).findAll()
this.currencies?.addChangeListener { _, _ ->
this.currencies?.addChangeListener { currencies, _ ->
if (changedCurrencies.isNotEmpty()) {
realm.writeAsync { asyncRealm ->
currencies.realm.writeAsync { asyncRealm ->
for (currencyId in this.changedCurrencies) {
asyncRealm.findById<Currency>(currencyId)?.let { currency ->
Timber.d("Compute currency ${currency.code} ")
@ -68,25 +70,25 @@ object DataManager {
}
fun sessionToCompute(session: Session) {
Timber.d("sessionToCompute")
// Timber.d("sessionToCompute, date = ${session.startDate} / ${session.endDate}")
statsToComputeSessionIds.add(session.id)
}
fun sessionDateChanged(session: Session) {
Timber.d("sessionDateChanged")
// Timber.d("sessionDateChanged")
dateModifiedSessionIds.add(session.id)
}
fun currencyToCompute(currency: Currency) {
Timber.d("sessionToCompute")
// Timber.d("currencyToCompute")
changedCurrencies.add(currency.id)
}
private fun computeStatsIfNecessary(realm: Realm) {
if (statsToComputeSessionIds.isNotEmpty()) {
for (sessionId in statsToComputeSessionIds) {
Timber.d("Session Manager > compute stats")
realm.findById<Session>(sessionId)?.let { session ->
// Timber.d("Session Manager > compute stats, set = ${session.sessionSet}")
session.computeStats()
session.sessionSet?.computeStats()
}
@ -98,8 +100,8 @@ object DataManager {
private fun computeDatesIfNecessary(realm: Realm) {
if (dateModifiedSessionIds.isNotEmpty()) {
for (sessionId in dateModifiedSessionIds) {
Timber.d("Session Manager > manage dates")
realm.findById<Session>(sessionId)?.let { session ->
// Timber.d("Session Manager > manage dates, set = ${session.sessionSet}")
if (session.endDate != null) {
updateTimeline(session)
} else if (session.sessionSet != null) {
@ -116,7 +118,7 @@ object DataManager {
*/
fun updateTimeline(session: Session) {
Timber.d("updateTimeline...")
// Timber.d("updateTimeline...")
if (!session.realm.isInTransaction) {
throw PAIllegalStateException("realm should be in transaction at this point")
@ -160,7 +162,7 @@ object DataManager {
* Does that by deleting then recreating
*/
private fun cleanupSessionSets(session: Session, sessionSets: RealmResults<SessionSet>) {
Timber.d("cleanupSessionSets...")
// Timber.d("cleanupSessionSets...")
// get all endedSessions from sets
val allImpactedSessions = mutableSetOf<Session>()
@ -183,7 +185,7 @@ object DataManager {
* Update the global timeline using the impacted [sessionSets] and the updated [session]
*/
private fun updateTimeFrames(sessionSets: RealmResults<SessionSet>, session: Session) {
Timber.d("updateTimeFrames...")
// Timber.d("updateTimeFrames...")
when (sessionSets.size) {
0 -> createOrUpdateSessionSet(session)
@ -196,7 +198,7 @@ object DataManager {
* Creates or update the session set for the [session]
*/
private fun createOrUpdateSessionSet(session: Session) {
Timber.d("createOrUpdateSessionSet...")
// Timber.d("createOrUpdateSessionSet...")
val set = session.sessionSet
if (set != null) {
@ -212,7 +214,7 @@ object DataManager {
* Create a set and affect it to the [session]
*/
private fun createSessionSet(session: Session) {
Timber.d("createSessionSet...")
// Timber.d("createSessionSet...")
val realm = session.realm
val set = SessionSet.newInstance(realm)
@ -222,11 +224,11 @@ object DataManager {
session.sessionSet = set
set.computeStats()
Timber.d("SET SESSION count = ${set.sessions?.size}")
val t = 0
val f = realm.where<SessionSet>().equalTo("sessions.type", t).findAll()
Timber.d("CASH SET COUNT = ${f.size}")
// Timber.d("SET SESSION count = ${set.sessions?.size}")
//
// val t = 0
// val f = realm.where<SessionSet>().equalTo("sessions.type", t).findAll()
// Timber.d("CASH SET COUNT = ${f.size}")
}
@ -236,7 +238,7 @@ object DataManager {
*/
private fun mergeSessionGroups(session: Session, sessionSets: RealmResults<SessionSet>) {
Timber.d("mergeSessionGroups")
// Timber.d("mergeSessionGroups")
var startDate = session.startDate!!
var endDate = session.endDate!!
@ -291,7 +293,7 @@ object DataManager {
*/
fun removeFromTimeline(session: Session) {
Timber.d("removeFromTimeline")
// Timber.d("removeFromTimeline")
if (!session.realm.isInTransaction) {
throw PAIllegalStateException("realm should be in transaction at this point")
@ -304,7 +306,7 @@ object DataManager {
sessionSet.sessions?.asIterable()?.let { sessions.addAll(it) }
sessions.remove(session)
Timber.d(">>> sessionSet.deleteFromRealm")
// Timber.d(">>> sessionSet.deleteFromRealm")
sessionSet.deleteFromRealm()
sessions.forEach {

@ -11,6 +11,7 @@ import net.pokeranalytics.android.model.realm.PerformanceKey
import net.pokeranalytics.android.ui.view.rows.StaticReport
import net.pokeranalytics.android.util.extensions.findById
import net.pokeranalytics.android.util.extensions.formattedHourlyDuration
import net.pokeranalytics.android.util.extensions.writeAsync
interface NewPerformanceListener {
@ -104,7 +105,11 @@ class ReportWhistleBlower(var context: Context) {
fun resume() {
this.paused = false
this.requestReportLaunch()
val realm = Realm.getDefaultInstance()
realm.writeAsync {
this.requestReportLaunch()
}
realm.close()
}
fun has(performanceId: String): Boolean {

@ -4,12 +4,12 @@ import android.content.Context
import io.realm.Realm
import io.realm.kotlin.where
import net.pokeranalytics.android.PokerAnalyticsApplication
import net.pokeranalytics.android.calculus.DataManager
import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.model.utils.Seed
import net.pokeranalytics.android.calculus.DataManager
import net.pokeranalytics.android.util.BLIND_SEPARATOR
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.extensions.writeAsync
@ -202,7 +202,9 @@ class Patcher {
val performanceCount = realm.where<Performance>().findAll().size
if (sessionCount > 1 && performanceCount == 0) {
DataManager.reportWhistleBlower?.requestReportLaunch()
realm.writeAsync {
DataManager.reportWhistleBlower?.requestReportLaunch()
}
}
realm.close()
}

@ -983,16 +983,16 @@ open class Session : RealmObject(), Savable, RowRepresentable, Timed,
}
private fun customFieldEntries(realm: Realm, customField: CustomField): List<CustomFieldEntry> {
// val cfEntries = customField.entries
// val sessionEntries = this.customFieldEntries
// private fun customFieldEntries(realm: Realm, customField: CustomField): List<CustomFieldEntry> {
//
// val entries = realm.where<CustomFieldEntry>()
// .`in`()
return listOf()
}
//// val cfEntries = customField.entries
//// val sessionEntries = this.customFieldEntries
////
//// val entries = realm.where<CustomFieldEntry>()
//// .`in`()
//
// return listOf()
// }
// private fun getOrCreateResult(): Result {
// return this.result
@ -1016,39 +1016,35 @@ open class Session : RealmObject(), Savable, RowRepresentable, Timed,
override fun formattedValue(stat: Stat): TextFormat {
// this.result?.let { result ->
val value: Double? = when (stat) {
Stat.NET_RESULT, Stat.AVERAGE, Stat.STANDARD_DEVIATION -> this.net
Stat.NUMBER_OF_GAMES, Stat.NUMBER_OF_SETS -> 1.0
Stat.AVERAGE_BUYIN -> this.buyin
Stat.ROI -> {
this.buyin?.let {
Stat.returnOnInvestment(this.net, it)
} ?: run {
null
}
val value: Double? = when (stat) {
Stat.NET_RESULT, Stat.AVERAGE, Stat.STANDARD_DEVIATION -> this.net
Stat.NUMBER_OF_GAMES, Stat.NUMBER_OF_SETS -> 1.0
Stat.AVERAGE_BUYIN -> this.buyin
Stat.ROI -> {
this.buyin?.let {
Stat.returnOnInvestment(this.net, it)
} ?: run {
null
}
Stat.HOURLY_RATE_BB -> this.bbHourlyRate
Stat.NET_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION_BB_PER_100_HANDS -> Stat.netBBPer100Hands(
this.bbNet,
this.estimatedHands
)
Stat.AVERAGE_NET_BB, Stat.BB_NET_RESULT -> this.bbNet
Stat.HOURLY_DURATION, Stat.AVERAGE_HOURLY_DURATION -> this.netDuration.toDouble()
Stat.HOURLY_RATE, Stat.STANDARD_DEVIATION_HOURLY -> this.hourlyRate
Stat.HANDS_PLAYED -> this.estimatedHands
Stat.WIN_RATIO -> null
else -> throw StatFormattingException("format undefined for stat ${stat.name}")
}
value?.let {
return stat.textFormat(it, currency = currency)
} ?: run {
return TextFormat(NULL_TEXT)
}
Stat.HOURLY_RATE_BB -> this.bbHourlyRate
Stat.NET_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION_BB_PER_100_HANDS -> Stat.netBBPer100Hands(
this.bbNet,
this.estimatedHands
)
Stat.AVERAGE_NET_BB, Stat.BB_NET_RESULT -> this.bbNet
Stat.HOURLY_DURATION, Stat.AVERAGE_HOURLY_DURATION -> this.netDuration.toDouble()
Stat.HOURLY_RATE, Stat.STANDARD_DEVIATION_HOURLY -> this.hourlyRate
Stat.HANDS_PLAYED -> this.estimatedHands
Stat.WIN_RATIO -> null
else -> throw StatFormattingException("format undefined for stat ${stat.name}")
}
// }
value?.let {
return stat.textFormat(it, currency = currency)
} ?: run {
return TextFormat(NULL_TEXT)
}
}

@ -15,7 +15,6 @@ import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.interfaces.Timed
import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.TextFormat
import timber.log.Timber
import java.text.DateFormat
import java.util.*
@ -62,7 +61,7 @@ open class SessionSet : RealmObject(), Timed, Filterable {
override var netDuration: Long = 0L
fun computeStats() {
Timber.d("compute > session count = ${this.sessions?.size}")
// Timber.d("compute > session count = ${this.sessions?.size}")
this.ratedNet = this.sessions?.sumOf { it.computableResult?.ratedNet ?: 0.0 } ?: 0.0
this.estimatedHands = this.sessions?.sumOf { it.estimatedHands } ?: 0.0
this.bbNet = this.sessions?.sumOf { it.bbNet } ?: 0.0
@ -103,8 +102,7 @@ open class SessionSet : RealmObject(), Timed, Filterable {
companion object {
fun newInstance(realm: Realm): SessionSet {
val sessionSet = SessionSet()
return realm.copyToRealm(sessionSet)
return realm.copyToRealm(SessionSet())
}
fun fieldNameForQueryType(queryCondition: Class <out QueryCondition>): String? {

@ -349,7 +349,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
CoroutineScope(context = Dispatchers.IO).launch {
val realm = Realm.getDefaultInstance()
realm.refresh()
// realm.refresh()
launchStatComputation(realm)

@ -287,9 +287,22 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
}
private fun writeChanges() {
getRealm().writeAsync { asyncRealm ->
Timber.d("write changes")
getRealm().writeAsync ({ asyncRealm ->
Timber.d("start transaction")
asyncRealm.copyToRealmOrUpdate(this.currentSession)
}
Timber.d("yupyup")
}, { // onSuccess we retrieved the object because it might have been changed (i.e. session set added). Not retrieving it can for example copy it without its sessionset, writing null in db whereas it should have it
Timber.d("onSuccess")
val id = this.currentSession.id
getRealm().refresh()
getRealm().findById<Session>(id)?.let { session ->
this.currentSession = getRealm().copyFromRealm(session)
Timber.d("Session retrieved, set = ${this.currentSession.sessionSet}, br = ${session.bankroll}")
} ?: throw PAIllegalStateException("session not found")
})
}
/**
@ -500,12 +513,15 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
val bankrollId = this.currentSession.bankroll?.id
val id = currentSession.id
getRealm().writeAsync { asyncRealm ->
getRealm().writeAsync ({ asyncRealm ->
asyncRealm.findById<Session>(id)?.let { session ->
session.cleanup()
session.deleteFromRealm()
}
}
} ?: throw PAIllegalStateException("session not found")
}, {
Timber.d("delete successful")
// getRealm().refresh()
})
bankrollId?.let {
BankrollReportManager.notifyBankrollReportImpact(bankrollId)

@ -8,7 +8,6 @@ import net.pokeranalytics.android.model.realm.Game
import net.pokeranalytics.android.model.realm.Location
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.util.extensions.getOrCreate
import net.pokeranalytics.android.util.extensions.writeAsync
import timber.log.Timber
import java.util.*
@ -35,14 +34,6 @@ class FakeDataManager {
val bankroll = realm.where<Bankroll>().findAll().firstOrNull()
val locations = realm.where<Location>().findAll()
if (locations.size == 0) {
realm.writeAsync { asyncRealm ->
listOf("Bellagio", "Aria", "Borgata").map {
asyncRealm.getOrCreate<Location>(it)
}
}
}
// Test endedSessions
Timber.d("*** Start creating ${numberOfSessions} fake computables...")
@ -51,10 +42,16 @@ class FakeDataManager {
realm.beginTransaction()
if (locations.size == 0) {
listOf("Bellagio", "Aria", "Borgata").map {
realm.getOrCreate<Location>(it)
}
}
for (index in 1..numberOfSessions) {
if (index % commitFrequency == 0) {
Timber.d("****** committing at ${index} computables...")
Timber.d("****** committing at ${index} sessions...")
realm.commitTransaction()
realm.beginTransaction()
}
@ -98,6 +95,8 @@ class FakeDataManager {
// session.cgSmallBlind = bigBlind / 2.0
}
realm.copyToRealmOrUpdate(session)
}
realm.commitTransaction()

@ -8,6 +8,7 @@ import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.interfaces.UsageCountable
import net.pokeranalytics.android.model.realm.*
import timber.log.Timber
import java.util.*
fun <T : RealmModel>Realm.count(clazz: Class<T>) : Long {
return this.where(clazz).count()
@ -110,14 +111,23 @@ fun Realm.writeAsync(handler: (Realm) -> (Unit)) {
fun Realm.writeAsync(handler: (Realm) -> (Unit), success: () -> (Unit)) {
Timber.d("Start write...")
Timber.d("Start write with success/error...")
val s = Date()
this.executeTransactionAsync({ asyncRealm ->
handler(asyncRealm)
Timber.d("REALM execution ended")
}, { // success
val e = Date()
val duration = e.time - s.time
Timber.d("//// transaction duration = $duration")
Timber.d("SUCCESS!")
success()
}, { error -> // error
Timber.w("Realm write error: $error")
Timber.d("Realm write error: $error")
})
}

Loading…
Cancel
Save