Resized thumbnails; async; extend MatrixCursor.

When requesting thumbnails, check if their dimensions are larger
than requested, and downscale to avoid memory pressure.  Load them
async and with LruCache.

Extend MatrixCursor so that RowBuilder can offer() columns without
requiring they know the projection map.  This makes it easier to
respond to query() calls, where the remote side controls the
projection map.  Use it to handle custom projections in external
storage backend.

Update date/time formatting to match spec.

Bug: 10333418, 10331689
Change-Id: I7e947a8e8068af8a39b55e6766b3241de4f3fc16
This commit is contained in:
Jeff Sharkey
2013-05-07 12:41:33 -07:00
parent a5599ef636
commit 9d0843df7e
9 changed files with 307 additions and 70 deletions

View File

@@ -83,11 +83,10 @@ public class MatrixCursor extends AbstractCursor {
* row
*/
public RowBuilder newRow() {
rowCount++;
int endIndex = rowCount * columnCount;
final int row = rowCount++;
final int endIndex = rowCount * columnCount;
ensureCapacity(endIndex);
int start = endIndex - columnCount;
return new RowBuilder(start, endIndex);
return new RowBuilder(row);
}
/**
@@ -180,18 +179,29 @@ public class MatrixCursor extends AbstractCursor {
}
/**
* Builds a row, starting from the left-most column and adding one column
* value at a time. Follows the same ordering as the column names specified
* at cursor construction time.
* Builds a row of values using either of these approaches:
* <ul>
* <li>Values can be added with explicit column ordering using
* {@link #add(Object)}, which starts from the left-most column and adds one
* column value at a time. This follows the same ordering as the column
* names specified at cursor construction time.
* <li>Column and value pairs can be offered for possible inclusion using
* {@link #offer(String, Object)}. If the cursor includes the given column,
* the value will be set for that column, otherwise the value is ignored.
* This approach is useful when matching data to a custom projection.
* </ul>
* Undefined values are left as {@code null}.
*/
public class RowBuilder {
private int index;
private final int row;
private final int endIndex;
RowBuilder(int index, int endIndex) {
this.index = index;
this.endIndex = endIndex;
private int index;
RowBuilder(int row) {
this.row = row;
this.index = row * columnCount;
this.endIndex = index + columnCount;
}
/**
@@ -210,6 +220,21 @@ public class MatrixCursor extends AbstractCursor {
data[index++] = columnValue;
return this;
}
/**
* Offer value for possible inclusion if this cursor defines the given
* column. Columns not defined by the cursor are silently ignored.
*
* @return this builder to support chaining
*/
public RowBuilder offer(String columnName, Object value) {
for (int i = 0; i < columnNames.length; i++) {
if (columnName.equals(columnNames[i])) {
data[(row * columnCount) + i] = value;
}
}
return this;
}
}
// AbstractCursor implementation.