improve upsert perfomance

This commit is contained in:
2024-08-13 23:39:44 +03:00
parent 30e5968e03
commit 25762cbae8
8 changed files with 127 additions and 83 deletions

View File

@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"sync"
"time"
"git.loyso.art/frx/devsim/internal/entities"
@ -30,11 +31,16 @@ func Dial(ctx context.Context, uri string) (*repository, error) {
return nil, fmt.Errorf("pinging mongo database: %w", err)
}
return &repository{client: client}, nil
updateOptions := options.Update().SetUpsert(true)
return &repository{
client: client,
updateOptions: updateOptions,
}, nil
}
type repository struct {
client *mongo.Client
client *mongo.Client
updateOptions *options.UpdateOptions
}
func (r *repository) Close() error {
@ -46,22 +52,24 @@ func (r *repository) Close() error {
func (r *repository) StatsRepository() statsRepository {
return statsRepository{
collection: r.client.Database("bench").Collection("device_stats"),
collection: r.client.Database("bench").Collection("device_stats"),
updateOptions: r.updateOptions,
}
}
type statsRepository struct {
collection *mongo.Collection
collection *mongo.Collection
updateOptions *options.UpdateOptions
}
type deviceStatsDB struct {
UpdatedAt time.Time `bson:"updated_at"`
DeviceID string `bson:"_id"`
IncomingTraffic int `bson:"inc_traffic"`
OutgoinfTraffic int `bson:"out_traffic"`
IncomingRPS int `bson:"inc_rps"`
ReadRPS int `bson:"read_rps"`
WriteRPS int `bson:"write_rps"`
UpdatedAt time.Time `bson:"updated_at"`
}
func (s deviceStatsDB) asDomain() entities.DeviceStatistics {
@ -76,15 +84,26 @@ func (s deviceStatsDB) asDomain() entities.DeviceStatistics {
}
}
func (r statsRepository) Upsert(ctx context.Context, stats entities.DeviceStatistics) error {
opts := options.Update().SetUpsert(true)
var bsonSyncPool = sync.Pool{
New: func() any {
m := make(bson.M, 1)
return &m
},
}
filter := bson.D{
{
Key: "_id",
Value: stats.ID,
},
}
func getPoolD() *bson.M {
return bsonSyncPool.Get().(*bson.M)
}
func putPoolD(m *bson.M) {
bsonSyncPool.Put(m)
}
type filterByID struct {
ID entities.DeviceID `bson:"_id"`
}
func (r statsRepository) Upsert(ctx context.Context, stats entities.DeviceStatistics) error {
document := deviceStatsDB{
DeviceID: string(stats.ID),
IncomingTraffic: stats.IncomingTrafficBytes,
@ -95,9 +114,13 @@ func (r statsRepository) Upsert(ctx context.Context, stats entities.DeviceStatis
UpdatedAt: time.Now(),
}
// updatePtr := getPoolD()
// update := *updatePtr
// defer putPoolD(updatePtr)
update := bson.M{"$set": document}
_, err := r.collection.UpdateOne(ctx, filter, update, opts)
_, err := r.collection.UpdateOne(ctx, filterByID{ID: stats.ID}, update, r.updateOptions)
if err != nil {
return fmt.Errorf("inserting: %w", err)
}