-
Notifications
You must be signed in to change notification settings - Fork 0
/
bookmap.h
54 lines (50 loc) · 1.84 KB
/
bookmap.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#pragma once
#include <stdexcept>
#include <cstddef>
#include <atomic>
#include "orderbook.h"
#define MAX_INSTRUMENTS 1024
/** Book is a lock-free map of instrument -> OrderBook */
class BookMap {
std::atomic<OrderBook*> table[MAX_INSTRUMENTS];
public:
BookMap() {
for(int i=0;i<MAX_INSTRUMENTS;i++) table[i].store(nullptr);
}
OrderBook* getOrCreate(const std::string &instrument,OrderBookListener &listener) {
auto hash = std::hash<std::string>{}(instrument);
const auto start = hash%MAX_INSTRUMENTS;
auto book = table[start].load();
if(book!=nullptr && book->instrument==instrument) return book;
auto new_book = new OrderBook(instrument,listener);
auto index = start;
while(true) {
if(book!=nullptr) {
index = (index + 1) % MAX_INSTRUMENTS;
if(index==start) throw new std::runtime_error("no room in books map");
book = table[index].load();
if(book!=nullptr && book->instrument==instrument) return book;
}
if(book==nullptr) {
OrderBook* tmp = nullptr;
if(table[index].compare_exchange_strong(tmp,new_book)) return new_book;
if(tmp->instrument==instrument) {
delete(new_book);
return tmp;
}
}
}
};
OrderBook* get(const std::string &instrument) {
auto hash = std::hash<std::string>{}(instrument);
const auto start = hash%MAX_INSTRUMENTS;
auto index = start;
while(true) {
auto book = table[index].load();
if(book==nullptr) return nullptr;
if(book->instrument==instrument) return book;
index = (index + 1) % MAX_INSTRUMENTS;
if(index==start) return nullptr;
}
}
};