/*
* 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.ignite.internal.processors.hadoop.shuffle.collections;
import java.util.Iterator;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.internal.processors.hadoop.HadoopJobInfo;
import org.apache.ignite.internal.processors.hadoop.HadoopSerialization;
import org.apache.ignite.internal.processors.hadoop.HadoopTaskContext;
import org.apache.ignite.internal.processors.hadoop.HadoopTaskInput;
import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
/**
* Base class for hash multimaps.
*/
public abstract class HadoopHashMultimapBase extends HadoopMultimapBase {
/**
* @param jobInfo Job info.
* @param mem Memory.
*/
protected HadoopHashMultimapBase(HadoopJobInfo jobInfo, GridUnsafeMemory mem) {
super(jobInfo, mem);
}
/** {@inheritDoc} */
@Override public boolean visit(boolean ignoreLastVisited, Visitor v) throws IgniteCheckedException {
throw new UnsupportedOperationException("visit");
}
/** {@inheritDoc} */
@Override public HadoopTaskInput input(HadoopTaskContext taskCtx) throws IgniteCheckedException {
return new Input(taskCtx);
}
/**
* @return Hash table capacity.
*/
public abstract int capacity();
/**
* @param idx Index in hash table.
* @return Meta page pointer.
*/
protected abstract long meta(int idx);
/**
* @param meta Meta pointer.
* @return Key hash.
*/
protected int keyHash(long meta) {
return mem.readInt(meta);
}
/**
* @param meta Meta pointer.
* @return Key size.
*/
protected int keySize(long meta) {
return mem.readInt(meta + 4);
}
/**
* @param meta Meta pointer.
* @return Key pointer.
*/
protected long key(long meta) {
return mem.readLong(meta + 8);
}
/**
* @param meta Meta pointer.
* @return Value pointer.
*/
protected long value(long meta) {
return mem.readLong(meta + 16);
}
/**
* @param meta Meta pointer.
* @param val Value pointer.
*/
protected void value(long meta, long val) {
mem.writeLong(meta + 16, val);
}
/**
* @param meta Meta pointer.
* @return Collision pointer.
*/
protected long collision(long meta) {
return mem.readLong(meta + 24);
}
/**
* @param meta Meta pointer.
* @param collision Collision pointer.
*/
protected void collision(long meta, long collision) {
assert meta != collision : meta;
mem.writeLong(meta + 24, collision);
}
/**
* Reader for key and value.
*/
protected class Reader extends ReaderBase {
/**
* @param ser Serialization.
*/
protected Reader(HadoopSerialization ser) {
super(ser);
}
/**
* @param meta Meta pointer.
* @return Key.
*/
public Object readKey(long meta) {
assert meta > 0 : meta;
try {
return read(key(meta), keySize(meta));
}
catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
}
}
/**
* Task input.
*/
protected class Input implements HadoopTaskInput {
/** */
private int idx = -1;
/** */
private long metaPtr;
/** */
private final int cap;
/** */
private final Reader keyReader;
/** */
private final Reader valReader;
/**
* @param taskCtx Task context.
* @throws IgniteCheckedException If failed.
*/
public Input(HadoopTaskContext taskCtx) throws IgniteCheckedException {
cap = capacity();
keyReader = new Reader(taskCtx.keySerialization());
valReader = new Reader(taskCtx.valueSerialization());
}
/** {@inheritDoc} */
@Override public boolean next() {
if (metaPtr != 0) {
metaPtr = collision(metaPtr);
if (metaPtr != 0)
return true;
}
while (++idx < cap) { // Scan table.
metaPtr = meta(idx);
if (metaPtr != 0)
return true;
}
return false;
}
/** {@inheritDoc} */
@Override public Object key() {
return keyReader.readKey(metaPtr);
}
/** {@inheritDoc} */
@Override public Iterator<?> values() {
return new ValueIterator(value(metaPtr), valReader);
}
/** {@inheritDoc} */
@Override public void close() throws IgniteCheckedException {
keyReader.close();
valReader.close();
}
}
}