Skip to content
This repository has been archived by the owner on Sep 28, 2022. It is now read-only.

Commit

Permalink
Merge pull request #61 from yuce/range-operators
Browse files Browse the repository at this point in the history
Added range field operations
  • Loading branch information
yuce committed Oct 2, 2017
2 parents c710aa3 + 116946d commit 4015ea8
Show file tree
Hide file tree
Showing 9 changed files with 389 additions and 114 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ Java client for Pilosa high performance distributed bitmap index.

* **Next**:
* Added support for creating range encoded frames.
* Added `SetFieldValue`, `Sum` and `Xor` calls.
* Added `Xor` call.
* Added range field operations.
* Added support for excluding bits or attributes from bitmap calls. In order to exclude bits, call `setExcludeBits(true)` in your `QueryOptions.Builder`. In order to exclude attributes, call `setExcludeAttributes(true)`.
* Customizable CSV time stamp format.
* **Deprecation** Row and column labels are deprecated, and will be removed in a future release of this library. Do not use `IndexOptions.Builder.setColumnLabel` and `FrameOptions.Builder.setRowLabel` methods for new code. See: https://github.com/pilosa/pilosa/issues/752 for more info.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,14 +501,17 @@ public void rangeFrameTest() throws IOException {
client.query(this.index.batchQuery(
frame.setBit(1, 10),
frame.setBit(1, 100),
frame.setFieldValue(10, "foo", 11),
frame.setFieldValue(100, "foo", 15)
frame.field("foo").setValue(10, 11),
frame.field("foo").setValue(100, 15)
));
QueryResponse response = client.query(frame.sum(frame.bitmap(1), "foo"));
QueryResponse response = client.query(frame.field("foo").sum(frame.bitmap(1)));
assertEquals(26, response.getResult().getSum());
assertEquals(2, response.getResult().getCount());
}

response = client.query(frame.field("foo").lessThan(15));
assertEquals(1, response.getResults().size());
assertEquals(10, (long) response.getResult().getBitmap().getBits().get(0));
}
}

@Test
Expand Down
44 changes: 14 additions & 30 deletions com.pilosa.client/src/main/java/com/pilosa/client/orm/Frame.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
Expand All @@ -64,6 +65,7 @@ private Frame(Index index, String name, FrameOptions options) {
this.options = options;
this.columnLabel = index.getOptions().getColumnLabel();
this.rowLabel = options.getRowLabel();
this.fields = new HashMap<>();
}

/**
Expand Down Expand Up @@ -379,33 +381,18 @@ public PqlBaseQuery setRowAttrs(long rowID, Map<String, Object> attributes) {
}

/**
* Creates a SetFieldValue query.
*
* @param columnID column ID
* @param field the field to set
* @param value the value to assign to the field
* @return a PQL query
* @see <a href="https://www.pilosa.com/docs/query-language/#setfieldvalue">SetFieldValue Query</a>
*/
public PqlBaseQuery setFieldValue(long columnID, String field, long value) {
String qry = String.format("SetFieldValue(frame='%s', %s=%d, %s=%d)",
this.name, this.columnLabel, columnID, field, value);
return this.index.pqlQuery(qry);
}

/**
* Creates a SumReduce query.
* <p>
* The frame for this query should have fields set.
* </p>
*
* @param bitmap The bitmap query to use.
* @param field The field to calculate the sum for.
* @return a PQL query
* @see <a href="https://www.pilosa.com/docs/query-language/#sum">Sum Query</a>
* Returns a RangeField object with the given name
* @param name field name
* @return RangeField object
*/
public PqlBaseQuery sum(PqlBitmapQuery bitmap, String field) {
return rangeQuery("Sum", bitmap, field);
public RangeField field(String name) {
RangeField field = this.fields.get(name);
if (field == null) {
Validator.ensureValidLabel(name);
field = new RangeField(this, name);
this.fields.put(name, field);
}
return field;
}

@Override
Expand All @@ -429,16 +416,13 @@ public int hashCode() {
.toHashCode();
}

private PqlBaseQuery rangeQuery(String call, PqlBitmapQuery bitmap, String field) {
return this.index.pqlQuery(String.format("%s(%s, frame='%s', field='%s')", call, bitmap.serialize(), this.name, field));
}

private final static DateFormat fmtDate = new SimpleDateFormat("yyyy-MM-dd");
private final static DateFormat fmtTime = new SimpleDateFormat("HH:mm");
private String name;
private Index index;
private FrameOptions options;
private String rowLabel;
private String columnLabel;
private Map<String, RangeField> fields;
private ObjectMapper mapper = new ObjectMapper();
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public Builder setCacheSize(int cacheSize) {
* @see <a href="https://www.pilosa.com/docs/data-model/#frame">Pilosa Data Model: Frame</a>
*/
public Builder addIntField(String name, long min, long max) {
this.fields.put(name, RangeField.intField(name, min, max));
this.fields.put(name, RangeFieldInfo.intField(name, min, max));
return this;
}

Expand All @@ -162,7 +162,7 @@ public FrameOptions build() {
private boolean inverseEnabled = false;
private CacheType cacheType = CacheType.DEFAULT;
private int cacheSize = 0;
private Map<String, RangeField> fields = new HashMap<>();
private Map<String, RangeFieldInfo> fields = new HashMap<>();

}

Expand Down Expand Up @@ -232,8 +232,8 @@ public String toString() {
if (this.fields.size() > 0) {
builder.append(",\"rangeEnabled\":true");
builder.append(",\"fields\":[");
Iterator<Map.Entry<String, RangeField>> iter = this.fields.entrySet().iterator();
Map.Entry<String, RangeField> entry = iter.next();
Iterator<Map.Entry<String, RangeFieldInfo>> iter = this.fields.entrySet().iterator();
Map.Entry<String, RangeFieldInfo> entry = iter.next();
builder.append(entry.getValue());
while (iter.hasNext()) {
entry = iter.next();
Expand Down Expand Up @@ -278,19 +278,19 @@ public int hashCode() {
private FrameOptions(final String rowLabel, final TimeQuantum timeQuantum,
final boolean inverseEnabled,
final CacheType cacheType, final int cacheSize,
final Map<String, RangeField> fields) {
final Map<String, RangeFieldInfo> fields) {
this.rowLabel = rowLabel;
this.timeQuantum = timeQuantum;
this.inverseEnabled = inverseEnabled;
this.cacheType = cacheType;
this.cacheSize = cacheSize;
this.fields = (fields != null) ? fields : new HashMap<String, RangeField>();
this.fields = (fields != null) ? fields : new HashMap<String, RangeFieldInfo>();
}

private final String rowLabel;
private final TimeQuantum timeQuantum;
private final boolean inverseEnabled;
private final CacheType cacheType;
private final int cacheSize;
private final Map<String, RangeField> fields;
private final Map<String, RangeFieldInfo> fields;
}
125 changes: 95 additions & 30 deletions com.pilosa.client/src/main/java/com/pilosa/client/orm/RangeField.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,90 @@

package com.pilosa.client.orm;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pilosa.client.Validator;
import com.pilosa.client.exceptions.ValidationException;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.util.HashMap;
import java.util.Map;

public class RangeField {
public static RangeField intField(String name, long min, long max) {
Validator.ensureValidLabel(name);
if (max <= min) {
throw new ValidationException("Max should be greater than min for int fields");
}
Map<String, Object> properties = new HashMap<>(4);
properties.put("name", name);
properties.put("type", "int");
properties.put("min", min);
properties.put("max", max);
return new RangeField(properties);
/**
* Creates a Range query with less than (<) condition.
*
* @param n The value to compare
* @return a PQL query
*/
public PqlBitmapQuery lessThan(long n) {
return binaryOperation("<", n);
}

@Override
public String toString() {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(this.properties);
} catch (Exception ex) {
throw new ValidationException("Field properties weren't converted to JSON", ex);
}
/**
* Creates a Range query with less than or equal (<=) condition.
*
* @param n The value to compare
* @return a PQL query
*/
public PqlBitmapQuery lessThanOrEqual(long n) {
return binaryOperation("<=", n);
}

/**
* Creates a Range query with greater than (>) condition.
*
* @param n The value to compare
* @return a PQL query
*/
public PqlBitmapQuery greaterThan(long n) {
return binaryOperation(">", n);
}

/**
* Creates a Range query with greater than or equal (>=) condition.
*
* @param n The value to compare
* @return a PQL query
*/
public PqlBitmapQuery greaterThanOrEqual(long n) {
return binaryOperation(">=", n);
}

/**
* Creates a Range query with between (><) condition.
*
* @param a Closed range start
* @param b Closed range end
* @return a PQL query
*/
public PqlBitmapQuery between(long a, long b) {
String qry = String.format("Range(frame='%s', %s >< [%d,%d])",
frame.getName(), this.name, a, b);
return this.index.pqlBitmapQuery(qry);
}

/**
* Creates a Sum query.
* <p>
* The frame for this query should have fields set.
* </p>
*
* @param bitmap The bitmap query to use.
* @return a PQL query
* @see <a href="https://www.pilosa.com/docs/query-language/#sum">Sum Query</a>
*/
public PqlBaseQuery sum(PqlBitmapQuery bitmap) {
String qry = String.format("Sum(%s, frame='%s', field='%s')",
bitmap.serialize(), frame.getName(), name);
return this.index.pqlQuery(qry);
}

/**
* Creates a SetFieldValue query.
*
* @param columnID column ID
* @param value the value to assign to the field
* @return a PQL query
* @see <a href="https://www.pilosa.com/docs/query-language/#setfieldvalue">SetFieldValue Query</a>
*/
public PqlBaseQuery setValue(long columnID, long value) {
String qry = String.format("SetFieldValue(frame='%s', %s=%d, %s=%d)",
frame.getName(), this.index.getOptions().getColumnLabel(), columnID, name, value);
return this.index.pqlQuery(qry);
}

@Override
Expand All @@ -75,19 +129,30 @@ public boolean equals(Object obj) {
return true;
}
RangeField rhs = (RangeField) obj;
return rhs.properties.equals(this.properties);
return rhs.name.equals(this.name);
}

@Override
public int hashCode() {
return new HashCodeBuilder(31, 47)
.append(this.properties)
.append(this.name)
.toHashCode();
}

RangeField(Map<String, Object> properties) {
this.properties = properties;

RangeField(Frame frame, String name) {
this.index = frame.getIndex();
this.frame = frame;
this.name = name;
}

private PqlBitmapQuery binaryOperation(String op, long n) {
String qry = String.format("Range(frame='%s', %s %s %d)",
frame.getName(), this.name, op, n);
return this.index.pqlBitmapQuery(qry);
}

private final Map<String, Object> properties;
private Index index;
private Frame frame;
private String name;
}

0 comments on commit 4015ea8

Please sign in to comment.