Skip to content

Commit

Permalink
feat(db): update leveldb and rocksdb for arm
Browse files Browse the repository at this point in the history
  • Loading branch information
halibobo1205 committed Nov 8, 2024
1 parent c136a26 commit fed7b0e
Show file tree
Hide file tree
Showing 26 changed files with 616 additions and 262 deletions.
47 changes: 47 additions & 0 deletions arch/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import org.gradle.nativeplatform.platform.internal.Architectures

description = "arch – a distributed consensus arithmetic for blockchain."


static def isX86() {
def arch = System.getProperty("os.arch").toLowerCase()
return Architectures.X86_64.isAlias(arch) || Architectures.X86.isAlias(arch)
}

if (isX86()) {
ext {
leveldbGroup = "org.fusesource.leveldbjni"
leveldbName = "leveldbjni-all"
leveldbVersion = "1.8"
rocksDBVersion = "5.15.10"
}
} else {
ext {
leveldbGroup = "com.halibobor"
leveldbName = "leveldbjni-all"
leveldbVersion = "1.18.3"
rocksDBVersion = "7.7.3"
}
}

sourceSets {
x86 {
java {
srcDir 'src/main/java/x86'
}
}
arm {
java {
srcDir 'src/main/java/arm'
}
}
}

dependencies {
api group: leveldbGroup, name: leveldbName, version: leveldbVersion
api group: 'org.rocksdb', name: 'rocksdbjni', version: rocksDBVersion
}

tasks.withType(JavaCompile).configureEach {
source = isX86() ? sourceSets.x86.java : sourceSets.arm.java
}
124 changes: 124 additions & 0 deletions arch/src/main/java/arm/org/tron/common/utils/MarketComparator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package org.tron.common.utils;

import java.math.BigInteger;

