add tag & prop commands

This commit is contained in:
Mengyi Zhou 2016-07-19 13:41:43 +08:00
parent 379af75de3
commit b23ef0dde9
9 changed files with 385 additions and 15 deletions

View file

@ -1,5 +1,7 @@
package com.ctrip.zeus.service.query;
import com.ctrip.zeus.tag.PropertyService;
import com.ctrip.zeus.tag.TagService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@ -15,6 +17,10 @@ public class CriteriaQueryFactory {
private CriteriaQuery slbCriteriaQuery;
@Resource
private CriteriaQuery virtualServerCriteriaQuery;
@Resource
private TagService tagService;
@Resource
private PropertyService propertyService;
public CriteriaQuery getCriteriaQuery(String type) {
switch (type) {
@ -28,4 +34,12 @@ public class CriteriaQueryFactory {
return null;
}
}
public TagService getTagService() {
return tagService;
}
public PropertyService getPropertyService() {
return propertyService;
}
}

View file

@ -3,10 +3,7 @@ package com.ctrip.zeus.service.query;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.service.model.IdVersion;
import com.ctrip.zeus.service.model.SelectionMode;
import com.ctrip.zeus.service.query.command.GroupQueryCommand;
import com.ctrip.zeus.service.query.command.QueryCommand;
import com.ctrip.zeus.service.query.command.SlbQueryCommand;
import com.ctrip.zeus.service.query.command.VsQueryCommand;
import com.ctrip.zeus.service.query.command.*;
import com.google.common.base.Joiner;
import java.util.*;
@ -22,8 +19,10 @@ public class QueryEngine {
private final GroupQueryCommand groupQueryCommand = new GroupQueryCommand();
private final VsQueryCommand vsQueryCommand = new VsQueryCommand();
private final SlbQueryCommand slbQueryCommand = new SlbQueryCommand();
private final TagQueryCommand tagCommand = new TagQueryCommand();
private final PropQueryCommand propertyCommand = new PropQueryCommand();
private final QueryCommand[] sequenceController = new QueryCommand[3];
private final QueryCommand[] sequenceController = new QueryCommand[5];
public QueryEngine(Queue<String[]> params, String resource, SelectionMode mode) {
this.params = params;
@ -46,6 +45,8 @@ public class QueryEngine {
sequenceController[2] = vsQueryCommand;
break;
}
sequenceController[3] = tagCommand;
sequenceController[4] = propertyCommand;
}
public void init(boolean skipable) throws ValidationException {
@ -68,6 +69,28 @@ public class QueryEngine {
}
public IdVersion[] run(CriteriaQueryFactory criteriaQueryFactory) throws Exception {
// filter by tags and props
Set<Long> pre = criteriaQueryFactory.getTagService().queryByCommand(tagCommand, resource);
Set<Long> propItems = criteriaQueryFactory.getPropertyService().queryByCommand(propertyCommand, resource);
if (pre == null) {
pre = propItems;
} else {
if (propItems != null) pre.retainAll(propItems);
}
QueryCommand c = sequenceController[0];
if (pre != null) {
Set<Long> orig = new HashSet<>();
// 0 is the index of id
for (String s : c.getValue(0)) {
orig.add(Long.parseLong(s));
}
pre.retainAll(orig);
c.addAtIndex(0, Joiner.on(",").join(pre));
}
// filter by criteria queries
String[] traverseSequence = new String[]{sequenceController[1].getType(),
sequenceController[2].getType(), sequenceController[0].getType()};
IdVersion[] result = traverseQuery(traverseSequence, 0, criteriaQueryFactory);

View file

@ -0,0 +1,76 @@
package com.ctrip.zeus.service.query.command;
import com.ctrip.zeus.tag.entity.Property;
import java.util.ArrayList;
import java.util.List;
/**
* Created by zhoumy on 2016/7/19.
*/
public class PropQueryCommand implements QueryCommand {
public final int union_prop = 0;
public final int join_prop = 1;
private final String type;
private String[] values = new String[2];
public PropQueryCommand() {
this.type = "prop";
}
@Override
public boolean add(String queryName, String queryValue) {
int idx;
switch (queryName) {
case "anyProp":
case "unionProp":
idx = union_prop;
break;
case "props":
case "joinPro":
idx = join_prop;
break;
default:
return false;
}
return addAtIndex(idx, queryValue);
}
@Override
public boolean addAtIndex(int idx, String queryValue) {
if (idx < values.length) {
values[idx] = queryValue;
return true;
} else {
return false;
}
}
@Override
public boolean hasValue(int idx) {
return values[idx] != null;
}
@Override
public String[] getValue(int idx) {
String value = values[idx];
return value == null ? null : value.split(",");
}
public List<Property> getProperties(int idx) {
List<Property> properties = new ArrayList<>();
for (String s : getValue(idx)) {
int ps = s.trim().indexOf(':');
if (ps == -1) continue;
properties.add(new Property().setName(s.substring(0, ps)).setValue(s.substring(ps + 1)));
}
return properties;
}
@Override
public String getType() {
return type;
}
}

View file

@ -0,0 +1,61 @@
package com.ctrip.zeus.service.query.command;
/**
* Created by zhoumy on 2016/7/19.
*/
public class TagQueryCommand implements QueryCommand {
public final int union_tag = 0;
public final int join_tag = 1;
private final String type;
private String[] values = new String[2];
public TagQueryCommand() {
type = "tag";
}
@Override
public boolean add(String queryName, String queryValue) {
int idx;
switch (queryName) {
case "anyTag":
case "unionTag":
idx = union_tag;
break;
case "tags":
case "joinTag":
idx = join_tag;
break;
default:
return false;
}
return addAtIndex(idx, queryValue);
}
@Override
public boolean addAtIndex(int idx, String queryValue) {
if (idx < values.length) {
values[idx] = queryValue;
return true;
} else {
return false;
}
}
@Override
public boolean hasValue(int idx) {
return values[idx] != null;
}
@Override
public String[] getValue(int idx) {
String value = values[idx];
return value == null ? null : value.split(",");
}
@Override
public String getType() {
return type;
}
}

View file

@ -1,19 +1,27 @@
package com.ctrip.zeus.tag;
import com.ctrip.zeus.service.query.command.QueryCommand;
import com.ctrip.zeus.tag.entity.Property;
import java.util.List;
import java.util.Set;
/**
* Created by zhoumy on 2015/7/21.
*/
public interface PropertyService {
Set<Long> queryByCommand(QueryCommand command, String type) throws Exception;
List<Property> getAllProperties() throws Exception;
List<Property> getProperties(String type, Long itemId) throws Exception;
Property getProperty(String pname, Long itemId, String type) throws Exception;
Set<Long> unionQuery(List<Property> properties, String type) throws Exception;
Set<Long> joinQuery(List<Property> properties, String type) throws Exception;
List<Long> queryTargets(String pname, String pvalue, String type) throws Exception;
}

View file

@ -1,13 +1,20 @@
package com.ctrip.zeus.tag;
import com.ctrip.zeus.service.query.command.QueryCommand;
import java.util.List;
import java.util.Set;
/**
* Created by zhoumy on 2015/7/20.
*/
public interface TagService {
List<Long> query(List<String> tagNames, String type) throws Exception;
Set<Long> queryByCommand(QueryCommand command, String type) throws Exception;
Set<Long> unionQuery(List<String> tagNames, String type) throws Exception;
Set<Long> joinQuery(List<String> tagNames, String type) throws Exception;
List<Long> query(String tagName, String type) throws Exception;

View file

@ -1,15 +1,14 @@
package com.ctrip.zeus.tag.impl;
import com.ctrip.zeus.dal.core.*;
import com.ctrip.zeus.service.query.command.PropQueryCommand;
import com.ctrip.zeus.service.query.command.QueryCommand;
import com.ctrip.zeus.tag.PropertyService;
import com.ctrip.zeus.tag.entity.Property;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* Created by zhoumy on 2015/7/21.
@ -23,6 +22,23 @@ public class PropertyServiceImpl implements PropertyService {
@Resource
private PropertyItemDao propertyItemDao;
@Override
public Set<Long> queryByCommand(QueryCommand command, String type) throws Exception {
Set<Long> result = null;
PropQueryCommand propQuery = (PropQueryCommand) command;
if (command.hasValue(propQuery.union_prop)) {
result = unionQuery(propQuery.getProperties(propQuery.union_prop), type);
}
if (command.hasValue(propQuery.join_prop)) {
if (result == null) {
result = joinQuery(propQuery.getProperties(propQuery.join_prop), type);
} else {
result.retainAll(joinQuery(propQuery.getProperties(propQuery.join_prop), type));
}
}
return result;
}
@Override
public Property getProperty(String pname, Long itemId, String type) throws Exception {
PropertyKeyDo kd = propertyKeyDao.findByName(pname, PropertyKeyEntity.READSET_FULL);
@ -40,6 +56,81 @@ public class PropertyServiceImpl implements PropertyService {
return null;
}
@Override
public Set<Long> unionQuery(List<Property> properties, String type) throws Exception {
Map<String, Long> pnames = new HashMap<>();
Map<String, Long> pids = new HashMap<>();
Long obj = 0L;
for (Property p : properties) {
pnames.put(p.getName(), obj);
pids.put(p.getName() + ":" + p.getValue(), obj);
}
for (PropertyKeyDo e : propertyKeyDao.findByNames(pnames.keySet().toArray(new String[0]), PropertyKeyEntity.READSET_FULL)) {
pnames.put(e.getName(), e.getId());
}
for (PropertyDo e : propertyDao.findAllByIds(pnames.values().toArray(new Long[0]), PropertyEntity.READSET_FULL)) {
String k = pnames.get(e.getPropertyKeyId()) + ":" + e.getPropertyValue();
if (pids.containsKey(k)) {
pids.put(k, e.getId());
}
}
Set<Long> result = new HashSet<>();
for (PropertyItemDo e : propertyItemDao.findAllByProperties(pids.values().toArray(new Long[0]), PropertyItemEntity.READSET_FULL)) {
if (e.getType().equals(type)) {
result.add(e.getItemId());
}
}
return result;
}
@Override
public Set<Long> joinQuery(List<Property> properties, String type) throws Exception {
Map<String, Long> pnames = new HashMap<>();
Map<String, Long> pids = new HashMap<>();
Long obj = 0L;
for (Property p : properties) {
pnames.put(p.getName(), obj);
pids.put(p.getName() + ":" + p.getValue(), obj);
}
for (PropertyKeyDo e : propertyKeyDao.findByNames(pnames.keySet().toArray(new String[0]), PropertyKeyEntity.READSET_FULL)) {
pnames.put(e.getName(), e.getId());
}
for (Long l : pnames.values()) {
if (l == obj) return new HashSet<>();
}
for (PropertyDo e : propertyDao.findAllByIds(pnames.values().toArray(new Long[0]), PropertyEntity.READSET_FULL)) {
String k = pnames.get(e.getPropertyKeyId()) + ":" + e.getPropertyValue();
if (pids.containsKey(k)) {
pids.put(k, e.getId());
}
}
for (Long l : pids.values()) {
if (l == obj) return new HashSet<>();
}
int joinedValue = pids.size();
Map<Long, Counter> marker = new HashMap<>();
for (PropertyItemDo e : propertyItemDao.findAllByProperties(pids.values().toArray(new Long[0]), PropertyItemEntity.READSET_FULL)) {
if (e.getType().equals(type)) {
Counter m = marker.get(e.getPropertyId());
if (m == null) {
marker.put(e.getItemId(), new Counter());
} else {
m.incr();
}
}
}
Set<Long> result = new HashSet<>();
for (Map.Entry<Long, Counter> e : marker.entrySet()) {
if (e.getValue().get() == joinedValue) result.add(e.getKey());
}
return result;
}
@Override
public List<Long> queryTargets(String pname, String pvalue, String type) throws Exception {
List<Long> result = new ArrayList<>();
@ -97,4 +188,16 @@ public class PropertyServiceImpl implements PropertyService {
}
return new ArrayList<>(result.values());
}
private class Counter {
int count = 1;
public void incr() {
count++;
}
public int get() {
return count;
}
}
}

View file

@ -1,12 +1,13 @@
package com.ctrip.zeus.tag.impl;
import com.ctrip.zeus.dal.core.*;
import com.ctrip.zeus.service.query.command.QueryCommand;
import com.ctrip.zeus.service.query.command.TagQueryCommand;
import com.ctrip.zeus.tag.TagService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
/**
* Created by zhoumy on 2015/7/20.
@ -19,22 +20,76 @@ public class TagServiceImpl implements TagService {
private TagItemDao tagItemDao;
@Override
public List<Long> query(List<String> tagNames, String type) throws Exception {
public Set<Long> queryByCommand(QueryCommand command, String type) throws Exception {
Set<Long> result = null;
TagQueryCommand tagQuery = (TagQueryCommand) command;
if (command.hasValue(tagQuery.union_tag)) {
List<String> tn = new ArrayList<>();
for (String s : tagQuery.getValue(tagQuery.union_tag)) {
tn.add(s.trim());
}
result = unionQuery(tn, type);
}
if (command.hasValue(tagQuery.join_tag)) {
List<String> tn = new ArrayList<>();
for (String s : tagQuery.getValue(tagQuery.join_tag)) {
tn.add(s.trim());
}
if (result == null) {
result = joinQuery(tn, type);
} else {
result.retainAll(joinQuery(tn, type));
}
}
return result;
}
@Override
public Set<Long> unionQuery(List<String> tagNames, String type) throws Exception {
List<TagDo> tags = tagDao.findAllByNames(tagNames.toArray(new String[tagNames.size()]), TagEntity.READSET_FULL);
if (tags.size() == 0) return new ArrayList<>();
if (tags.size() == 0) return new HashSet<>();
Long[] tagIds = new Long[tags.size()];
for (int i = 0; i < tagIds.length; i++) {
tagIds[i] = tags.get(i).getId();
}
List<Long> result = new ArrayList<>();
Set<Long> result = new HashSet<>();
for (TagItemDo d : tagItemDao.findByTagsAndType(tagIds, type, TagItemEntity.READSET_FULL)) {
result.add(d.getItemId());
}
return result;
}
@Override
public Set<Long> joinQuery(List<String> tagNames, String type) throws Exception {
List<TagDo> tags = tagDao.findAllByNames(tagNames.toArray(new String[tagNames.size()]), TagEntity.READSET_FULL);
if (tags.size() == 0) return new HashSet<>();
Long[] tagIds = new Long[tags.size()];
for (int i = 0; i < tagIds.length; i++) {
tagIds[i] = tags.get(i).getId();
}
if (tagIds.length < tagNames.size()) return new HashSet<>();
int joinedValue = tagIds.length;
Map<Long, Counter> marker = new HashMap<>();
for (TagItemDo d : tagItemDao.findByTagsAndType(tagIds, type, TagItemEntity.READSET_FULL)) {
Counter m = marker.get(d.getItemId());
if (m == null) {
marker.put(d.getItemId(), new Counter());
} else {
m.incr();
}
}
Set<Long> result = new HashSet<>();
for (Map.Entry<Long, Counter> e : marker.entrySet()) {
if (e.getValue().get() == joinedValue) result.add(e.getKey());
}
return result;
}
@Override
public List<Long> query(String tagName, String type) throws Exception {
TagDo d = tagDao.findByName(tagName, TagEntity.READSET_FULL);
@ -64,4 +119,16 @@ public class TagServiceImpl implements TagService {
}
return result;
}
private class Counter {
int count = 1;
public void incr() {
count++;
}
public int get() {
return count;
}
}
}

View file

@ -209,6 +209,7 @@
</entity>
<entity name="property-key" table="property_key" alias="pk" do-class="PropertyKeyDo">
<var name="ids" value-type="Long[]"/>
<var name="names" value-type="String[]"/>
<query-defs>
<query name="find-all-by-ids" type="SELECT" multiple="true">
<param name="ids"/>
@ -238,6 +239,16 @@
]]>
</statement>
</query>
<query name="find-by-names" type="SELECT" multiple="true">
<param name="names"/>
<statement>
<![CDATA[
SELECT <FIELDS/>
FROM <TABLE/>
WHERE <FIELD name='name'/> in <IN>${names}</IN>
]]>
</statement>
</query>
<query name="update" type="UPDATE">
<param name="id"/>
<statement>