All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cz.o2.proxima.direct.randomaccess.RandomAccessReader Maven / Gradle / Ivy

There is a newer version: 0.14.0
Show newest version
/*
 * Copyright 2017-2023 O2 Czech Republic, a.s.
 *
 * 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 cz.o2.proxima.direct.randomaccess;

import cz.o2.proxima.annotations.Stable;
import cz.o2.proxima.direct.core.ContextProvider;
import cz.o2.proxima.direct.core.DirectDataOperator;
import cz.o2.proxima.functional.Consumer;
import cz.o2.proxima.functional.UnaryFunction;
import cz.o2.proxima.repository.AttributeDescriptor;
import cz.o2.proxima.repository.EntityDescriptor;
import cz.o2.proxima.repository.Repository;
import cz.o2.proxima.util.Pair;
import java.io.Closeable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
import lombok.Value;

/**
 * Reader of data stored in random access storage. Every class that implements both {@code
 * AbstractAttributeWriter} and {@code RandomAccessReader} can be used to access data stored at that
 * attribute family by random access. The data can be either get by pair (key, attribute) or scanned
 * through by a mask (key, attributePrefix) for attributes that are wildcard attributes.
 */
@Stable
public interface RandomAccessReader extends Closeable {

  /** {@link Serializable} factory for {@link RandomAccessReader}. */
  @FunctionalInterface
  interface Factory extends UnaryFunction {}

  /** A wraper for a get request. */
  @Value
  class GetRequest {

    public static  GetRequest of(
        String key, String attribute, AttributeDescriptor desc, long stamp) {

      return new GetRequest<>(key, attribute, desc, stamp);
    }

    String key;
    String attribute;
    AttributeDescriptor desc;
    long stamp;
  }

  /** A facade for fetching multiple {@link KeyValue KeyValues} in single request. */
  interface MultiFetch {

    /**
     * Add new {@link GetRequest} to the multi fetch.
     *
     * @param  type of attribute
     * @param request the request to add
     * @return this
     */
     MultiFetch get(GetRequest request);

    /**
     * Perform the multi fetch and pass results through the provided consumer
     *
     * @param consumer consumer to receive results of the multifetch
     */
    void fetch(Consumer, Optional>>> consumer);
  }

  /**
   * Create a new builder that is able to construct {@link RandomAccessReader} from multiple readers
   * responsible for reading from various attribute families.
   *
   * @param repo the {@link Repository}
   * @param context direct translation context provider (e.g. {@link DirectDataOperator})
   * @return new builder for multi random access reader
   */
  static MultiAccessBuilder newBuilder(Repository repo, ContextProvider context) {
    return new MultiAccessBuilder(repo, context.getContext());
  }

  /** Type of listing (either listing entities of entity attributes). */
  enum Listing {
    ENTITY,
    ATTRIBUTE
  }

  /**
   * Construct {@code Offset} from string (representing either key of the entity or attribute).
   *
   * @param type the type of the key
   * @param key the key of entity or attribute
   * @return offset representation of the key
   */
  RandomOffset fetchOffset(Listing type, String key);

  /**
   * Retrieve data stored under given (key, attribute) pair (if any).
   *
   * @param  value type
   * @param key key of the entity
   * @param desc the attribute to search for (not wildcard)
   * @return optional {@link KeyValue} if present
   */
  default  Optional> get(String key, AttributeDescriptor desc) {
    return get(key, desc.getName(), desc, System.currentTimeMillis());
  }

  /**
   * Retrieve data stored under given (key, attribute) pair (if any).
   *
   * @param  value type
   * @param key key of the entity
   * @param desc the attribute to search for (not wildcard)
   * @param stamp timestamp to relatively to which retrieve the data
   * @return optional {@link KeyValue} if present
   */
  default  Optional> get(String key, AttributeDescriptor desc, long stamp) {
    return get(key, desc.getName(), desc, stamp);
  }

  /**
   * Retrieve data stored under given (key, attribute) pair (if any).
   *
   * @param  value type
   * @param key key of the entity
   * @param attribute name of the attribute
   * @param desc the attribute to search for
   * @return optional {@link KeyValue} if present
   */
  default  Optional> get(String key, String attribute, AttributeDescriptor desc) {
    return get(key, attribute, desc, System.currentTimeMillis());
  }

  /**
   * Get single {@link KeyValue} using {@link GetRequest}.
   *
   * @param  value type
   * @param request the request
   * @return optional {@link KeyValue} if present
   */
  default  Optional> get(GetRequest request) {
    return get(request.getKey(), request.getAttribute(), request.getDesc(), request.getStamp());
  }

  /**
   * Retrieve data stored under given (key, attribute) pair (if any).
   *
   * @param  value type
   * @param key key of the entity
   * @param attribute name of the attribute
   * @param desc the attribute to search for
   * @param stamp timestamp to relatively to which retrieve the data
   * @return optional {@link KeyValue} if present
   */
   Optional> get(
      String key, String attribute, AttributeDescriptor desc, long stamp);

