Apart from anything else, directly on the stock exchange a lot of Ha, thank brightest Great God..
.
Focus is the following passage:
Object object = redisTemplate.execute(redisUpdateOrderScript,
//这里有key 要像官网说的那样加个"{}",不然就报错了,这里3个key都要前缀一致
Arrays.asList(hkey, amountKey, key),
//值无要求
amount.longValueExact(),price.doubleValue(),price.doubleValue());
My own understanding is that the implementation and enforcement hget script is the same, but the content lua script executed by Redis, but asked to send commands are the same. Therefore, the above three key plus had the same prefix.
.
.
.
Business logic is like this:
the gear 20 which bets placed Redis
1. ordered set (sorted set) automatically ordering price
ZADD key 0.0354 "0.0354"
2. Then go to the hash value based on price, val is taken at this price Single
HGET key 0.0354
java code
Plus Handicap
public void addOrderForLua(BeforeMatchDTO model) {
//缓存失效
redisService.remove(RedisService.getPositionKey(model.getContract()));
BigDecimal price = model.getPrice();
BigDecimal amount = model.getAmount().multiply(PRECISION_DOUBLE);
String key = RedisKeyGen.getContractPositionZsetKey(model.getContract(), model.getDirection());
log.info("getContractPositionZsetKey:{}",key);
String hkey = RedisKeyGen.getContractPositionHashKey(model.getContract(), model.getDirection());
log.info("getContractPositionHashKey:{}",hkey);
String amountKey = RedisKeyGen.getContractPositionAmountKey(model.getContract(),price.stripTrailingZeros().toPlainString());
log.info("getContractPositionAmountKey:{}",amountKey);
log.info("addOrderForLua contract:{}, value:{}", model.getContract(), amount.longValueExact());
Object object = redisTemplate.execute(redisUpdateOrderScript, Arrays.asList(hkey, amountKey, key), amount.longValueExact(),price.doubleValue(),price.doubleValue());
log.info("addOrderForLua" + object);
}
Less Handicap
public void subOrderForLua(String contract,BigDecimal price,BigDecimal amount,int direction) {
//缓存失效
redisService.remove(RedisService.getPositionKey(contract));
String key = RedisKeyGen.getContractPositionZsetKey(contract, direction);
log.info("getContractPositionZsetKey:{}",key);
String hkey = RedisKeyGen.getContractPositionHashKey(contract, direction);
log.info("getContractPositionHashKey:{}",hkey);
String amountKey = RedisKeyGen.getContractPositionAmountKey(contract,price.stripTrailingZeros().toPlainString());
log.info("getContractPositionAmountKey:{}",amountKey);
log.info("subOrderForLua contract:{}, value:{}", contract, amount.doubleValue());
BigDecimal amountTag = amount.multiply(PRECISION_DOUBLE).negate(); //转成负数
Object nowAmount = redisService.hmGet(hkey, price.toPlainString());
log.info("subOrderForLua nowAmount:{},direction:{}", nowAmount, direction);
Object object = redisTemplate.execute(redisUpdateOrderScript, Arrays.asList(hkey, amountKey, key), amountTag.longValueExact(),price.doubleValue(),price.doubleValue());
log.info("subOrderForLua" + object);
}
Query (Local Key to see the value of the conversion please ignore)
public List<QuotationOrderRsgResp> query(String contract,int direction) {
List<QuotationOrderRsgResp> result = new ArrayList<>();
String key = RedisKeyGen.getContractPositionZsetKey(contract, direction);
log.info("getContractPositionZsetKey:{}",key);
String hkey = RedisKeyGen.getContractPositionHashKey(contract, direction);
log.info("getContractPositionHashKey:{}",hkey);
Set<Object> objectSet = null;
//卖从低到高
if(QuotationConstants.DIRECTION_SELL == direction) {
objectSet = redisService.rangeByIndex(key, 0, 19);
} else {
//买从高到低
objectSet = redisService.reverseRangeByIndex(key, 0, 19);
}
if (objectSet != null && objectSet.size() > 0) {
Integer [] digits = convertService.getContractDigitsForInt(contract);
for (Object obj : objectSet) {
log.info("query class:{},val:{}",obj.getClass(),JSON.toJSONString(obj));
BigDecimal price = new BigDecimal(obj.toString());
String amountKey = RedisKeyGen.getContractPositionAmountKey(contract,price.stripTrailingZeros().toPlainString());
Object object = redisService.hmGet(hkey, amountKey);
log.info("getContractPositionAmountKey hmGet key:{},val:{}",amountKey,object);
BigDecimal valTemp = getBigDecimal(object);
if(valTemp.compareTo(BigDecimal.ZERO) == 0) continue;
BigDecimal val = valTemp.divide(PRECISION_DOUBLE);
QuotationOrderRsgResp resp = new QuotationOrderRsgResp();
resp.setContract(contract);
resp.setDirection(direction);
resp.setPrice(convertService.setScale(price, digits[0]));
resp.setVolume(convertService.setScale(val,digits[1]));
resp.setTotal(convertService.setScale(price.multiply(val),add(digits[0] ,digits[1])));
result.add(resp);
}
} else {
log.info("query redis is null! contract:{},direction:{}", contract, direction);
}
return result;
}
key generation
public static final String getContractPositionZsetKey(String contract,int direction){
return "{POSITION:"+contract+"}.POSITION-ORDER-" + contract + "-" + direction;
}
public static final String getContractPositionHashKey(String contract,int direction){
return "{POSITION:"+contract+"}.POSITION-ORDER-VAL-" + contract + "-" + direction;
}
public static final String getContractPositionAmountKey(String contract,String amount){
return "{POSITION:"+contract+"}." + amount;
}
lua script
local val1 = '"'
local valAmount = redis.call('hget',KEYS[1],KEYS[2])
if not valAmount then
redis.pcall('hset',KEYS[1],KEYS[2],ARGV[1])
if tonumber(ARGV[1]) > 0 then
local val2 = val1 .. ARGV[3] .. val1
return redis.pcall('ZADD', KEYS[3], tonumber(ARGV[2]), val2)
else
return 1
end
else
local tagAmount = tonumber(valAmount) + ARGV[1]
redis.pcall('hset',KEYS[1],KEYS[2],tagAmount)
local val2 = val1 .. ARGV[3] .. val1
local zset = redis.pcall('ZRANK', KEYS[3], val2)
if tagAmount <= 0 then
if not zset then
return 1
else
return redis.pcall('ZREMRANGEBYSCORE', KEYS[3], tonumber(ARGV[2]), tonumber(ARGV[2]))
end
else
if not zset then
local val2 = val1 .. ARGV[3] .. val1
return redis.pcall('ZADD', KEYS[3], tonumber(ARGV[2]), val2)
else
return 1
end
end
end