/** * (c) Copyright 2012 WibiData, Inc. * * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * Licensed 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.kiji.mapreduce.kvstore; import java.io.IOException; import org.kiji.annotations.ApiAudience; import org.kiji.annotations.ApiStability; import org.kiji.annotations.Inheritance; import org.kiji.mapreduce.kvstore.framework.KeyValueStoreConfiguration; /** * <p>A KeyValueStore specifies all the resources needed to surface * key-value pairs from some backing store. This may be defined on * files, a Kiji table, or some other resource like a different NoSQL database. * See the {@link org.kiji.mapreduce.kvstore.lib} package for implementations.</p> * * <p>The {@link org.kiji.mapreduce.kvstore.KeyValueStoreReader} interface defines * an implementation that actually accesses these key-value pairs, given * sufficient configuration info from the KeyValueStore itself. KeyValueStoreReaders * are opened by the {@link #open()} method of KeyValueStore.</p> * * <p>Within the Kiji framework, a KeyValueStore may be used within a MapReduce job, * or outside of one, e.g. in a streaming process. In a MapReduce job, it will have access * to the job Configuration. In other environments, it may not have access to the same * resources. * As a result, you should be careful that your KeyValueStore implementation * can be run with the resources available in any expected operating environment. * (For example, you should <i>not</i> use the DistributedCache * in <code>storeToConf()</code> when a KeyValueStore is used within a non-MapReduce process.)</p> * * <h1>Lifecycle in the Kiji ecosystem:</h1> * <p>A KeyValueStore is bound to a name by the KeyValueStoreClient.getRequiredStores() method. * At runtime, you may override these name-to-KeyValueStore bindings * by specifying XML configuration files, or specifying individual name-to-store bindings * programmatically by using a subclass of MapReduceJobBuilder (e.g., KijiProduceJobBuilder). * These KeyValueStores will be instantiated with the default constructor, * the XML will be parsed into configuration name-value pairs, and those will be passed to * <code>initFromConf()</code>. * * <p>In a MapReduce job, configuration will be serialized using * <code>storeToConf()</code>, which copies data into the job Configuration. On the * mapper side, this KeyValueStore will be deserialized by instantiating a KeyValueStore * instance through reflection, which uses the default constructor then initialized with a * single call to <code>initFromConf()</code>. <b>Thus, if you implement this interface, * it is required that you provide a public no-argument constructor so your KeyValueStore * can be used within MapReduce.</b> </p> * * <p>To actually read key-value pairs, get a KeyValueStoreReader with the * <code>open()</code> method. Close it when you're finished using it.</p> * * <p>KeyValueStore implementations may disallow calls to <code>initFromConf()</code> * after calling <code>open()</code>; it's expected that an "opened" KeyValueStore * must be treated as immutable. Implementations may throw InvalidStateException * if you do this.</p> * * @param <K> the key type expected to be implemented by the keys to this store. * @param <V> the value type expected to be accessed by the keys to this store. */ @ApiAudience.Public @ApiStability.Stable @Inheritance.Extensible public interface KeyValueStore<K, V> { /** * Serializes the state of the KeyValueStore into * the provided KeyValueStoreConfiguration. * * @param conf the KeyValueStoreConfiguration to serialize state into. * This will be placed in a unique namespace of the job Configuration, * so it can write any key. * @throws IOException if there is an error writing state to the configuration. */ void storeToConf(KeyValueStoreConfiguration conf) throws IOException; /** * Deserializes the state of this KeyValueStore from the * KeyValueStoreConfiguration. * * @param conf the KeyValueStoreConfiguration storing state for this KeyValueStore. * @throws IOException if there is an error reading from the configuration. */ void initFromConf(KeyValueStoreConfiguration conf) throws IOException; /** * Opens a KeyValueStoreReader instance for access by clients to this store. * After calling this method, some implementations may deny subsequent calls to * initFromConf() by throwing InvalidStateException. * * @return the KeyValueStoreReader associated with this KeyValueStore. * @throws IOException if there is an error opening the underlying storage resource. */ KeyValueStoreReader<K, V> open() throws IOException; }