@Override public Collection<Pair<Mutation, byte[]>> getIndexUpdate(Mutation mutation, IndexMetaData indexMetaData) throws IOException { // create a state manager, so we can manage each batch LocalTableState state = new LocalTableState(localTable, mutation); // build the index updates for each group IndexUpdateManager manager = new IndexUpdateManager(indexMetaData); batchMutationAndAddUpdates(manager, state, mutation, indexMetaData); if (LOG.isTraceEnabled()) { LOG.trace("Found index updates for Mutation: " + mutation + "\n" + manager); } return manager.toMap(); }
/** * @param updates */ public void addAll(Collection<Pair<Mutation, String>> updates) { for (Pair<Mutation, String> update : updates) { addIndexUpdate(Bytes.toBytes(update.getSecond()), update.getFirst()); } }
/** * Add an index update. Keeps the latest {@link Put} for a given timestamp * @param tableName * @param m */ public void addIndexUpdate(byte[] tableName, Mutation m) { // we only keep the most recent update ImmutableBytesPtr key = new ImmutableBytesPtr(tableName); Collection<Mutation> updates = map.get(key); if (updates == null) { updates = new TreeSet<Mutation>(COMPARATOR); map.put(key, updates); } if (indexMetaData.getReplayWrite() != null) { // if we're replaying mutations, we don't need to worry about out-of-order updates updates.add(m); } else { fixUpCurrentUpdates(updates, m); } }
IndexUpdateManager manager = new IndexUpdateManager(mockIndexMetaData); manager.addIndexUpdate(table, d); manager.addIndexUpdate(table, p); List<Mutation> pending = new ArrayList<Mutation>(); pending.add(p); manager.addIndexUpdate(table, d2); pending.add(d); validate(manager, pending); manager.addIndexUpdate(table, d3); pending.add(d); validate(manager, pending); manager = new IndexUpdateManager(mockIndexMetaData); manager.addIndexUpdate(table, d2); manager.addIndexUpdate(table, p); validate(manager, Collections.<Mutation> emptyList()); manager = new IndexUpdateManager(mockIndexMetaData); manager.addIndexUpdate(table, p); manager.addIndexUpdate(table, p1); manager.addIndexUpdate(table, d4); pending.clear(); pending.add(p);
public List<Pair<Mutation, byte[]>> toMap() { List<Pair<Mutation, byte[]>> updateMap = Lists.newArrayList(); for (Entry<ImmutableBytesPtr, Collection<Mutation>> updates : map.entrySet()) { // get is ok because we always set with just the bytes byte[] tableName = updates.getKey().get(); for (Mutation m : updates.getValue()) { // skip elements that have been marked for delete if (shouldBeRemoved(m)) { continue; } updateMap.add(new Pair<Mutation, byte[]>(m, tableName)); } } return updateMap; }
@Test public void testMutationComparator() throws Exception { IndexUpdateManager manager = new IndexUpdateManager(mockIndexMetaData); Comparator<Mutation> comparator = manager.COMPARATOR; Put p = new Put(row, 10); // lexigraphically earlier should sort earlier Put p1 = new Put(Bytes.toBytes("ro"), 10); assertTrue("lexigraphically later sorting first, should be earlier first.", comparator.compare(p, p1) > 0); p1 = new Put(Bytes.toBytes("row1"), 10); assertTrue("lexigraphically later sorting first, should be earlier first.", comparator.compare(p1, p) > 0); // larger ts sorts before smaller, for the same row p1 = new Put(row, 11); assertTrue("Smaller timestamp sorting first, should be larger first.", comparator.compare(p, p1) > 0); // still true, even for deletes Delete d = new Delete(row, 11); assertTrue("Smaller timestamp sorting first, should be larger first.", comparator.compare(p, d) > 0); // for the same row, t1, the delete should sort earlier d = new Delete(row, 10); assertTrue("Delete doesn't sort before put, for the same row and ts", comparator.compare(p, d) > 0); // but for different rows, we still respect the row sorting. d = new Delete(Bytes.toBytes("row1"), 10); assertTrue("Delete doesn't sort before put, for the same row and ts", comparator.compare(p, d) < 0); }
private void validate(IndexUpdateManager manager, List<Mutation> pending) { for (Pair<Mutation, byte[]> entry : manager.toMap()) { assertEquals("Table name didn't match for stored entry!", table, entry.getSecond()); Mutation m = pending.remove(0); // test with == to match the exact entries, Mutation.equals just checks the row assertTrue( "Didn't get the expected mutation! Expected: " + m + ", but got: " + entry.getFirst(), m == entry.getFirst()); } assertTrue("Missing pending updates: " + pending, pending.isEmpty()); } }
markMutationForRemoval(stored); return; if (pendingDelete != null) { markMutationForRemoval(pendingMutation); break;
@Override public String toString() { StringBuffer sb = new StringBuffer("Pending Index Updates:\n"); for (Entry<ImmutableBytesPtr, Collection<Mutation>> entry : map.entrySet()) { String tableName = Bytes.toStringBinary(entry.getKey().get()); sb.append(" Table: '" + tableName + "'\n"); for (Mutation m : entry.getValue()) { sb.append("\t"); if (shouldBeRemoved(m)) { sb.append("[REMOVED]"); } sb.append(m.getClass().getSimpleName() + ":" + ((m instanceof Put) ? m.getTimeStamp() + " " : "")); sb.append(" row=" + Bytes.toStringBinary(m.getRow())); sb.append("\n"); if (m.getFamilyCellMap().isEmpty()) { sb.append("\t\t=== EMPTY ===\n"); } for (List<Cell> kvs : m.getFamilyCellMap().values()) { for (Cell kv : kvs) { sb.append("\t\t" + kv.toString() + "/value=" + Bytes.toStringBinary(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength())); sb.append("\n"); } } } } return sb.toString(); } }
markMutationForRemoval(stored); return; if (pendingDelete != null) { markMutationForRemoval(pendingMutation); break;
@Override public Collection<Pair<Mutation, byte[]>> getIndexUpdate(Mutation mutation, IndexMetaData indexMetaData) throws IOException { // create a state manager, so we can manage each batch LocalTableState state = new LocalTableState(localTable, mutation); // build the index updates for each group IndexUpdateManager manager = new IndexUpdateManager(indexMetaData); batchMutationAndAddUpdates(manager, state, mutation, indexMetaData); if (LOG.isTraceEnabled()) { LOG.trace("Found index updates for Mutation: " + mutation + "\n" + manager); } return manager.toMap(); }
updateMap.addIndexUpdate(d.getTableName(), remove);
public List<Pair<Mutation, byte[]>> toMap() { List<Pair<Mutation, byte[]>> updateMap = Lists.newArrayList(); for (Entry<ImmutableBytesPtr, Collection<Mutation>> updates : map.entrySet()) { // get is ok because we always set with just the bytes byte[] tableName = updates.getKey().get(); for (Mutation m : updates.getValue()) { // skip elements that have been marked for delete if (shouldBeRemoved(m)) { continue; } updateMap.add(new Pair<Mutation, byte[]>(m, tableName)); } } return updateMap; }
/** * Add an index update. Keeps the latest {@link Put} for a given timestamp * @param tableName * @param m */ public void addIndexUpdate(byte[] tableName, Mutation m) { // we only keep the most recent update ImmutableBytesPtr key = new ImmutableBytesPtr(tableName); Collection<Mutation> updates = map.get(key); if (updates == null) { updates = new TreeSet<Mutation>(COMPARATOR); map.put(key, updates); } if (indexMetaData.getReplayWrite() != null) { // if we're replaying mutations, we don't need to worry about out-of-order updates updates.add(m); } else { fixUpCurrentUpdates(updates, m); } }
markMutationForRemoval(stored); return; if (pendingDelete != null) { markMutationForRemoval(pendingMutation); break;
@Override public Collection<Pair<Mutation, byte[]>> getIndexUpdate(Mutation mutation, IndexMetaData indexMetaData) throws IOException { // create a state manager, so we can manage each batch LocalTableState state = new LocalTableState(localTable, mutation); // build the index updates for each group IndexUpdateManager manager = new IndexUpdateManager(indexMetaData); batchMutationAndAddUpdates(manager, state, mutation, indexMetaData); if (LOG.isTraceEnabled()) { LOG.trace("Found index updates for Mutation: " + mutation + "\n" + manager); } return manager.toMap(); }
byte[] table = update.getTableName(); Mutation mutation = update.getUpdate(); updateMap.addIndexUpdate(table, mutation);
public List<Pair<Mutation, byte[]>> toMap() { List<Pair<Mutation, byte[]>> updateMap = Lists.newArrayList(); for (Entry<ImmutableBytesPtr, Collection<Mutation>> updates : map.entrySet()) { // get is ok because we always set with just the bytes byte[] tableName = updates.getKey().get(); for (Mutation m : updates.getValue()) { // skip elements that have been marked for delete if (shouldBeRemoved(m)) { continue; } updateMap.add(new Pair<Mutation, byte[]>(m, tableName)); } } return updateMap; }
/** * Add an index update. Keeps the latest {@link Put} for a given timestamp * @param tableName * @param m */ public void addIndexUpdate(byte[] tableName, Mutation m) { // we only keep the most recent update ImmutableBytesPtr key = new ImmutableBytesPtr(tableName); Collection<Mutation> updates = map.get(key); if (updates == null) { updates = new TreeSet<Mutation>(COMPARATOR); map.put(key, updates); } if (indexMetaData.getReplayWrite() != null) { // if we're replaying mutations, we don't need to worry about out-of-order updates updates.add(m); } else { fixUpCurrentUpdates(updates, m); } }
/** * @param updates */ public void addAll(Collection<Pair<Mutation, String>> updates) { for (Pair<Mutation, String> update : updates) { addIndexUpdate(Bytes.toBytes(update.getSecond()), update.getFirst()); } }