Skip to content

Commit

Permalink
Support pagination when single index query (#328)
Browse files Browse the repository at this point in the history
Support pagination when single index query

Change-Id: Iab355a9f68cebd8ebc666cf126842eb19fa40240
  • Loading branch information
Linary authored and zhoney committed Mar 27, 2019
1 parent 1e8e7bd commit c50c34a
Show file tree
Hide file tree
Showing 46 changed files with 1,584 additions and 224 deletions.
4 changes: 2 additions & 2 deletions hugegraph-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>hugegraph</artifactId>
<groupId>com.baidu.hugegraph</groupId>
<version>0.9.1</version>
<version>0.9.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down Expand Up @@ -86,7 +86,7 @@
</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Implementation-Version>0.34.0.0</Implementation-Version>
<Implementation-Version>0.35.0.0</Implementation-Version>
</manifestEntries>
</archive>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,17 +222,20 @@ public String list(@Context GraphManager manager,
LOG.debug("Graph [{}] query edges by vertex: {}, direction: {}, " +
"label: {}, properties: {}, offset: {}, page: {}, limit: {}",
vertexId, direction, label, properties, offset, page, limit);

Map<String, Object> props = parseProperties(properties);
if (page != null) {
E.checkArgument(vertexId == null && direction == null &&
label == null && properties == null && offset == 0,
"Not support quering edges based on paging and " +
"[vertex, direction, label, properties, offset] " +
"together");
offset == 0,
"Not support querying edges based on paging " +
"and [vertex, direction, offset] together");
E.checkArgument(props.size() <= 1,
"Not support querying edges based on paging " +
"and more than one property");
}

Id vertex = VertexAPI.checkAndParseVertexId(vertexId);
Direction dir = parseDirection(direction);
Map<String, Object> props = parseProperties(properties);

HugeGraph g = graph(manager, graph);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,16 @@ public String list(@Context GraphManager manager,
LOG.debug("Graph [{}] query vertices by label: {}, properties: {}, " +
"offset: {}, page: {}, limit: {}",
graph, label, properties, offset, page, limit);
if (page != null) {
E.checkArgument(label == null && properties == null && offset == 0,
"Not support quering vertices based on paging " +
"and [label, properties, offset] together");
}

Map<String, Object> props = parseProperties(properties);
if (page != null) {
E.checkArgument(offset == 0,
"Not support querying vertices based on paging " +
"and offset together");
E.checkArgument(props.size() <= 1,
"Not support querying vertices based on paging " +
"and more than one property");
}

HugeGraph g = graph(manager, graph);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@
import com.codahale.metrics.Histogram;
import com.codahale.metrics.annotation.Timed;
import com.fasterxml.jackson.annotation.JsonProperty;

import jersey.repackaged.com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap;

@Path("graphs/{graph}/jobs/gremlin")
@Singleton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@ public final class ApiVersion {
* [0.32] Issue-250: Keep depth and degree consistent for traverser api
* [0.33] Issue-305: Implement customized paths and crosspoints RESTful API
* [0.34] Issue-307: Let VertexAPI use simplified property serializer
* [0.35] Issue-287: Support pagination when do index query
*/

// The second parameter of Version.of() is for IDE running without JAR
public static final Version VERSION = Version.of(ApiVersion.class, "0.34");
public static final Version VERSION = Version.of(ApiVersion.class, "0.35");

public static final void check() {
// Check version of hugegraph-core. Firstly do check from version 0.3
Expand Down
2 changes: 1 addition & 1 deletion hugegraph-cassandra/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>hugegraph</artifactId>
<groupId>com.baidu.hugegraph</groupId>
<version>0.9.1</version>
<version>0.9.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,25 +127,6 @@ protected List<Select> query2Select(String table, Query query) {
"currently, it will be replaced by [0, offset + limit)");
}

// Set limit
if (query.limit() != Query.NO_LIMIT) {
long total = query.total();
String page = query.page();
if (page == null) {
select.limit((int) total);
} else {
select.setFetchSize((int) total);
// It's the first time if page is empty
if (!page.isEmpty()) {
try {
select.setPagingState(PagingState.fromString(page));
} catch (PagingStateException e) {
throw new BackendException(e.getMessage());
}
}
}
}

// Set order-by
for (Map.Entry<HugeKeys, Order> order : query.orders().entrySet()) {
String name = formatKey(order.getKey());
Expand All @@ -162,19 +143,45 @@ protected List<Select> query2Select(String table, Query query) {

if (query.conditions().isEmpty()) {
// Query only by id
this.setPageState(query, ids);
LOG.debug("Query only by id(s): {}", ids);
return ids;
} else {
List<Select> conds = new ArrayList<Select>(ids.size());
List<Select> conds = new ArrayList<>(ids.size());
for (Select selection : ids) {
// Query by condition
conds.addAll(this.queryCondition2Select(query, selection));
}
this.setPageState(query, conds);
LOG.debug("Query by conditions: {}", conds);
return conds;
}
}

protected void setPageState(Query query, List<Select> selects) {
if (query.limit() == Query.NO_LIMIT) {
return;
}
for (Select select : selects) {
long total = query.total();
String page = query.page();
if (page == null) {
// Set limit
select.limit((int) total);
} else {
select.setFetchSize((int) total);
// It's the first time if page is empty
if (!page.isEmpty()) {
try {
select.setPagingState(PagingState.fromString(page));
} catch (PagingStateException e) {
throw new BackendException(e);
}
}
}
}
}

protected List<Select> queryId2Select(Query query, Select select) {
// Query by id(s)
if (query.ids().isEmpty()) {
Expand Down
4 changes: 2 additions & 2 deletions hugegraph-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.baidu.hugegraph</groupId>
<artifactId>hugegraph</artifactId>
<version>0.9.1</version>
<version>0.9.2</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>hugegraph-core</artifactId>
Expand Down Expand Up @@ -157,7 +157,7 @@
</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Implementation-Version>0.9.1.0</Implementation-Version>
<Implementation-Version>0.9.2.0</Implementation-Version>
</manifestEntries>
</archive>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright 2017 HugeGraph Authors
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package com.baidu.hugegraph.backend.page;

import java.util.Set;
import java.util.function.Function;

import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.backend.query.ConditionQuery;
import com.baidu.hugegraph.util.E;
import com.baidu.hugegraph.util.InsertionOrderUtil;
import com.google.common.collect.ImmutableSet;

public final class IdHolder {

private final ConditionQuery query;
private final Function<ConditionQuery, PageIds> idsFetcher;
private boolean exhausted;

private Set<Id> ids;

/**
* For non-paging situation
*/
public IdHolder(Set<Id> ids) {
this.query = null;
this.idsFetcher = null;
this.exhausted = false;
if (ids instanceof ImmutableSet) {
this.ids = InsertionOrderUtil.newSet(ids);
} else {
this.ids = ids;
}
}

/**
* For paging situation
*/
public IdHolder(ConditionQuery query,
Function<ConditionQuery, PageIds> idsFetcher) {
E.checkArgument(query.paging(),
"Query '%s' must include page info", query);
this.query = query.copy();
this.idsFetcher = idsFetcher;
this.exhausted = false;
this.ids = null;
}

public void merge(Set<Id> ids) {
this.ids.addAll(ids);
}

public Set<Id> ids() {
E.checkNotNull(this.ids, "ids");
return this.ids;
}

public int size() {
if (this.ids == null) {
return 0;
}
return this.ids.size();
}

public boolean paging() {
return this.idsFetcher != null;
}

public PageIds fetchNext(String page, long pageSize) {
if (this.exhausted) {
return PageIds.EMPTY;
}

this.query.page(page);
this.query.limit(pageSize);

PageIds result = this.idsFetcher.apply(this.query);

assert result != null;
this.ids = result.ids();
if (this.ids.size() != this.query.limit() || result.page() == null) {
this.exhausted = true;
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2017 HugeGraph Authors
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package com.baidu.hugegraph.backend.page;

import java.util.ArrayList;
import java.util.Collection;

import com.baidu.hugegraph.util.E;

public final class IdHolderList extends ArrayList<IdHolder> {

private final boolean paging;

public IdHolderList(boolean paging) {
this.paging = paging;
}

public boolean paging() {
return this.paging;
}

@Override
public boolean add(IdHolder holder) {
E.checkArgument(this.paging == holder.paging(),
"The IdHolder to be linked must be " +
"in same paging mode");
if (this.paging || this.isEmpty()) {
super.add(holder);
} else {
assert this.size() == 1;
IdHolder self = this.get(0);
assert !self.paging();
self.merge(holder.ids());
}
return true;
}

@Override
public boolean addAll(Collection<? extends IdHolder> idHolders) {
for (IdHolder idHolder : idHolders) {
this.add(idHolder);
}
return true;
}

public int idsSize() {
if (this.paging || this.isEmpty()) {
return 0;
} else {
assert this.size() == 1;
return this.get(0).size();
}
}
}
Loading

0 comments on commit c50c34a

Please sign in to comment.