Skip to content
Permalink
Browse files

Update tree size for ordertree

  • Loading branch information...
tubackkhoa committed Jan 17, 2019
1 parent 28dbe3e commit 8718c78d3366bcc3499a39c2809a8edead1c491a
@@ -196,6 +196,7 @@ func EncodeBytesOrderListItem(item *OrderListItem) ([]byte, error) {
func DecodeBytesOrderListItem(bytes []byte, item *OrderListItem) error {
// try with OrderItem
start := 0
// make it crash it wrong format, no need to check length
totalLength := len(bytes)

if item.Volume == nil {
@@ -240,7 +241,7 @@ func EncodeBytesOrderTreeItem(item *OrderTreeItem) ([]byte, error) {
start := 1 * common.HashLength
totalLength := start + 1*common.HashLength // PriceTreeKey
// uint64 is 8 byte
totalLength += 8 * 2 // NumOrders and Depth
totalLength += 8 * 3 // NumOrders, Depth and PriceTreeSize

returnBytes := make([]byte, totalLength)

@@ -255,13 +256,17 @@ func EncodeBytesOrderTreeItem(item *OrderTreeItem) ([]byte, error) {
start += 8

binary.BigEndian.PutUint64(returnBytes[start:start+8], item.Depth)
start += 8

binary.BigEndian.PutUint64(returnBytes[start:start+8], item.PriceTreeSize)

return returnBytes, nil
}

func DecodeBytesOrderTreeItem(bytes []byte, item *OrderTreeItem) error {
// try with OrderItem
start := 0
// make it crash it wrong format, no need to check length
totalLength := len(bytes)

if item.Volume == nil {
@@ -281,9 +286,12 @@ func DecodeBytesOrderTreeItem(bytes []byte, item *OrderTreeItem) error {
item.NumOrders = binary.BigEndian.Uint64(bytes[start : start+8])
start += 8

item.Depth = binary.BigEndian.Uint64(bytes[start : start+8])
start += 8

// may have wrong format, just get next 8 bytes
if start+8 <= totalLength {
item.Depth = binary.BigEndian.Uint64(bytes[start : start+8])
item.PriceTreeSize = binary.BigEndian.Uint64(bytes[start : start+8])
}

// fmt.Printf("Item : %d, %d\n", start+8, totalLength)
@@ -3,14 +3,15 @@ package orderbook
var datadir = "../datadir/testing"

// var datadir = "../../.data_30100/orderbook/"
// orderbook for this pair
var pairName = "TOMO/WETH"

// override Encode and Decode for better performance
var testDB = NewBatchDatabaseWithEncode(datadir, 0, 0, EncodeBytesItem, DecodeBytesItem)
var testOrderBook = NewOrderBook(pairName, testDB)

var testOrderTree = NewOrderTree(testDB, []byte("ordertree"))

// orderbook for this pair
var pairName = "TOMO/WETH"
// order tree without orderbook
var testOrderTree = NewOrderTree(testDB, []byte("ordertree"), testOrderBook)

var testTimestamp uint64 = 123452342343
var testQuanity = ToBigInt("1000")
@@ -81,10 +81,8 @@ func NewOrderBook(name string, db *BatchDatabase) *OrderBook {
Key: key,
}

bids := NewOrderTree(db, bidsKey)
asks := NewOrderTree(db, asksKey)
bids.orderBook = orderBook
asks.orderBook = orderBook
bids := NewOrderTree(db, bidsKey, orderBook)
asks := NewOrderTree(db, asksKey, orderBook)

// set asks and bids
orderBook.Bids = bids
@@ -5,7 +5,7 @@ import (
)

func TestNewOrderBook(t *testing.T) {
orderBook := NewOrderBook(pairName, testDB)
orderBook := testOrderBook
// // try to restore before next operation
// orderBook.Restore()

@@ -31,7 +31,7 @@ func TestNewOrderBook(t *testing.T) {
}

func TestOrderBook(t *testing.T) {
orderBook := NewOrderBook(pairName, testDB)
orderBook := testOrderBook
orderBook.Restore()

limitOrders := make([]map[string]string, 0)
@@ -152,11 +152,13 @@ func TestOrderBook(t *testing.T) {

trades, orderInBook = orderBook.ProcessOrder(marketOrder, true)

tradedPrice := trades[0]["price"]
tradedQuantity := trades[0]["quantity"]
if len(trades) > 0 {
tradedPrice := trades[0]["price"]
tradedQuantity := trades[0]["quantity"]

if !(tradedPrice == "101" && tradedQuantity == "2" && len(orderInBook) == 0) {
t.Errorf("orderBook.ProcessOrder incorrect")
if !(tradedPrice == "101" && tradedQuantity == "2" && len(orderInBook) == 0) {
t.Errorf("orderBook.ProcessOrder incorrect")
}
}

// t.Logf("\nOrderBook :%s", orderBook.String(0))
@@ -207,7 +209,7 @@ func TestOrderBook(t *testing.T) {
}

func TestOrderBookRestore(t *testing.T) {
orderBook := NewOrderBook(pairName, testDB)
orderBook := testOrderBook
orderBook.SetDebug(true)

orderBook.Restore()
@@ -89,6 +89,7 @@ func NewOrderListWithItem(item *OrderListItem, orderTree *OrderTree) *OrderList
func (orderList *OrderList) GetOrder(key []byte) *Order {
// re-use method from orderbook, because orderlist has the same slot as orderbook
return orderList.orderTree.orderBook.GetOrder(key)

// if orderList.isEmptyKey(key) {
// return nil
// }
@@ -1,6 +1,7 @@
package orderbook

import (
"math/big"
"strconv"
"testing"
)
@@ -35,48 +36,48 @@ func TestOrderList(t *testing.T) {
order := NewOrder(dummyOrder, orderList.Key)
orderList.AppendOrder(order)

// if !(orderList.Item.Length == 1) {
// t.Errorf("Orderlist Length incorrect, got: %d, want: %d.", orderList.Item.Length, 1)
// }
if !(orderList.Item.Length == 1) {
t.Errorf("Orderlist Length incorrect, got: %d, want: %d.", orderList.Item.Length, 1)
}

// if orderList.Item.Price.Cmp(testPrice) != 0 {
// t.Errorf("Orderlist price incorrect, got: %d, want: %d.", orderList.Item.Price, testPrice)
// }
if orderList.Item.Price.Cmp(testPrice) != 0 {
t.Errorf("Orderlist price incorrect, got: %d, want: %d.", orderList.Item.Price, testPrice)
}

// if orderList.Item.Volume.Cmp(order.Item.Quantity) != 0 {
// t.Errorf("Orderlist volume incorrect, got: %d, want: %d.", orderList.Item.Volume, order.Item.Quantity)
// }
if orderList.Item.Volume.Cmp(order.Item.Quantity) != 0 {
t.Errorf("Orderlist volume incorrect, got: %d, want: %d.", orderList.Item.Volume, order.Item.Quantity)
}

// dummyOrder1 := make(map[string]string)
// dummyOrder1["timestamp"] = strconv.FormatUint(testTimestamp1, 10)
// dummyOrder1["quantity"] = testQuanity1.String()
// dummyOrder1["price"] = testPrice1.String()
// dummyOrder1["order_id"] = strconv.Itoa(testOrderID1)
// dummyOrder1["trade_id"] = strconv.Itoa(testTradeID1)
dummyOrder1 := make(map[string]string)
dummyOrder1["timestamp"] = strconv.FormatUint(testTimestamp1, 10)
dummyOrder1["quantity"] = testQuanity1.String()
dummyOrder1["price"] = testPrice1.String()
dummyOrder1["order_id"] = strconv.Itoa(testOrderID1)
dummyOrder1["trade_id"] = strconv.Itoa(testTradeID1)

// order1 := NewOrder(dummyOrder1, orderList.Key)
// orderList.AppendOrder(order1)
order1 := NewOrder(dummyOrder1, orderList.Key)
orderList.AppendOrder(order1)

// if !(orderList.Item.Length == 2) {
// t.Errorf("Orderlist Length incorrect, got: %d, want: %d.", orderList.Item.Length, 2)
// }
if !(orderList.Item.Length == 2) {
t.Errorf("Orderlist Length incorrect, got: %d, want: %d.", orderList.Item.Length, 2)
}

// orderListQuantity := Add(order.Item.Quantity, order1.Item.Quantity)
// if orderList.Item.Volume.Cmp(orderListQuantity) != 0 {
// t.Errorf("Orderlist Length incorrect, got: %d, want: %d.", orderList.Item.Volume, orderListQuantity)
// }
orderListQuantity := Add(order.Item.Quantity, order1.Item.Quantity)
if orderList.Item.Volume.Cmp(orderListQuantity) != 0 {
t.Errorf("Orderlist Length incorrect, got: %d, want: %d.", orderList.Item.Volume, orderListQuantity)
}

// // headOrder := orderList.GetOrder(orderList.Item.HeadOrder)
headOrder := orderList.GetOrder(orderList.Item.HeadOrder)

// // if !IsEqual(new(big.Int).SetBytes(headOrder.Key), big.NewInt(1)) {
// // t.Errorf("headorder id incorrect, got: %x, want: %d.", headOrder.Key, big.NewInt(1))
// // }
if !IsEqual(new(big.Int).SetBytes(headOrder.Key), big.NewInt(1)) {
t.Errorf("headorder id incorrect, got: %x, want: %d.", headOrder.Key, big.NewInt(1))
}

// // nextOrder := orderList.GetOrder(headOrder.Item.NextOrder)
nextOrder := orderList.GetOrder(headOrder.Item.NextOrder)

// // if !IsEqual(new(big.Int).SetBytes(nextOrder.Key), big.NewInt(2)) {
// // t.Errorf("Next headorder id incorrect, got: %x, want: %d.", nextOrder.Key, big.NewInt(2))
// // }
if !IsEqual(new(big.Int).SetBytes(nextOrder.Key), big.NewInt(2)) {
t.Errorf("Next headorder id incorrect, got: %x, want: %d.", nextOrder.Key, big.NewInt(2))
}

t.Logf("Order List : %s", orderList.String(0))
}
@@ -9,10 +9,11 @@ import (
)

type OrderTreeItem struct {
Volume *big.Int `json:"volume"` // Contains total quantity from all Orders in tree
NumOrders uint64 `json:"numOrders"` // Contains count of Orders in tree
Depth uint64 `json:"depth"` // Number of different prices in tree (http://en.wikipedia.org/wiki/Order_book_(trading)#Book_depth)
PriceTreeKey []byte `json:"priceTreeKey"` // Root Key of price tree
Volume *big.Int `json:"volume"` // Contains total quantity from all Orders in tree
NumOrders uint64 `json:"numOrders"` // Contains count of Orders in tree
Depth uint64 `json:"depth"` // Number of different prices in tree (http://en.wikipedia.org/wiki/Order_book_(trading)#Book_depth)
PriceTreeKey []byte `json:"priceTreeKey"` // Root Key of price tree
PriceTreeSize uint64 `json:"priceTreeSize"` // Number of nodes
}

// OrderTree : order tree structure for travelling
@@ -30,7 +31,7 @@ type OrderTree struct {
}

// NewOrderTree create new order tree
func NewOrderTree(orderDB *BatchDatabase, key []byte) *OrderTree {
func NewOrderTree(orderDB *BatchDatabase, key []byte, orderBook *OrderBook) *OrderTree {
// create priceTree from db for order list
// orderListDBPath := path.Join(datadir, "pricetree")
// orderDBPath := path.Join(datadir, "order")
@@ -55,6 +56,7 @@ func NewOrderTree(orderDB *BatchDatabase, key []byte) *OrderTree {
Key: key,
slot: slot,
Item: item,
orderBook: orderBook,
// orderListCache: itemCache,
}

@@ -79,10 +81,11 @@ func (orderTree *OrderTree) Save() error {
// commit tree changes
// orderTree.PriceTree.Commit()

// update tree meta information
// update tree meta information, make sure item existed instead of checking rootKey
priceTreeRoot := orderTree.PriceTree.Root()
if priceTreeRoot != nil {
orderTree.Item.PriceTreeKey = priceTreeRoot.Key
orderTree.Item.PriceTreeSize = orderTree.PriceTree.Size()
}

// using rlp.EncodeToBytes as underlying encode method
@@ -99,6 +102,15 @@ func (orderTree *OrderTree) Save() error {
// return orderTree.OrderDB.Put(OrderTreeKey, ordertreeBytes)
}

// save this tree information then do database commit
func (orderTree *OrderTree) Commit() error {
err := orderTree.Save()
if err == nil {
err = orderTree.orderDB.Commit()
}
return err
}

func (orderTree *OrderTree) Restore() error {
// val.(*OrderTreeItem)
val, err := orderTree.orderDB.Get(orderTree.Key, orderTree.Item)
@@ -110,17 +122,17 @@ func (orderTree *OrderTree) Restore() error {
orderTree.Item = val.(*OrderTreeItem)

// update root key for pricetree
orderTree.PriceTree.SetRootKey(orderTree.Item.PriceTreeKey)
orderTree.PriceTree.SetRootKey(orderTree.Item.PriceTreeKey, orderTree.Item.PriceTreeSize)
}

return err
}

func (orderTree *OrderTree) String(startDepth int) string {
tabs := strings.Repeat("\t", startDepth)
return fmt.Sprintf("{\n\t%sMinPriceList: %s\n\t%sMaxPriceList: %s\n\t%sVolume: %v\n\t%sNumOrders: %d\n\t%sDepth: %d\n%s}",
return fmt.Sprintf("{\n\t%sMinPriceList: %s\n\t%sMaxPriceList: %s\n\t%sVolume: %v\n\t%sNumOrders: %d\n\t%sDepth: %d\n\t%sTreeSize: %d\n%s}",
tabs, orderTree.MinPriceList().String(startDepth+1), tabs, orderTree.MaxPriceList().String(startDepth+1), tabs,
orderTree.Item.Volume, tabs, orderTree.Item.NumOrders, tabs, orderTree.Item.Depth, tabs)
orderTree.Item.Volume, tabs, orderTree.Item.NumOrders, tabs, orderTree.Item.Depth, tabs, orderTree.Item.PriceTreeSize, tabs)
}

func (orderTree *OrderTree) Length() uint64 {
Oops, something went wrong.

0 comments on commit 8718c78

Please sign in to comment.
You can’t perform that action at this time.