Skip to content

Commit

Permalink
[scsi] support prefix based string match (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
jywadhwani authored May 10, 2021
1 parent f7a40c4 commit 682a19c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ static class GMAIndexPair {
Collections.unmodifiableMap(new HashMap<Condition, String>() {
{
put(Condition.EQUAL, "=");
put(Condition.LESS_THAN, "<");
put(Condition.LESS_THAN_OR_EQUAL_TO, "<=");
put(Condition.GREATER_THAN, ">");
put(Condition.GREATER_THAN_OR_EQUAL_TO, ">=");
put(Condition.LESS_THAN, "<");
put(Condition.LESS_THAN_OR_EQUAL_TO, "<=");
put(Condition.START_WITH, "LIKE");
}
});

Expand Down Expand Up @@ -796,7 +797,8 @@ public long newNumericId(@Nonnull String namespace, int maxTransactionRetry) {
}

@Nonnull
static GMAIndexPair getGMAIndexPair(@Nonnull IndexValue indexValue) {
static GMAIndexPair getGMAIndexPair(@Nonnull IndexCriterion criterion) {
final IndexValue indexValue = criterion.getPathParams().getValue();
final Object object;
if (indexValue.isBoolean()) {
object = indexValue.getBoolean().toString();
Expand All @@ -814,13 +816,21 @@ static GMAIndexPair getGMAIndexPair(@Nonnull IndexValue indexValue) {
object = indexValue.getLong();
return new GMAIndexPair(EbeanMetadataIndex.LONG_COLUMN, object);
} else if (indexValue.isString()) {
object = indexValue.getString();
object = getValueFromIndexCriterion(criterion);
return new GMAIndexPair(EbeanMetadataIndex.STRING_COLUMN, object);
} else {
throw new IllegalArgumentException("Invalid index value " + indexValue);
}
}

static String getValueFromIndexCriterion(@Nonnull IndexCriterion criterion) {
final IndexValue indexValue = criterion.getPathParams().getValue();
if (criterion.getPathParams().getCondition().equals(Condition.START_WITH)) {
return indexValue.getString() + "%";
}
return indexValue.getString();
}

/**
* Sets the values of parameters in metadata index query based on its position, values obtained from
* {@link IndexCriterionArray} and last urn. Also sets the LIMIT of SQL query using the page size input.
Expand All @@ -839,7 +849,7 @@ private static void setParameters(@Nonnull IndexCriterionArray indexCriterionArr
indexQuery.setParameter(pos++, criterion.getAspect());
if (criterion.getPathParams() != null) {
indexQuery.setParameter(pos++, criterion.getPathParams().getPath());
indexQuery.setParameter(pos++, getGMAIndexPair(criterion.getPathParams().getValue()).value);
indexQuery.setParameter(pos++, getGMAIndexPair(criterion).value);
}
}
indexQuery.setParameter(pos, pageSize);
Expand Down Expand Up @@ -878,7 +888,8 @@ private static String constructSQLQuery(@Nonnull IndexCriterionArray indexCriter
.append(".path = ? AND t")
.append(i)
.append(".")
.append(getGMAIndexPair(criterion.getPathParams().getValue()).valueType)
.append(getGMAIndexPair(criterion).valueType)
.append(" ")
.append(getStringForOperator(criterion.getPathParams().getCondition()))
.append("?");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,43 @@ void testListUrnsFromIndexManyFilters() {
assertEquals(urns7, Collections.emptyList());
}

@Test
public void testStartsWith() {
EbeanLocalDAO<EntityAspectUnion, FooUrn> dao = createDao(FooUrn.class);
dao.enableLocalSecondaryIndex(true);
FooUrn urn1 = makeFooUrn(1);
FooUrn urn2 = makeFooUrn(2);
String aspect = "aspect" + System.currentTimeMillis();

addIndex(urn1, aspect, "/path", "value1");
addIndex(urn1, FooUrn.class.getCanonicalName(), "/fooId", 1);

addIndex(urn2, aspect, "/path", "value2");
addIndex(urn2, FooUrn.class.getCanonicalName(), "/fooId", 2);

// starts with substring
IndexValue indexValue1 = new IndexValue();
indexValue1.setString("val");
IndexCriterion criterion1 = new IndexCriterion().setAspect(aspect)
.setPathParams(new IndexPathParams().setPath("/path").setValue(indexValue1).setCondition(Condition.START_WITH));

IndexCriterionArray indexCriterionArray1 = new IndexCriterionArray(Collections.singletonList(criterion1));
final IndexFilter indexFilter1 = new IndexFilter().setCriteria(indexCriterionArray1);
List<FooUrn> urns1 = dao.listUrns(indexFilter1, null, 5);
assertEquals(urns1, Arrays.asList(urn1, urn2));

// full string
IndexValue indexValue2 = new IndexValue();
indexValue2.setString("value1");
IndexCriterion criterion2 = new IndexCriterion().setAspect(aspect)
.setPathParams(new IndexPathParams().setPath("/path").setValue(indexValue2).setCondition(Condition.START_WITH));

IndexCriterionArray indexCriterionArray2 = new IndexCriterionArray(Collections.singletonList(criterion2));
final IndexFilter indexFilter2 = new IndexFilter().setCriteria(indexCriterionArray2);
List<FooUrn> urns2 = dao.listUrns(indexFilter2, null, 5);
assertEquals(urns2, Collections.singletonList(urn1));
}

@Test
public void testListUrns() {
EbeanLocalDAO<EntityAspectUnion, FooUrn> dao = createDao(FooUrn.class);
Expand Down Expand Up @@ -1325,41 +1362,45 @@ void testUpdateLocalIndex() {
@Test
void testGetGMAIndexPair() {
IndexValue indexValue = new IndexValue();
String aspect = "aspect" + System.currentTimeMillis();
IndexPathParams indexPathParams = new IndexPathParams().setPath("/path1").setValue(indexValue);
IndexCriterion indexCriterion = new IndexCriterion().setAspect(aspect).setPathParams(indexPathParams);

// 1. IndexValue pair corresponds to boolean
indexValue.setBoolean(false);
EbeanLocalDAO.GMAIndexPair gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexValue);
EbeanLocalDAO.GMAIndexPair gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexCriterion);
assertEquals(EbeanMetadataIndex.STRING_COLUMN, gmaIndexPair.valueType);
assertEquals("false", gmaIndexPair.value);
// 2. IndexValue pair corresponds to double
double dVal = 0.000001;
indexValue.setDouble(dVal);
gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexValue);
gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexCriterion);
assertEquals(EbeanMetadataIndex.DOUBLE_COLUMN, gmaIndexPair.valueType);
assertEquals(dVal, gmaIndexPair.value);
// 3. IndexValue pair corresponds to float
float fVal = 0.0001f;
double doubleVal = fVal;
indexValue.setFloat(fVal);
gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexValue);
gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexCriterion);
assertEquals(EbeanMetadataIndex.DOUBLE_COLUMN, gmaIndexPair.valueType);
assertEquals(doubleVal, gmaIndexPair.value);
// 4. IndexValue pair corresponds to int
int iVal = 100;
long longVal = iVal;
indexValue.setInt(iVal);
gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexValue);
gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexCriterion);
assertEquals(EbeanMetadataIndex.LONG_COLUMN, gmaIndexPair.valueType);
assertEquals(longVal, gmaIndexPair.value);
// 5. IndexValue pair corresponds to long
long lVal = 1L;
indexValue.setLong(lVal);
gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexValue);
gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexCriterion);
assertEquals(EbeanMetadataIndex.LONG_COLUMN, gmaIndexPair.valueType);
assertEquals(lVal, gmaIndexPair.value);
// 6/ IndexValue pair corresponds to string
String sVal = "testVal";
indexValue.setString(sVal);
gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexValue);
gmaIndexPair = EbeanLocalDAO.getGMAIndexPair(indexCriterion);
assertEquals(EbeanMetadataIndex.STRING_COLUMN, gmaIndexPair.valueType);
assertEquals(sVal, gmaIndexPair.value);
}
Expand Down

0 comments on commit 682a19c

Please sign in to comment.