Skip to content

Commit

Permalink
Added alternate index key generation
Browse files Browse the repository at this point in the history
  • Loading branch information
ghelmling committed Feb 13, 2010
1 parent 72893fb commit c7365ff
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 22 deletions.
92 changes: 71 additions & 21 deletions src/java/meetup/beeno/EntityIndexer.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class EntityIndexer {
private HUtil.HCol dateField;
private boolean invertDate = false;
private List<HUtil.HCol> extraFields;
private IndexKeyFactory keyFactory = new DefaultKeyFactory();

public EntityIndexer(IndexMapping mapping) {
this.indexTable = mapping.getTableName();
Expand All @@ -50,6 +51,15 @@ public EntityIndexer(IndexMapping mapping) {
this.dateField = mapping.getDateField();
this.invertDate = mapping.isDateInverted();
this.extraFields = mapping.getExtraFields();

if (mapping.getKeyFactory() != null) {
try {
this.keyFactory = mapping.getKeyFactory().newInstance();
}
catch (Exception e) {
throw new IllegalArgumentException("Unable to instantiate key factory class", e);
}
}
}

public String getIndexTable() { return this.indexTable; }
Expand Down Expand Up @@ -147,30 +157,70 @@ protected byte[] getValue(byte[] family, byte[] col,
* implementations
*/
public byte[] createIndexKey(byte[] primaryVal, Long date, byte[] origRow) {
byte[] key = new byte[0];
HDataTypes.HField pbVal = PBUtil.readMessage(primaryVal);
// order numeric types
if (pbVal != null && pbVal.getType() == HDataTypes.HField.Type.INTEGER) {
key = Bytes.add(key, HUtil.toOrderedBytes(pbVal.getInteger()));
if (this.dateField != null && date != null) {
return this.keyFactory.createKey(primaryVal, origRow, date, this.invertDate);
}
else {
// just use raw bytes
key = Bytes.add(key, primaryVal);
}

// add on date, if specified
if (this.dateField != null && date != null) {
key = Bytes.add(key,
Bytes.add(ROW_KEY_SEP,
HUtil.toOrderedBytes(date, this.invertDate)) );
return this.keyFactory.createKey(primaryVal, origRow, null, this.invertDate);
}
}


public static class DefaultKeyFactory implements IndexKeyFactory {

@Override
public byte[] createKey( byte[] primaryVal, byte[] rowKey, Long date, boolean invertDate ) {
byte[] key = new byte[0];
HDataTypes.HField pbVal = PBUtil.readMessage(primaryVal);
// order numeric types
if (pbVal != null && pbVal.getType() == HDataTypes.HField.Type.INTEGER) {
key = Bytes.add(key, HUtil.toOrderedBytes(pbVal.getInteger()));
}
else {
// just use raw bytes
key = Bytes.add(key, primaryVal);
}

// add on date, if specified
if (date != null) {
key = Bytes.add(key,
Bytes.add(ROW_KEY_SEP, HUtil.toOrderedBytes(date, invertDate)) );
}

// add on the original row key to ensure uniqueness
if (rowKey != null && rowKey.length > 0) {
key = Bytes.add(key,
Bytes.add(ROW_KEY_SEP, rowKey));
}

return key;
}
}


/**
* Generates the same index keys as DefaultKeyFactory, but prefixed with the primary value mod 100 for
* better row key distribution.
*
* This is designed specifically to avoid hot regions arising from frequently used indexes based off of
* a sequentially incremented primary value.
* @author garyh
*
*/
public static class ModKeyFactory extends DefaultKeyFactory {
private static int base = 100;

// add on the original row key to ensure uniqueness
if (origRow != null && origRow.length > 0) {
key = Bytes.add(key,
Bytes.add(ROW_KEY_SEP, origRow));
public byte[] createKey( byte[] primaryVal, byte[] rowKey, Long date, boolean invertDate) {
byte[] key = new byte[0];
HDataTypes.HField pbVal = PBUtil.readMessage(primaryVal);
// order numeric types
if (pbVal != null && pbVal.getType() == HDataTypes.HField.Type.INTEGER) {
long val = pbVal.getInteger();
key = Bytes.add(Bytes.toBytes(Long.toString( val % base )), ROW_KEY_SEP);
}
key = Bytes.add(key, super.createKey(primaryVal, rowKey, date, invertDate));

return key;
}

return key;
}
}
}
3 changes: 2 additions & 1 deletion src/java/meetup/beeno/HIndex.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@
public @interface HIndex {
String date_col() default "";
boolean date_invert() default false;
String[] extra_cols();
String[] extra_cols() default {};
Class<? extends IndexKeyFactory> key_factory() default EntityIndexer.DefaultKeyFactory.class;
}
6 changes: 6 additions & 0 deletions src/java/meetup/beeno/IndexKeyFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package meetup.beeno;

public interface IndexKeyFactory {

public byte[] createKey(byte[] primaryVal, byte[] rowKey, Long date, boolean invertDate);
}
4 changes: 4 additions & 0 deletions src/java/meetup/beeno/mapping/IndexMapping.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import meetup.beeno.EntityIndexer;
import meetup.beeno.HIndex;
import meetup.beeno.IndexKeyFactory;
import meetup.beeno.util.HUtil;
import meetup.beeno.util.HUtil.HCol;

Expand All @@ -20,6 +21,7 @@ public class IndexMapping {
protected boolean invertDate = false;
protected List<HUtil.HCol> extraFields = new ArrayList<HUtil.HCol>();
protected EntityIndexer generator;
protected Class<? extends IndexKeyFactory> keyFactory;

public IndexMapping(String baseTable, FieldMapping baseField, HIndex indexAnnotation) {
this.indexTable = String.format("%s-by_%s", baseTable, baseField.getColumn());
Expand All @@ -33,6 +35,7 @@ public IndexMapping(String baseTable, FieldMapping baseField, HIndex indexAnnota
if (indexAnnotation.date_col() != null && indexAnnotation.date_col().length() > 0)
this.dateCol = HUtil.HCol.parse(indexAnnotation.date_col());
this.invertDate = indexAnnotation.date_invert();
this.keyFactory = indexAnnotation.key_factory();

this.generator = new EntityIndexer(this);
}
Expand All @@ -43,4 +46,5 @@ public IndexMapping(String baseTable, FieldMapping baseField, HIndex indexAnnota
public boolean isDateInverted() { return this.invertDate; }
public List<HUtil.HCol> getExtraFields() { return this.extraFields; }
public EntityIndexer getGenerator() { return this.generator; }
public Class<? extends IndexKeyFactory> getKeyFactory() { return this.keyFactory; }
}

0 comments on commit c7365ff

Please sign in to comment.