From ebcb50762934713a1b07a1a77dab4b17ba98318e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Tue, 15 Jun 2021 20:13:34 +0200 Subject: [PATCH] optimized wallet header calculation for better performance 160 ms for three wallets over 9500 transactions --- pkg/models/wallets.go | 5 +++ pkg/services/wallets.go | 74 +++++++++++++++++++++++++++------------- pkg/utl/common/common.go | 2 +- 3 files changed, 57 insertions(+), 24 deletions(-) diff --git a/pkg/models/wallets.go b/pkg/models/wallets.go index f72112e..4c79665 100644 --- a/pkg/models/wallets.go +++ b/pkg/models/wallets.go @@ -20,3 +20,8 @@ type WalletHeader struct { NextMonth int `json:"nextMonth"` Currency string `json:"currency"` } + +type WalletTransactions struct { + WalletId string + Transactions []Transaction +} diff --git a/pkg/services/wallets.go b/pkg/services/wallets.go index ad38c28..37907c2 100644 --- a/pkg/services/wallets.go +++ b/pkg/services/wallets.go @@ -1,6 +1,7 @@ package services import ( + "sync" "time" "wallet-api/pkg/models" "wallet-api/pkg/utl/common" @@ -40,7 +41,8 @@ func (as *WalletService) GetAll(am *models.Auth, filtered *models.FilteredRespon func (as *WalletService) GetHeader(am *models.Auth, embed string, walletId string) *models.WalletHeader { wm := new(models.WalletHeader) - //wallets := new([]models.Wallet) + var wallets []models.WalletTransactions + var wg sync.WaitGroup transactions := new([]models.Transaction) query := as.Db.Model(transactions).Relation("Wallet").Where("wallet.? = ?", pg.Ident("user_id"), am.Id).Relation("TransactionType") @@ -65,31 +67,41 @@ func (as *WalletService) GetHeader(am *models.Auth, embed string, walletId strin firstOfMonthAfterNext := time.Date(currentYear, currentMonth+2, 1, 0, 0, 0, 0, currentLocation) for _, trans := range *transactions { - if trans.TransactionDate.Before(firstOfNextMonth) && trans.TransactionDate.After(firstOfMonth) { - if trans.TransactionType.Type == "expense" { - currentBalance -= trans.Amount - } else { - currentBalance += trans.Amount - } - } else if trans.TransactionDate.Before(firstOfMonthAfterNext) && trans.TransactionDate.After(firstOfNextMonth) { - if trans.TransactionType.Type == "expense" { - nextMonth -= trans.Amount - } else { - nextMonth += trans.Amount - } - } else if trans.TransactionDate.Before(firstOfMonth) { - if trans.TransactionType.Type == "expense" { - lastMonthBalance -= trans.Amount - currentBalance -= trans.Amount - } else { - lastMonthBalance += trans.Amount - currentBalance += trans.Amount - } - } + addWhere(&wallets, trans.WalletID, trans) } - wm.CurrentBalance = currentBalance + for range wallets { + wg.Add(1) + go func() { + defer wg.Done() + for _, trans := range *transactions { + if trans.TransactionDate.Before(firstOfNextMonth) && trans.TransactionDate.After(firstOfMonth) { + if trans.TransactionType.Type == "expense" { + currentBalance -= trans.Amount + } else { + currentBalance += trans.Amount + } + } else if trans.TransactionDate.Before(firstOfMonthAfterNext) && trans.TransactionDate.After(firstOfNextMonth) { + if trans.TransactionType.Type == "expense" { + nextMonth -= trans.Amount + } else { + nextMonth += trans.Amount + } + } else if trans.TransactionDate.Before(firstOfMonth) { + if trans.TransactionType.Type == "expense" { + lastMonthBalance -= trans.Amount + } else { + lastMonthBalance += trans.Amount + } + } + } + }() + } + + wg.Wait() + wm.LastMonth = lastMonthBalance + wm.CurrentBalance = currentBalance + lastMonthBalance wm.NextMonth = currentBalance + nextMonth wm.Currency = "USD" wm.WalletId = walletId @@ -98,3 +110,19 @@ func (as *WalletService) GetHeader(am *models.Auth, embed string, walletId strin return wm } + +func addWhere(s *[]models.WalletTransactions, walletId string, e models.Transaction) { + var exists bool + for _, a := range *s { + if a.WalletId == walletId { + a.Transactions = append(a.Transactions, e) + } + exists = true + } + if !exists { + var walletTransaction models.WalletTransactions + walletTransaction.WalletId = walletId + walletTransaction.Transactions = append(walletTransaction.Transactions, e) + *s = append(*s, walletTransaction) + } +} diff --git a/pkg/utl/common/common.go b/pkg/utl/common/common.go index e28db33..4c2ee83 100644 --- a/pkg/utl/common/common.go +++ b/pkg/utl/common/common.go @@ -38,4 +38,4 @@ func GetIP() string { } } return "" -} +} \ No newline at end of file