public class MarketComparator {

public static final int TOKEN_ID_LENGTH = Long.toString(Long.MAX_VALUE).getBytes().length; // 19


public static int comparePriceKey(byte[] o1, byte[] o2) {
//compare pair
byte[] pair1 = new byte[TOKEN_ID_LENGTH * 2];
byte[] pair2 = new byte[TOKEN_ID_LENGTH * 2];

System.arraycopy(o1, 0, pair1, 0, TOKEN_ID_LENGTH * 2);
System.arraycopy(o2, 0, pair2, 0, TOKEN_ID_LENGTH * 2);

int pairResult = compareUnsigned(pair1, pair2);
if (pairResult != 0) {
return pairResult;
}

//compare price
byte[] getSellTokenQuantity1 = new byte[8];
byte[] getBuyTokenQuantity1 = new byte[8];

byte[] getSellTokenQuantity2 = new byte[8];
byte[] getBuyTokenQuantity2 = new byte[8];

int longByteNum = 8;

System.arraycopy(o1, TOKEN_ID_LENGTH + TOKEN_ID_LENGTH,
getSellTokenQuantity1, 0, longByteNum);
System.arraycopy(o1, TOKEN_ID_LENGTH + TOKEN_ID_LENGTH + longByteNum,
getBuyTokenQuantity1, 0, longByteNum);

System.arraycopy(o2, TOKEN_ID_LENGTH + TOKEN_ID_LENGTH,
getSellTokenQuantity2, 0, longByteNum);
System.arraycopy(o2, TOKEN_ID_LENGTH + TOKEN_ID_LENGTH + longByteNum,
getBuyTokenQuantity2, 0, longByteNum);

long sellTokenQuantity1 = toLong(getSellTokenQuantity1);
long buyTokenQuantity1 = toLong(getBuyTokenQuantity1);
long sellTokenQuantity2 = toLong(getSellTokenQuantity2);
long buyTokenQuantity2 = toLong(getBuyTokenQuantity2);

if ((sellTokenQuantity1 == 0 || buyTokenQuantity1 == 0)
&& (sellTokenQuantity2 == 0 || buyTokenQuantity2 == 0)) {
return 0;
}

if (sellTokenQuantity1 == 0 || buyTokenQuantity1 == 0) {
return -1;
}

if (sellTokenQuantity2 == 0 || buyTokenQuantity2 == 0) {
return 1;
}

return comparePrice(sellTokenQuantity1, buyTokenQuantity1,
sellTokenQuantity2, buyTokenQuantity2);

}

/**
* Note: the params should be the same token pair, or you should change the order.
* All the quantity should be bigger than 0.
* */
public static int comparePrice(long price1SellQuantity, long price1BuyQuantity,
long price2SellQuantity, long price2BuyQuantity) {
try {
return Long.compare(Math.multiplyExact(price1BuyQuantity, price2SellQuantity),
Math.multiplyExact(price2BuyQuantity, price1SellQuantity));

} catch (ArithmeticException ex) {
// do nothing here, because we will use BigInteger to compute again
}

BigInteger price1BuyQuantityBI = BigInteger.valueOf(price1BuyQuantity);
BigInteger price1SellQuantityBI = BigInteger.valueOf(price1SellQuantity);
BigInteger price2BuyQuantityBI = BigInteger.valueOf(price2BuyQuantity);
BigInteger price2SellQuantityBI = BigInteger.valueOf(price2SellQuantity);

return price1BuyQuantityBI.multiply(price2SellQuantityBI)
.compareTo(price2BuyQuantityBI.multiply(price1SellQuantityBI));
}

/**
* copy from org.bouncycastle.util.Arrays.compareUnsigned
*/
private static int compareUnsigned(byte[] a, byte[] b) {
if (a == b) {
return 0;
}
if (a == null) {
return -1;
}
if (b == null) {
return 1;
}
int minLen = Math.min(a.length, b.length);
for (int i = 0; i < minLen; ++i) {
int aVal = a[i] & 0xFF;
int bVal = b[i] & 0xFF;
if (aVal < bVal) {
return -1;
}
if (aVal > bVal) {
return 1;
}
}
if (a.length < b.length) {
return -1;
}
if (a.length > b.length) {
return 1;
}
return 0;
}

public static long toLong(byte[] b) {
return (b == null || b.length == 0) ? 0 : new BigInteger(1, b).longValue();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.tron.common.utils;

import org.tron.core.capsule.utils.MarketUtils;

public class MarketOrderPriceComparatorForLevelDB implements org.iq80.leveldb.DBComparator {

@Override
Expand All @@ -26,7 +24,7 @@ public byte[] findShortSuccessor(byte[] key) {
*/
@Override
public int compare(byte[] o1, byte[] o2) {
return MarketUtils.comparePriceKey(o1, o2);
return MarketComparator.comparePriceKey(o1, o2);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.tron.common.utils;

import java.nio.ByteBuffer;
import org.rocksdb.AbstractComparator;
import org.rocksdb.ComparatorOptions;

public class MarketOrderPriceComparatorForRocksDB extends AbstractComparator {

public MarketOrderPriceComparatorForRocksDB(final ComparatorOptions copt) {
super(copt);
}

@Override
public String name() {
return "MarketOrderPriceComparator";
}

@Override
public int compare(final ByteBuffer a, final ByteBuffer b) {
return MarketComparator.comparePriceKey(convertDataToBytes(a), convertDataToBytes(b));
}

/**
* DirectSlice.data().array will throw UnsupportedOperationException.
* */
public byte[] convertDataToBytes(ByteBuffer buf) {
byte[] bytes = new byte[buf.remaining()];
buf.get(bytes);
return bytes;
}

}
124 changes: 124 additions & 0 deletions arch/src/main/java/x86/org/tron/common/utils/MarketComparator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package org.tron.common.utils;

import java.math.BigInteger;

public class MarketComparator {

public static final int TOKEN_ID_LENGTH = Long.toString(Long.MAX_VALUE).getBytes().length; // 19


public static int comparePriceKey(byte[] o1, byte[] o2) {
//compare pair
byte[] pair1 = new byte[TOKEN_ID_LENGTH * 2];
byte[] pair2 = new byte[TOKEN_ID_LENGTH * 2];

System.arraycopy(o1, 0, pair1, 0, TOKEN_ID_LENGTH * 2);
System.arraycopy(o2, 0, pair2, 0, TOKEN_ID_LENGTH * 2);

int pairResult = compareUnsigned(pair1, pair2);
if (pairResult != 0) {
return pairResult;
}

//compare price
byte[] getSellTokenQuantity1 = new byte[8];
byte[] getBuyTokenQuantity1 = new byte[8];

byte[] getSellTokenQuantity2 = new byte[8];
byte[] getBuyTokenQuantity2 = new byte[8];

int longByteNum = 8;

System.arraycopy(o1, TOKEN_ID_LENGTH + TOKEN_ID_LENGTH,
getSellTokenQuantity1, 0, longByteNum);
System.arraycopy(o1, TOKEN_ID_LENGTH + TOKEN_ID_LENGTH + longByteNum,
getBuyTokenQuantity1, 0, longByteNum);

System.arraycopy(o2, TOKEN_ID_LENGTH + TOKEN_ID_LENGTH,
getSellTokenQuantity2, 0, longByteNum);
System.arraycopy(o2, TOKEN_ID_LENGTH + TOKEN_ID_LENGTH + longByteNum,
getBuyTokenQuantity2, 0, longByteNum);

long sellTokenQuantity1 = toLong(getSellTokenQuantity1);
long buyTokenQuantity1 = toLong(getBuyTokenQuantity1);
long sellTokenQuantity2 = toLong(getSellTokenQuantity2);
long buyTokenQuantity2 = toLong(getBuyTokenQuantity2);

if ((sellTokenQuantity1 == 0 || buyTokenQuantity1 == 0)
&& (sellTokenQuantity2 == 0 || buyTokenQuantity2 == 0)) {
return 0;
}

if (sellTokenQuantity1 == 0 || buyTokenQuantity1 == 0) {
return -1;
}

if (sellTokenQuantity2 == 0 || buyTokenQuantity2 == 0) {
return 1;
}

return comparePrice(sellTokenQuantity1, buyTokenQuantity1,
sellTokenQuantity2, buyTokenQuantity2);

}

/**
* Note: the params should be the same token pair, or you should change the order.
* All the quantity should be bigger than 0.
* */
public static int comparePrice(long price1SellQuantity, long price1BuyQuantity,
long price2SellQuantity, long price2BuyQuantity) {
try {
return Long.compare(Math.multiplyExact(price1BuyQuantity, price2SellQuantity),
Math.multiplyExact(price2BuyQuantity, price1SellQuantity));

} catch (ArithmeticException ex) {
// do nothing here, because we will use BigInteger to compute again
}

BigInteger price1BuyQuantityBI = BigInteger.valueOf(price1BuyQuantity);
BigInteger price1SellQuantityBI = BigInteger.valueOf(price1SellQuantity);
BigInteger price2BuyQuantityBI = BigInteger.valueOf(price2BuyQuantity);
BigInteger price2SellQuantityBI = BigInteger.valueOf(price2SellQuantity);

return price1BuyQuantityBI.multiply(price2SellQuantityBI)
.compareTo(price2BuyQuantityBI.multiply(price1SellQuantityBI));
}

/**
* copy from org.bouncycastle.util.Arrays.compareUnsigned
*/
private static int compareUnsigned(byte[] a, byte[] b) {
if (a == b) {
return 0;
}
if (a == null) {
return -1;
}
if (b == null) {
return 1;
}
int minLen = Math.min(a.length, b.length);
for (int i = 0; i < minLen; ++i) {
int aVal = a[i] & 0xFF;
int bVal = b[i] & 0xFF;
if (aVal < bVal) {
return -1;
}
if (aVal > bVal) {
return 1;
}
}
if (a.length < b.length) {
return -1;
}
if (a.length > b.length) {
return 1;
}
return 0;
}

public static long toLong(byte[] b) {
return (b == null || b.length == 0) ? 0 : new BigInteger(1, b).longValue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.tron.common.utils;

public class MarketOrderPriceComparatorForLevelDB implements org.iq80.leveldb.DBComparator {

@Override
public String name() {
return "MarketOrderPriceComparator";
}

@Override
public byte[] findShortestSeparator(byte[] start, byte[] limit) {
return new byte[0];
}

@Override
public byte[] findShortSuccessor(byte[] key) {
return new byte[0];
}

/**
* Note, for this compare, we should ensure token and quantity are all bigger than 0. Otherwise,
* when quantity is 0, the result of compare this key with others will be 0, but actually the
* result should be -1.
*/
@Override
public int compare(byte[] o1, byte[] o2) {
return MarketComparator.comparePriceKey(o1, o2);
}

}
Loading

0 comments on commit fed7b0e

Please sign in to comment.