decred.org/dcrdex@v1.0.5/server/market/epoch.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package market
     5  
     6  import (
     7  	"time"
     8  
     9  	"decred.org/dcrdex/dex/order"
    10  	"decred.org/dcrdex/server/account"
    11  )
    12  
    13  // EpochQueue represents an epoch order queue. The methods are NOT thread safe
    14  // by design.
    15  type EpochQueue struct {
    16  	// Epoch is the epoch index.
    17  	Epoch    int64
    18  	Duration int64
    19  	// Start and End define the time range of the epoch as [Start,End).
    20  	Start, End time.Time
    21  	// Orders holds the epoch queue orders in a map for quick lookups.
    22  	Orders map[order.OrderID]order.Order
    23  	// UserCancels counts the number of cancel orders per user.
    24  	UserCancels map[account.AccountID]uint32
    25  	// CancelTargets maps known targeted order IDs with the CancelOrder
    26  	CancelTargets map[order.OrderID]*order.CancelOrder
    27  }
    28  
    29  // NewEpoch creates an epoch with the given index and duration in milliseconds.
    30  func NewEpoch(idx int64, duration int64) *EpochQueue {
    31  	startTime := time.UnixMilli(idx * duration)
    32  	return &EpochQueue{
    33  		Epoch:         idx,
    34  		Duration:      duration,
    35  		Start:         startTime,
    36  		End:           startTime.Add(time.Duration(duration) * time.Millisecond),
    37  		Orders:        make(map[order.OrderID]order.Order),
    38  		UserCancels:   make(map[account.AccountID]uint32),
    39  		CancelTargets: make(map[order.OrderID]*order.CancelOrder),
    40  	}
    41  }
    42  
    43  // OrderSlice extracts the orders in a slice. The slice ordering is random.
    44  func (eq *EpochQueue) OrderSlice() []order.Order {
    45  	orders := make([]order.Order, 0, len(eq.Orders))
    46  	for _, ord := range eq.Orders {
    47  		orders = append(orders, ord)
    48  	}
    49  	return orders
    50  }
    51  
    52  // Stores an order in the Order slice, overwriting and pre-existing order.
    53  func (eq *EpochQueue) Insert(ord order.Order) {
    54  	eq.Orders[ord.ID()] = ord
    55  	if co, ok := ord.(*order.CancelOrder); ok {
    56  		eq.CancelTargets[co.TargetOrderID] = co
    57  		eq.UserCancels[co.AccountID]++
    58  	}
    59  }
    60  
    61  // IncludesTime checks if the given time falls in the epoch.
    62  func (eq *EpochQueue) IncludesTime(t time.Time) bool {
    63  	// [Start,End): Check the inclusive lower bound.
    64  	if t.Equal(eq.Start) {
    65  		return true
    66  	}
    67  	// Check (Start,End).
    68  	return t.After(eq.Start) && t.Before(eq.End)
    69  }