Skip to content
Snippets Groups Projects
Commit 8af3ab9d authored by Alexandr Lyapunov's avatar Alexandr Lyapunov Committed by Roman Tsisyk
Browse files

vinyl: extraxt vy_read_iterator to its own source file

parent bd04983a
No related branches found
No related tags found
No related merge requests found
......@@ -58,6 +58,7 @@ add_library(box STATIC
vy_index.c
vy_tx.c
vy_write_iterator.c
vy_read_iterator.c
vy_cache.c
vy_log.c
vy_upsert.c
......
This diff is collapsed.
This diff is collapsed.
#ifndef INCLUDES_TARANTOOL_BOX_VY_READ_ITERATOR_H
#define INCLUDES_TARANTOOL_BOX_VY_READ_ITERATOR_H
/*
* Copyright 2010-2017, Tarantool AUTHORS, please see AUTHORS file.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdint.h>
#include <stdbool.h>
#include "iterator_type.h"
#include "vy_range.h"
#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */
/**
* Merge iterator takes several iterators as sources and sorts
* output from them by the given order and LSN DESC. It has no filter,
* it just sorts output from its sources.
*
* All statements from all sources can be traversed via
* next_key()/next_lsn() like in a simple iterator (run, mem etc).
* next_key() switches to the youngest statement of
* the next key (according to the order), and next_lsn()
* switches to an older statement of the same key.
*
* There are several merge optimizations, which expect that:
*
* 1) All sources are sorted by age, i.e. the most fresh
* sources are added first.
* 2) Mutable sources are added before read-blocking sources.
*
* The iterator can merge the write set of the current
* transaction, that does not belong to any range but to entire
* index, and mems and runs of some range. For this purpose the
* iterator has a special flag (range_ended) that signals to the
* read iterator that it must switch to the next range.
*/
struct vy_merge_iterator {
/** Array of sources */
struct vy_merge_src *src;
/** Number of elements in the src array */
uint32_t src_count;
/** Number of elements allocated in the src array */
uint32_t src_capacity;
/** Current source offset that merge iterator is positioned on */
uint32_t curr_src;
/** Offset of the first source with is_mutable == true */
uint32_t mutable_start;
/** Next offset after the last source with is_mutable == true */
uint32_t mutable_end;
/** The offset starting with which the sources were skipped */
uint32_t skipped_start;
/** Index key definition. */
const struct key_def *key_def;
/** Format to allocate REPLACE and DELETE tuples. */
struct tuple_format *format;
/** Format to allocate UPSERT tuples. */
struct tuple_format *upsert_format;
/** Set if this iterator is for a primary index. */
bool is_primary;
/* {{{ Range version checking */
/* pointer to index->range_tree_version */
const uint32_t *p_range_tree_version;
/* pointer to index->mem_list_version */
const uint32_t *p_mem_list_version;
/* copy of index->range_tree_version to track range tree changes */
uint32_t range_tree_version;
/* copy of index->mem_list_version to track range tree changes */
uint32_t mem_list_version;
/* pointer to range->version */
const uint32_t *p_range_version;
/* copy of curr_range->version to track mem/run lists changes */
uint32_t range_version;
/* Range version checking }}} */
const struct tuple *key;
/** Iteration type. */
enum iterator_type iterator_type;
/** Current stmt that merge iterator is positioned on */
struct tuple *curr_stmt;
/**
* All sources with this front_id are on the same key of
* current iteration (optimization)
*/
uint32_t front_id;
/**
* For some optimization the flag is set for unique
* index and full key and EQ order - that means that only
* one value is to be emitted by the iterator.
*/
bool is_one_value;
/**
* If index is unique and full key is given we can
* optimize first search in order to avoid unnecessary
* reading from disk. That flag is set to true during
* initialization if index is unique and full key is
* given. After first _get or _next_key call is set to
* false
*/
bool unique_optimization;
/**
* This flag is set to false during initialization and
* means that we must do lazy search for first _get or
* _next call. After that is set to false
*/
bool search_started;
/**
* If all sources marked with belong_range = true comes to
* the end of data this flag is automatically set to true;
* is false otherwise. For read iterator range_ended = true
* means that it must switch to next range
*/
bool range_ended;
};
/**
* Complex read iterator over vinyl index and write_set of current tx
* Iterates over ranges, creates merge iterator for every range and outputs
* the result.
* Can also wor without transaction, just set tx = NULL in _open
* Applyes upserts and skips deletes, so only one replace stmt for every key
* is output
*/
struct vy_read_iterator {
/** Vinyl run environment. */
struct vy_run_env *run_env;
/* index to iterate over */
struct vy_index *index;
/* transaction to iterate over */
struct vy_tx *tx;
/* search options */
enum iterator_type iterator_type;
const struct tuple *key;
const struct vy_read_view **read_view;
/* iterator over ranges */
struct vy_range_iterator range_iterator;
/* current range */
struct vy_range *curr_range;
/* merge iterator over current range */
struct vy_merge_iterator merge_iterator;
struct tuple *curr_stmt;
/* is lazy search started */
bool search_started;
};
/**
* Open the read iterator.
* @param itr Read iterator.
* @param run_env Vinyl run environment.
* @param index Vinyl index to iterate.
* @param tx Current transaction, if exists.
* @param iterator_type Type of the iterator that determines order
* of the iteration.
* @param key Key for the iteration.
* @param vlsn Maximal visible LSN of transactions.
*/
void
vy_read_iterator_open(struct vy_read_iterator *itr, struct vy_run_env *run_env,
struct vy_index *index, struct vy_tx *tx,
enum iterator_type iterator_type, const struct tuple *key,
const struct vy_read_view **rv);
/**
* Get the next statement with another key, or start the iterator,
* if it wasn't started.
* @param itr Read iterator.
* @param[out] result Found statement is stored here.
*
* @retval 0 Success.
* @retval -1 Read error.
*/
NODISCARD int
vy_read_iterator_next(struct vy_read_iterator *itr, struct tuple **result);
/**
* Close the iterator and free resources.
*/
void
vy_read_iterator_close(struct vy_read_iterator *itr);
#if defined(__cplusplus)
} /* extern "C" */
#endif /* defined(__cplusplus) */
#endif /* INCLUDES_TARANTOOL_BOX_VY_READ_ITERATOR_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment