package com.alibaba.doris.dataserver.action.parser;
import com.alibaba.doris.common.data.Key;
import com.alibaba.doris.common.data.util.ByteUtils;
import com.alibaba.doris.common.route.VirtualRouter;
import com.alibaba.doris.common.router.virtual.VirtualRouterImpl;
import com.alibaba.doris.dataserver.action.data.ActionData;
import com.alibaba.doris.dataserver.action.data.BaseActionData;
import com.alibaba.doris.dataserver.action.data.SimpleActionData;
import com.alibaba.doris.dataserver.net.ByteBufferWrapper;
import com.alibaba.doris.dataserver.net.protocol.text.ProtocolConstant;
/**
* @author ajun Email:jack.yuj@alibaba-inc.com
*/
public abstract class BaseActionParser implements ActionParser {
protected String parseNextField(byte[] line, int[] startPos) {
int pos = startPos[0];
if (pos >= line.length) {
return null;
}
while (line[pos] != ProtocolConstant.SPACE && (line[pos] != ProtocolConstant.CRLF[0])) {
pos++;
}
if (pos == startPos[0]) {
if (line[pos] == ProtocolConstant.SPACE) {
startPos[0]++;
} else if (line[pos] == ProtocolConstant.CRLF[0]) {
startPos[0] += 2;
} else if (line[pos] == ProtocolConstant.CRLF[1]) {
startPos[0]++;
}
return null;
}
int skipLen = 0;
if (line[pos] == ProtocolConstant.SPACE) {
// skip ' '
pos++;
skipLen = 1;
} else if (line[pos] == ProtocolConstant.CRLF[0]) {
// skip \r\n
pos += 2;
skipLen = 2;
} else if (line[pos] == ProtocolConstant.CRLF[1]) {
// skip \n
pos++;
skipLen = 1;
}
String value = ByteUtils.byteToString(line, startPos[0], (pos - startPos[0] - skipLen));
startPos[0] = pos;
return value;
}
public void readRouteVersion(BaseActionData actionData, byte[] header, int[] startPos) {
if ((startPos[0] + ProtocolConstant.CRLF.length) < header.length) {
String routeVersion = parseNextField(header, startPos);
if (null != routeVersion) {
actionData.setRouteVersion(Long.valueOf(routeVersion));
}
}
}
protected void readKeyBytes(BaseActionData actionData, byte[] header, int[] pos) {
int startPos = pos[0];
skipNextField(header, pos);
byte[] keyBytes = new byte[pos[0] - startPos - 1];
System.arraycopy(header, startPos, keyBytes, 0, keyBytes.length);
actionData.setKeyBytes(keyBytes);
}
protected void readVnode(BaseActionData actionData, byte[] header, int[] pos) {
if (SimpleActionData.INVALID_ROUTE_VERSION != actionData.getRouteVersion()) {
String vnodeStr = parseNextField(header, pos);
if (null != vnodeStr) {
actionData.setVnode(Integer.valueOf(vnodeStr));
}
}
if (Key.DEFAULT_VNODE == actionData.getVnode()) {
// Client没有传vnode过来,需要Server重新计算Vnode
int vnode = router.findVirtualNode(ByteUtils.byteToString(actionData.getKeyBytes()));
actionData.setVnode(vnode);
}
}
public void writeBody(ByteBufferWrapper buffer, ActionData actionData) {
;
}
public void readBody(byte[] body, ActionData actionData) {
;
}
/**
* 为了提升性能,new String会消耗大量CPU资源。
*
* @param line
* @param startPos
*/
protected void skipNextField(byte[] line, int[] startPos) {
int pos = startPos[0];
while (line[pos] != ProtocolConstant.SPACE && line[pos] != ProtocolConstant.CRLF[0]) {
pos++;
}
// skip ' '
pos++;
startPos[0] = pos;
}
private static final VirtualRouter router = VirtualRouterImpl.getInstance();
}