From f41959ccb2d9d4c722fe8fc3351401d53bcf4900 Mon Sep 17 00:00:00 2001 From: Manjunath Kudlur Date: Fri, 6 Nov 2015 16:27:58 -0800 Subject: TensorFlow: Initial commit of TensorFlow library. TensorFlow is an open source software library for numerical computation using data flow graphs. Base CL: 107276108 --- tensorflow/core/lib/io/two_level_iterator.cc | 148 +++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 tensorflow/core/lib/io/two_level_iterator.cc (limited to 'tensorflow/core/lib/io/two_level_iterator.cc') diff --git a/tensorflow/core/lib/io/two_level_iterator.cc b/tensorflow/core/lib/io/two_level_iterator.cc new file mode 100644 index 0000000000..409baade6d --- /dev/null +++ b/tensorflow/core/lib/io/two_level_iterator.cc @@ -0,0 +1,148 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "tensorflow/core/lib/io/two_level_iterator.h" + +#include "tensorflow/core/lib/io/table.h" +#include "tensorflow/core/lib/io/block.h" +#include "tensorflow/core/lib/io/format.h" +#include "tensorflow/core/lib/io/iterator.h" + +namespace tensorflow { +namespace table { + +namespace { + +typedef Iterator* (*BlockFunction)(void*, const StringPiece&); + +class TwoLevelIterator : public Iterator { + public: + TwoLevelIterator(Iterator* index_iter, BlockFunction block_function, + void* arg); + + virtual ~TwoLevelIterator(); + + virtual void Seek(const StringPiece& target); + virtual void SeekToFirst(); + virtual void Next(); + + virtual bool Valid() const { + return (data_iter_ == nullptr) ? false : data_iter_->Valid(); + } + virtual StringPiece key() const { + assert(Valid()); + return data_iter_->key(); + } + virtual StringPiece value() const { + assert(Valid()); + return data_iter_->value(); + } + virtual Status status() const { + // It'd be nice if status() returned a const Status& instead of a + // Status + if (!index_iter_->status().ok()) { + return index_iter_->status(); + } else if (data_iter_ != NULL && !data_iter_->status().ok()) { + return data_iter_->status(); + } else { + return status_; + } + } + + private: + void SaveError(const Status& s) { + if (status_.ok() && !s.ok()) status_ = s; + } + void SkipEmptyDataBlocksForward(); + void SetDataIterator(Iterator* data_iter); + void InitDataBlock(); + + BlockFunction block_function_; + void* arg_; + Status status_; + Iterator* index_iter_; + Iterator* data_iter_; // May be NULL + // If data_iter_ is non-NULL, then "data_block_handle_" holds the + // "index_value" passed to block_function_ to create the data_iter_. + string data_block_handle_; +}; + +TwoLevelIterator::TwoLevelIterator(Iterator* index_iter, + BlockFunction block_function, void* arg) + : block_function_(block_function), + arg_(arg), + index_iter_(index_iter), + data_iter_(NULL) {} + +TwoLevelIterator::~TwoLevelIterator() { + delete index_iter_; + delete data_iter_; +} + +void TwoLevelIterator::Seek(const StringPiece& target) { + index_iter_->Seek(target); + InitDataBlock(); + if (data_iter_ != NULL) data_iter_->Seek(target); + SkipEmptyDataBlocksForward(); +} + +void TwoLevelIterator::SeekToFirst() { + index_iter_->SeekToFirst(); + InitDataBlock(); + if (data_iter_ != NULL) data_iter_->SeekToFirst(); + SkipEmptyDataBlocksForward(); +} + +void TwoLevelIterator::Next() { + assert(Valid()); + data_iter_->Next(); + SkipEmptyDataBlocksForward(); +} + +void TwoLevelIterator::SkipEmptyDataBlocksForward() { + while (data_iter_ == NULL || !data_iter_->Valid()) { + // Move to next block + if (!index_iter_->Valid()) { + SetDataIterator(NULL); + return; + } + index_iter_->Next(); + InitDataBlock(); + if (data_iter_ != NULL) data_iter_->SeekToFirst(); + } +} + +void TwoLevelIterator::SetDataIterator(Iterator* data_iter) { + if (data_iter_ != NULL) { + SaveError(data_iter_->status()); + delete data_iter_; + } + data_iter_ = data_iter; +} + +void TwoLevelIterator::InitDataBlock() { + if (!index_iter_->Valid()) { + SetDataIterator(NULL); + } else { + StringPiece handle = index_iter_->value(); + if (data_iter_ != NULL && handle.compare(data_block_handle_) == 0) { + // data_iter_ is already constructed with this iterator, so + // no need to change anything + } else { + Iterator* iter = (*block_function_)(arg_, handle); + data_block_handle_.assign(handle.data(), handle.size()); + SetDataIterator(iter); + } + } +} + +} // namespace + +Iterator* NewTwoLevelIterator(Iterator* index_iter, + BlockFunction block_function, void* arg) { + return new TwoLevelIterator(index_iter, block_function, arg); +} + +} // namespace table +} // namespace tensorflow -- cgit v1.2.3