Skip to content

Commit

Permalink
#73 items counting implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
Yegor Bugayenko committed Mar 15, 2016
1 parent 49e5919 commit e85c614
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 6 deletions.
12 changes: 10 additions & 2 deletions src/main/java/com/jcabi/dynamo/AwsFrame.java
Expand Up @@ -30,7 +30,6 @@
package com.jcabi.dynamo;

import com.amazonaws.services.dynamodbv2.model.Condition;
import com.google.common.collect.Iterators;
import com.jcabi.aspects.Immutable;
import com.jcabi.aspects.Loggable;
import java.io.IOException;
Expand Down Expand Up @@ -130,7 +129,16 @@ public Iterator<Item> iterator() {

@Override
public int size() {
return Iterators.size(this.iterator());
try {
return this.valve.count(
this.credentials, this.name, this.conditions
);
} catch (final IOException ex) {
throw new IllegalStateException(
String.format("can't count items in \"%s\"", this.name),
ex
);
}
}

@Override
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/com/jcabi/dynamo/QueryValve.java
Expand Up @@ -177,6 +177,38 @@ public Dosage fetch(final Credentials credentials, final String table,
}
}

@Override
public int count(final Credentials credentials, final String table,
final Map<String, Condition> conditions) throws IOException {
final AmazonDynamoDB aws = credentials.aws();
try {
QueryRequest request = new QueryRequest()
.withTableName(table)
.withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
.withKeyConditions(conditions)
.withConsistentRead(true)
.withSelect(Select.COUNT)
.withLimit(Integer.MAX_VALUE);
if (!this.index.isEmpty()) {
request = request.withIndexName(this.index);
}
final long start = System.currentTimeMillis();
final QueryResult rslt = aws.query(request);
final int count = rslt.getCount();
Logger.info(
this,
// @checkstyle LineLength (1 line)
"#total(): COUNT=%d in '%s' using %s, %s, in %[ms]s",
count, request.getTableName(), request.getQueryFilter(),
AwsTable.print(rslt.getConsumedCapacity()),
System.currentTimeMillis() - start
);
return count;
} finally {
aws.shutdown();
}
}

/**
* With consistent read.
* @param cnst Consistent read
Expand Down
19 changes: 18 additions & 1 deletion src/main/java/com/jcabi/dynamo/ScanValve.java
Expand Up @@ -62,7 +62,7 @@
@Immutable
@ToString
@Loggable(Loggable.DEBUG)
@EqualsAndHashCode(of = { "limit" })
@EqualsAndHashCode(of = { "limit", "attributes" })
public final class ScanValve implements Valve {

/**
Expand Down Expand Up @@ -133,6 +133,23 @@ public Dosage fetch(final Credentials credentials,
}
}

@Override
public int count(final Credentials credentials, final String table,
final Map<String, Condition> conditions) throws IOException {
Dosage dosage = this.fetch(
credentials, table, conditions, Collections.<String>emptyList()
);
int count = 0;
while (true) {
count += dosage.items().size();
if (!dosage.hasNext()) {
break;
}
dosage = dosage.next();
}
return count;
}

/**
* With given limit.
* @param lmt Limit to use
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/jcabi/dynamo/Valve.java
Expand Up @@ -59,4 +59,15 @@ Dosage fetch(Credentials credentials, String table,
Map<String, Condition> conditions, Collection<String> keys)
throws IOException;

/**
* Count items.
* @param credentials Credentials to AWS
* @param table Table name
* @param conditions Conditions
* @return Total count of the
* @throws IOException In case of DynamoDB failure
*/
int count(Credentials credentials, String table,
Map<String, Condition> conditions) throws IOException;

}
7 changes: 7 additions & 0 deletions src/main/java/com/jcabi/dynamo/retry/ReValve.java
Expand Up @@ -81,4 +81,11 @@ public Dosage fetch(final Credentials credentials, final String table,
);
}

@Override
@RetryOnFailure(verbose = false, delay = Tv.FIVE, unit = TimeUnit.SECONDS)
public int count(final Credentials credentials, final String table,
final Map<String, Condition> conditions) throws IOException {
return this.origin.count(credentials, table, conditions);
}

}
29 changes: 26 additions & 3 deletions src/test/java/com/jcabi/dynamo/AwsFrameITCase.java
Expand Up @@ -52,12 +52,35 @@ public void calculatesItems() throws Exception {
final String name = RandomStringUtils.randomAlphabetic(Tv.EIGHT);
final RegionMock mock = new RegionMock();
final Table tbl = mock.get(name).table(name);
final Attributes attrs = new Attributes().with(mock.range(), 1L);
final String hash = "hello";
final Attributes attrs = new Attributes().with(mock.hash(), hash);
for (int idx = 0; idx < Tv.TEN; ++idx) {
tbl.put(attrs.with(mock.hash(), String.format("i%d", idx)));
tbl.put(attrs.with(mock.range(), idx));
}
MatcherAssert.assertThat(
tbl.frame().through(new ScanValve().withLimit(1)).size(),
tbl.frame()
.through(new ScanValve().withLimit(1))
.size(),
Matchers.equalTo(Tv.TEN)
);
MatcherAssert.assertThat(
tbl.frame()
.through(new ScanValve().withLimit(Tv.HUNDRED))
.size(),
Matchers.equalTo(Tv.TEN)
);
MatcherAssert.assertThat(
tbl.frame()
.through(new QueryValve().withLimit(1))
.where(mock.hash(), hash)
.size(),
Matchers.equalTo(Tv.TEN)
);
MatcherAssert.assertThat(
tbl.frame()
.through(new QueryValve().withLimit(Tv.HUNDRED))
.where(mock.hash(), hash)
.size(),
Matchers.equalTo(Tv.TEN)
);
}
Expand Down

0 comments on commit e85c614

Please sign in to comment.