OSDN Git Service

opt mov performance (#480)
[bytom/vapor.git] / application / mov / match / order_book.go
index f4cd852..ea49643 100644 (file)
@@ -2,6 +2,7 @@ package match
 
 import (
        "sort"
+       "sync"
 
        "github.com/bytom/vapor/application/mov/common"
        "github.com/bytom/vapor/application/mov/database"
@@ -12,22 +13,22 @@ import (
 type OrderBook struct {
        movStore database.MovStore
        // key of tradePair -> []order
-       dbOrders map[string][]*common.Order
+       dbOrders *sync.Map
        // key of tradePair -> iterator
-       orderIterators map[string]*database.OrderIterator
+       orderIterators *sync.Map
 
        // key of tradePair -> []order
-       arrivalAddOrders map[string][]*common.Order
+       arrivalAddOrders *sync.Map
        // key of order -> order
-       arrivalDelOrders map[string]*common.Order
+       arrivalDelOrders *sync.Map
 }
 
 // NewOrderBook create a new OrderBook object
 func NewOrderBook(movStore database.MovStore, arrivalAddOrders, arrivalDelOrders []*common.Order) *OrderBook {
        return &OrderBook{
                movStore:       movStore,
-               dbOrders:       make(map[string][]*common.Order),
-               orderIterators: make(map[string]*database.OrderIterator),
+               dbOrders:       &sync.Map{},
+               orderIterators: &sync.Map{},
 
                arrivalAddOrders: arrangeArrivalAddOrders(arrivalAddOrders),
                arrivalDelOrders: arrangeArrivalDelOrders(arrivalDelOrders),
@@ -37,34 +38,35 @@ func NewOrderBook(movStore database.MovStore, arrivalAddOrders, arrivalDelOrders
 // AddOrder add the in memory temp order to order table
 func (o *OrderBook) AddOrder(order *common.Order) error {
        tradePairKey := order.TradePair().Key()
-       orders := o.arrivalAddOrders[tradePairKey]
-       if len(orders) > 0 && order.Rate() > orders[len(orders)-1].Rate() {
+       orders := o.getArrivalAddOrders(tradePairKey)
+       if len(orders) > 0 && order.Cmp(orders[len(orders)-1]) > 0 {
                return errors.New("rate of order must less than the min order in order table")
        }
 
-       o.arrivalAddOrders[tradePairKey] = append(orders, order)
+       orders = append(orders, order)
+       o.arrivalAddOrders.Store(tradePairKey, orders)
        return nil
 }
 
 // PeekOrder return the next lowest order of given trade pair
 func (o *OrderBook) PeekOrder(tradePair *common.TradePair) *common.Order {
-       if len(o.dbOrders[tradePair.Key()]) == 0 {
+       if len(o.getDBOrders(tradePair.Key())) == 0 {
                o.extendDBOrders(tradePair)
        }
 
        var nextOrder *common.Order
-       orders := o.dbOrders[tradePair.Key()]
+       orders := o.getDBOrders(tradePair.Key())
        if len(orders) != 0 {
                nextOrder = orders[len(orders)-1]
        }
 
-       if nextOrder != nil && o.arrivalDelOrders[nextOrder.Key()] != nil {
-               o.dbOrders[tradePair.Key()] = orders[0 : len(orders)-1]
+       if nextOrder != nil && o.getArrivalDelOrders(nextOrder.Key()) != nil {
+               o.dbOrders.Store(tradePair.Key(), orders[0:len(orders)-1])
                return o.PeekOrder(tradePair)
        }
 
        arrivalOrder := o.peekArrivalOrder(tradePair)
-       if nextOrder == nil || (arrivalOrder != nil && arrivalOrder.Rate() < nextOrder.Rate()) {
+       if nextOrder == nil || (arrivalOrder != nil && arrivalOrder.Cmp(nextOrder) < 0) {
                nextOrder = arrivalOrder
        }
        return nextOrder
@@ -91,14 +93,14 @@ func (o *OrderBook) PopOrder(tradePair *common.TradePair) {
                return
        }
 
-       orders := o.dbOrders[tradePair.Key()]
+       orders := o.getDBOrders(tradePair.Key())
        if len(orders) != 0 && orders[len(orders)-1].Key() == order.Key() {
-               o.dbOrders[tradePair.Key()] = orders[0 : len(orders)-1]
+               o.dbOrders.Store(tradePair.Key(), orders[0 : len(orders)-1])
        }
 
-       arrivalOrders := o.arrivalAddOrders[tradePair.Key()]
+       arrivalOrders := o.getArrivalAddOrders(tradePair.Key())
        if len(arrivalOrders) != 0 && arrivalOrders[len(arrivalOrders)-1].Key() == order.Key() {
-               o.arrivalAddOrders[tradePair.Key()] = arrivalOrders[0 : len(arrivalOrders)-1]
+               o.arrivalAddOrders.Store(tradePair.Key(), arrivalOrders[0 : len(arrivalOrders)-1])
        }
 }
 
@@ -111,41 +113,67 @@ func (o *OrderBook) PopOrders(tradePairs []*common.TradePair) []*common.Order {
        return orders
 }
 
-func arrangeArrivalAddOrders(orders []*common.Order) map[string][]*common.Order {
-       arrivalAddOrderMap := make(map[string][]*common.Order)
+func (o *OrderBook) getDBOrders(tradePairKey string) []*common.Order {
+       if orders, ok := o.dbOrders.Load(tradePairKey); ok {
+               return orders.([]*common.Order)
+       }
+       return []*common.Order{}
+}
+
+func (o *OrderBook) getArrivalAddOrders(tradePairKey string) []*common.Order {
+       if orders, ok := o.arrivalAddOrders.Load(tradePairKey); ok {
+               return orders.([]*common.Order)
+       }
+       return []*common.Order{}
+}
+
+func (o *OrderBook) getArrivalDelOrders(orderKey string) *common.Order {
+       if order, ok := o.arrivalDelOrders.Load(orderKey); ok {
+               return order.(*common.Order)
+       }
+       return nil
+}
+
+func arrangeArrivalAddOrders(orders []*common.Order) *sync.Map {
+       orderMap := make(map[string][]*common.Order)
        for _, order := range orders {
-               arrivalAddOrderMap[order.TradePair().Key()] = append(arrivalAddOrderMap[order.TradePair().Key()], order)
+               orderMap[order.TradePair().Key()] = append(orderMap[order.TradePair().Key()], order)
        }
 
-       for _, orders := range arrivalAddOrderMap {
+       arrivalOrderMap := &sync.Map{}
+       for key, orders := range orderMap {
                sort.Sort(sort.Reverse(common.OrderSlice(orders)))
+               arrivalOrderMap.Store(key, orders)
+
        }
-       return arrivalAddOrderMap
+       return arrivalOrderMap
 }
 
-func arrangeArrivalDelOrders(orders []*common.Order) map[string]*common.Order {
-       arrivalDelOrderMap := make(map[string]*common.Order)
+func arrangeArrivalDelOrders(orders []*common.Order) *sync.Map {
+       arrivalDelOrderMap := &sync.Map{}
        for _, order := range orders {
-               arrivalDelOrderMap[order.Key()] = order
+               arrivalDelOrderMap.Store(order.Key(), order)
        }
        return arrivalDelOrderMap
 }
 
 func (o *OrderBook) extendDBOrders(tradePair *common.TradePair) {
-       iterator, ok := o.orderIterators[tradePair.Key()]
+       iterator, ok := o.orderIterators.Load(tradePair.Key())
        if !ok {
                iterator = database.NewOrderIterator(o.movStore, tradePair)
-               o.orderIterators[tradePair.Key()] = iterator
+               o.orderIterators.Store(tradePair.Key(), iterator)
        }
 
-       nextOrders := iterator.NextBatch()
+       nextOrders := iterator.(*database.OrderIterator).NextBatch()
+       orders := o.getDBOrders(tradePair.Key())
        for i := len(nextOrders) - 1; i >= 0; i-- {
-               o.dbOrders[tradePair.Key()] = append(o.dbOrders[tradePair.Key()], nextOrders[i])
+               orders = append(orders, nextOrders[i])
        }
+       o.dbOrders.Store(tradePair.Key(), orders)
 }
 
 func (o *OrderBook) peekArrivalOrder(tradePair *common.TradePair) *common.Order {
-       if arrivalAddOrders := o.arrivalAddOrders[tradePair.Key()]; len(arrivalAddOrders) > 0 {
+       if arrivalAddOrders := o.getArrivalAddOrders(tradePair.Key()); len(arrivalAddOrders) > 0 {
                return arrivalAddOrders[len(arrivalAddOrders)-1]
        }
        return nil