mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-18 07:26:50 +00:00
stream/buffer: Reduces map lookups by using key struct (#1309)
* stream/buffer: Adds key map optimisation (cherry-pick) * stream/buffer: Add buffer to DataHandler intermediary. Add field InitialUpdate bool to toggle when first update is seen for initial sync. * whoops * buffer: Add difference benchmarks for reference * glorious: nits (reverting out of context changes) * RM unused error that will be used later * purge: benchmark --------- Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
This commit is contained in:
@@ -60,7 +60,7 @@ func (w *Orderbook) Setup(exchangeConfig *config.Exchange, c *Config, dataHandle
|
||||
w.updateEntriesByID = c.UpdateEntriesByID
|
||||
w.exchangeName = exchangeConfig.Name
|
||||
w.dataHandler = dataHandler
|
||||
w.ob = make(map[currency.Code]map[currency.Code]map[asset.Item]*orderbookHolder)
|
||||
w.ob = make(map[Key]*orderbookHolder)
|
||||
w.verbose = exchangeConfig.Verbose
|
||||
|
||||
// set default publish period if missing
|
||||
@@ -91,9 +91,9 @@ func (w *Orderbook) Update(u *orderbook.Update) error {
|
||||
if err := w.validate(u); err != nil {
|
||||
return err
|
||||
}
|
||||
w.m.Lock()
|
||||
defer w.m.Unlock()
|
||||
book, ok := w.ob[u.Pair.Base][u.Pair.Quote][u.Asset]
|
||||
w.mtx.Lock()
|
||||
defer w.mtx.Unlock()
|
||||
book, ok := w.ob[Key{Base: u.Pair.Base.Item, Quote: u.Pair.Quote.Item, Asset: u.Asset}]
|
||||
if !ok {
|
||||
return fmt.Errorf("%w for Exchange %s CurrencyPair: %s AssetType: %s",
|
||||
errDepthNotFound,
|
||||
@@ -306,19 +306,9 @@ func (w *Orderbook) LoadSnapshot(book *orderbook.Base) error {
|
||||
return err
|
||||
}
|
||||
|
||||
w.m.Lock()
|
||||
defer w.m.Unlock()
|
||||
m1, ok := w.ob[book.Pair.Base]
|
||||
if !ok {
|
||||
m1 = make(map[currency.Code]map[asset.Item]*orderbookHolder)
|
||||
w.ob[book.Pair.Base] = m1
|
||||
}
|
||||
m2, ok := m1[book.Pair.Quote]
|
||||
if !ok {
|
||||
m2 = make(map[asset.Item]*orderbookHolder)
|
||||
m1[book.Pair.Quote] = m2
|
||||
}
|
||||
holder, ok := m2[book.Asset]
|
||||
w.mtx.Lock()
|
||||
defer w.mtx.Unlock()
|
||||
holder, ok := w.ob[Key{Base: book.Pair.Base.Item, Quote: book.Pair.Quote.Item, Asset: book.Asset}]
|
||||
if !ok {
|
||||
// Associate orderbook pointer with local exchange depth map
|
||||
var depth *orderbook.Depth
|
||||
@@ -333,16 +323,11 @@ func (w *Orderbook) LoadSnapshot(book *orderbook.Base) error {
|
||||
if w.publishPeriod != 0 {
|
||||
ticker = time.NewTicker(w.publishPeriod)
|
||||
}
|
||||
holder = &orderbookHolder{
|
||||
ob: depth,
|
||||
buffer: &buffer,
|
||||
ticker: ticker,
|
||||
}
|
||||
m2[book.Asset] = holder
|
||||
holder = &orderbookHolder{ob: depth, buffer: &buffer, ticker: ticker}
|
||||
w.ob[Key{Base: book.Pair.Base.Item, Quote: book.Pair.Quote.Item, Asset: book.Asset}] = holder
|
||||
}
|
||||
|
||||
holder.updateID = book.LastUpdateID
|
||||
|
||||
holder.ob.LoadSnapshot(book.Bids,
|
||||
book.Asks,
|
||||
book.LastUpdateID,
|
||||
@@ -370,15 +355,11 @@ func (w *Orderbook) LoadSnapshot(book *orderbook.Base) error {
|
||||
|
||||
// GetOrderbook returns an orderbook copy as orderbook.Base
|
||||
func (w *Orderbook) GetOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error) {
|
||||
w.m.Lock()
|
||||
defer w.m.Unlock()
|
||||
book, ok := w.ob[p.Base][p.Quote][a]
|
||||
w.mtx.Lock()
|
||||
defer w.mtx.Unlock()
|
||||
book, ok := w.ob[Key{Base: p.Base.Item, Quote: p.Quote.Item, Asset: a}]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%s %s %s %w",
|
||||
w.exchangeName,
|
||||
p,
|
||||
a,
|
||||
errDepthNotFound)
|
||||
return nil, fmt.Errorf("%s %s %s %w", w.exchangeName, p, a, errDepthNotFound)
|
||||
}
|
||||
return book.ob.Retrieve()
|
||||
}
|
||||
@@ -386,16 +367,16 @@ func (w *Orderbook) GetOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base
|
||||
// FlushBuffer flushes w.ob data to be garbage collected and refreshed when a
|
||||
// connection is lost and reconnected
|
||||
func (w *Orderbook) FlushBuffer() {
|
||||
w.m.Lock()
|
||||
w.ob = make(map[currency.Code]map[currency.Code]map[asset.Item]*orderbookHolder)
|
||||
w.m.Unlock()
|
||||
w.mtx.Lock()
|
||||
w.ob = make(map[Key]*orderbookHolder)
|
||||
w.mtx.Unlock()
|
||||
}
|
||||
|
||||
// FlushOrderbook flushes independent orderbook
|
||||
func (w *Orderbook) FlushOrderbook(p currency.Pair, a asset.Item) error {
|
||||
w.m.Lock()
|
||||
defer w.m.Unlock()
|
||||
book, ok := w.ob[p.Base][p.Quote][a]
|
||||
w.mtx.Lock()
|
||||
defer w.mtx.Unlock()
|
||||
book, ok := w.ob[Key{Base: p.Base.Item, Quote: p.Quote.Item, Asset: a}]
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot flush orderbook %s %s %s %w",
|
||||
w.exchangeName,
|
||||
|
||||
Reference in New Issue
Block a user