/**
* Copyright 2011 The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.index.coprocessor.wal;
import java.io.IOException;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.WALCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.WALObserver;
import org.apache.hadoop.hbase.index.IndexSpecification;
import org.apache.hadoop.hbase.index.coprocessor.regionserver.IndexRegionObserver;
import org.apache.hadoop.hbase.index.coprocessor.regionserver.IndexRegionObserver.IndexEdits;
import org.apache.hadoop.hbase.index.manager.IndexManager;
import org.apache.hadoop.hbase.index.util.IndexUtils;
import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
import org.apache.hadoop.hbase.util.Bytes;
public class IndexWALObserver implements WALObserver {
private static final Log LOG = LogFactory.getLog(IndexWALObserver.class);
private IndexManager indexManager = IndexManager.getInstance();
@Override
public boolean preWALWrite(ObserverContext<WALCoprocessorEnvironment> ctx, HRegionInfo info,
HLogKey logKey, WALEdit logEdit) throws IOException {
String tableNameStr = info.getTableNameAsString();
if (IndexUtils.isCatalogTable(info.getTableName()) || IndexUtils.isIndexTable(tableNameStr)) {
return true;
}
List<IndexSpecification> indices = indexManager.getIndicesForTable(tableNameStr);
if (indices != null && !indices.isEmpty()) {
LOG.trace("Entering preWALWrite for the table " + tableNameStr);
String indexTableName = IndexUtils.getIndexTableName(tableNameStr);
IndexEdits iEdits = IndexRegionObserver.threadLocal.get();
WALEdit indexWALEdit = iEdits.getWALEdit();
// This size will be 0 when none of the Mutations to the user table to be indexed.
// or write to WAL is disabled for the Mutations
if (indexWALEdit.getKeyValues().size() == 0) {
return true;
}
LOG.trace("Adding indexWALEdits into WAL for table " + tableNameStr);
HRegion indexRegion = iEdits.getRegion();
// TS in all KVs within WALEdit will be the same. So considering the 1st one.
Long time = indexWALEdit.getKeyValues().get(0).getTimestamp();
ctx.getEnvironment()
.getWAL()
.appendNoSync(indexRegion.getRegionInfo(), Bytes.toBytes(indexTableName), indexWALEdit,
logKey.getClusterId(), time, indexRegion.getTableDesc());
LOG.trace("Exiting preWALWrite for the table " + tableNameStr);
}
return true;
}
@Override
public void start(CoprocessorEnvironment env) throws IOException {
}
@Override
public void stop(CoprocessorEnvironment env) throws IOException {
}
@Override
public void postWALWrite(ObserverContext<WALCoprocessorEnvironment> ctx, HRegionInfo info,
HLogKey logKey, WALEdit logEdit) throws IOException {
}
/*
* HLog log =ctx.getEnvironment().getWAL(); List<KeyValue> kvList = logEdit.getKeyValues(); String
* userTableName = info.getEncodedName(); List<IndexSpecification> indices =
* IndexManager.getInstance().getIndicesForTable(userTableName); if(null != indices){
* handleWalEdit(userTableName, log, kvList, indices, info); } return false; } private void
* handleWalEdit(String userTableName, HLog log, List<KeyValue> kvList, List<IndexSpecification>
* indices, HRegionInfo info) { HashMap<byte[], Map<byte[], List<KeyValue>>> myMap = new
* HashMap<byte[], Map<byte[], List<KeyValue>>>(); for (KeyValue kv : kvList) { for
* (IndexSpecification idx : indices) { Set<ColumnQualifier> colSet = idx.getIndexColumns(); for
* (ColumnQualifier col : colSet) { if (Bytes.equals(kv.getFamily(), col.getColumnFamily()) &&
* Bytes.equals(kv.getQualifier(), col.getQualifier())) { Map<byte[], List<KeyValue>>
* mapOfCfToListOfKV = myMap.get(kv.getRow()); if (mapOfCfToListOfKV == null) { mapOfCfToListOfKV
* = new HashMap<byte[], List<KeyValue>>(); myMap.put(kv.getRow(), mapOfCfToListOfKV); } //
* listOfKVs.add(kv); List<KeyValue> listOfKV = mapOfCfToListOfKV.get(idx.getName().getBytes());
* if(listOfKV == null ){ listOfKV = new ArrayList<KeyValue>();
* mapOfCfToListOfKV.put(idx.getName().getBytes(), listOfKV); } listOfKV.add(kv.clone()); } } } }
* createIndexWalEdit(myMap, indices, info); } private void createIndexWalEdit( HashMap<byte[],
* Map<byte[], List<KeyValue>>> myMap, List<IndexSpecification> indices, HRegionInfo info) { int
* totalValueLength = 0; byte[] primaryRowKey = null; byte[] prStartKey = info.getStartKey(); for
* (Map.Entry<byte[], Map<byte[], List<KeyValue>>> mainEntry : myMap .entrySet()) { Map<byte[],
* List<KeyValue>> idxMap = mainEntry.getValue(); for(IndexSpecification index : indices){ byte[]
* name = index.getName().getBytes(); if(null != idxMap.get(name)){ Set<ColumnQualifier> colSet =
* index.getIndexColumns(); for (ColumnQualifier c : colSet) { totalValueLength = totalValueLength
* + c.getMaxValueLength(); } primaryRowKey = mainEntry.getKey(); int rowLength =
* prStartKey.length + name.length; rowLength += totalValueLength; rowLength +=
* primaryRowKey.length; } } } }
*/
}