  /**
   * Return a facade {@link MultiFetch} object that can be used to queue multiple requests to the
   * storage and fetch them at once using {@link MultiFetch#fetch(Consumer)}.
   *
   * @return the {@link MultiFetch}
   */
  default MultiFetch multiFetch() {
    return new MultiFetch() {

      final List> requests = new ArrayList<>();

      @Override
      public  MultiFetch get(GetRequest request) {
        requests.add(request);
        return this;
      }

      @SuppressWarnings({"rawtypes", "unchecked"})
      @Override
      public void fetch(Consumer, Optional>>> consumer) {
        requests.forEach(
            r -> consumer.accept(Pair.of(r, RandomAccessReader.this.get((GetRequest) r))));
      }
    };
  }

  /**
   * Scan all data stored per given key.
   *
   * @param key the key whose {@link KeyValue}s to scan
   * @param consumer consumer to use for scanning
   */
  default void scanWildcardAll(String key, Consumer> consumer) {
    scanWildcardAll(key, System.currentTimeMillis(), consumer);
  }

  /**
   * Scan all data stored per given key.
   *
   * @param key the key whose {@link KeyValue}s to scan
   * @param stamp timestamp to relatively to which retrieve the data
   * @param consumer consumer to use for scanning
   */
  default void scanWildcardAll(String key, long stamp, Consumer> consumer) {
    scanWildcardAll(key, null, stamp, -1, consumer);
  }

  /**
   * Scan all data stored per given key.
   *
   * @param key the key whose {@link KeyValue}s to scan
   * @param offset offset to start from (next key value will be returned)
   * @param limit how many elements to process at most
   * @param consumer consumer to use for scanning
   */
  default void scanWildcardAll(
      String key, @Nullable RandomOffset offset, int limit, Consumer> consumer) {

    scanWildcardAll(key, offset, System.currentTimeMillis(), limit, consumer);
  }

  /**
   * Scan all data stored per given key.
   *
   * @param key the key whose {@link KeyValue}s to scan
   * @param offset offset to start from (next key value will be returned)
   * @param stamp timestamp to relatively to which retrieve the data
   * @param limit how many elements to process at most
   * @param consumer consumer to use for scanning
   */
  void scanWildcardAll(
      String key,
      @Nullable RandomOffset offset,
      long stamp,
      int limit,
      Consumer> consumer);

  /**
   * List data stored for a particular wildcard attribute.
   *
   * @param  value type
   * @param key key of the entity
   * @param wildcard wildcard attribute to scan
   * @param consumer the consumer to stream data to
   */
  default  void scanWildcard(
      String key, AttributeDescriptor wildcard, Consumer> consumer) {

    scanWildcard(key, wildcard, null, System.currentTimeMillis(), -1, consumer);
  }

  /**
   * List data stored for a particular wildcard attribute.
   *
   * @param  value type
   * @param key key of the entity
   * @param wildcard wildcard attribute to scan
   * @param stamp timestamp to relatively to which retrieve the data
   * @param consumer the consumer to stream data to
   */
  default  void scanWildcard(
      String key, AttributeDescriptor wildcard, long stamp, Consumer> consumer) {

    scanWildcard(key, wildcard, null, stamp, -1, consumer);
  }

  /**
   * List data stored for a particular wildcard attribute.
   *
   * @param  value type
   * @param key key of the entity
   * @param wildcard wildcard attribute to scan
   * @param offset name of attribute (including the prefix) to start from
   * @param limit maximal number of items to consume *
   * @param consumer the consumer to stream data to
   */
  default  void scanWildcard(
      String key,
      AttributeDescriptor wildcard,
      @Nullable RandomOffset offset,
      int limit,
      Consumer> consumer) {

    scanWildcard(key, wildcard, offset, System.currentTimeMillis(), limit, consumer);
  }

  /**
   * List data stored for a particular wildcard attribute.
   *
   * @param  value type
   * @param key key of the entity
   * @param wildcard wildcard attribute to scan
   * @param offset name of attribute (including the prefix) to start from
   * @param stamp timestamp to relatively to which retrieve the data
   * @param limit maximal number of items to consume *
   * @param consumer the consumer to stream data to
   */
   void scanWildcard(
      String key,
      AttributeDescriptor wildcard,
      @Nullable RandomOffset offset,
      long stamp,
      int limit,
      Consumer> consumer);

  /**
   * List all entity keys.
   *
   * @param consumer consumer that will receive keys of entities in the random access storage
   */
  default void listEntities(Consumer> consumer) {
    listEntities(null, Integer.MAX_VALUE, consumer);
  }

  /**
   * List all entity keys with offset and limit.
   *
   * @param offset offset of the entities
   * @param limit limit for number of results
   * @param consumer consumer of results
   */
  void listEntities(
      @Nullable RandomOffset offset, int limit, Consumer> consumer);

  /**
   * Retrieve entity associated with this reader.
   *
   * @return entity associated with this reader
   */
  EntityDescriptor getEntityDescriptor();

  /**
   * Convert instance of this reader to {@link Factory} suitable for serialization.
   *
   * @return the {@link Factory} representing this reader
   */
  Factory asFactory();
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy