blob: 861dd449f8ed1a1a0bd966b332aa8fcc132cfe23 [file] [log] [blame]
// **********************************************************************
// @@@ START COPYRIGHT @@@
//
// 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.
//
// @@@ END COPYRIGHT @@@
// **********************************************************************
#ifndef TUPLESPACE_H
#define TUPLESPACE_H
//
// TupleSpace.h
//
// A TupleSpace stores tuple data, overflowing to temporary storage
// that occurs when memory limits are encountered. Data is written
// at the end of the TupleSpace and is read sequentially starting at
// the current read position. Tuple data can be read more than once
// by rewinding the current position to the beginning of the data.
//
class ex_cri_desc;
class ExSubtask;
#include "NABasicObject.h"
#include "ExOverflow.h"
#include "Allocator.h"
#include "BufferList.h"
#include "BufferReference.h"
#include "SwapSpace.h"
#include "CommonStructs.h"
namespace ExOverflow
{
class TupleSpace : public NABasicObject
{
public:
// TupleSpace constructor. If overflow to disk is enabled, the
// nBuffers value must be at least MIN_INITIAL_BUFFERS; otherwise
// nBuffers must be at least one.
TupleSpace(ByteCount tupleLen, BufferCount nBuffers,
ByteCount bufferSize, UInt32 memoryQuotaMB,
ex_expr* copyExpr, ex_cri_desc* criDesc,
NAMemory* heap, bool enableOverflow,
ExExeStmtGlobals* stmtGlobals,
UInt16 scratchThresholdPct,
ScratchOverflowMode ovMode,bool yieldQuota);
~TupleSpace(void);
// Default TupleSpace configuration is to initially allocate
// four 56 KB buffers, then allocate more buffers as needed
// subject to memory constraints. Two of these buffers are
// reserved for use as I/O buffers; the third buffer is used as
// the write_ buffer, and the fourth buffer is used as a
// readCache_ buffer. Some regression tests use a smaller
// 2048-byte buffer to make it easier to test merge join
// overflow to temporary storage. (NSK unbuffered I/O must be a
// multiple of 2 KB).
#if defined(NA_HAS_ANSI_CONST)
static const ByteCount OVERFLOW_TEST_BUFFER_SIZE = 2048;
static const ByteCount OVERFLOW_BUFFER_SIZE = 56 * 1024 * 4;
static const BufferCount NUM_RESERVE_BUFFERS = 2;
static const BufferCount MIN_INITIAL_BUFFERS = 4;
#else
enum { OVERFLOW_TEST_BUFFER_SIZE = 2048 };
enum { OVERFLOW_BUFFER_SIZE = 56 * 1024 * 4 };
enum { NUM_RESERVE_BUFFERS = 2 };
enum { MIN_INITIAL_BUFFERS = 4 };
#endif
// Advance the current tuple position to the next tuple
IoStatus advance(void);
// Set currentAtp to the current tuple position
IoStatus current(atp_struct*& currentAtp);
// Discard all tuple data
void discard(void);
// Is TupleSpace empty?
bool empty(void);
// Return the maximum number of bytes allocated since
// the last reacquireResources call.
ByteCount64 getMaxMemory(void) const;
// Return the number of bytes currently allocated
ByteCount64 getMemory(void) const;
// Return the last system (OS or FS) error
Int16 getLastError(void);
// Return the last SQLCODE (temporary storage I/O error)
Int16 getLastSqlCode(void);
// Return the memory manager quota in megabytes
UInt32 getQuotaMB(void) const;
// Insert tuple data into the write_ buffer
IoStatus insert(atp_struct* row, atp_struct **rtApt);
// Reset the current tuple position to the first tuple
IoStatus rewind(void);
// Reacquire TupleSpace resources (undo releaseResources).
// Failure to reacquire resources is fatal.
void reacquireResources(void);
// Release resources for use by other SQL/MX operators
void releaseResources(void);
// Set NSK-only ScratchFileConnection I/O event handler task
void setIoEventHandler(ExSubtask* ioEventHandler);
private:
#if defined(NA_HAS_ANSI_CONST)
// ATP index for contiguous saved duplicate right row tupp
static const Int16 SAVED_DUP_ATP_INDEX = 2;
#else
enum { SAVED_DUP_ATP_INDEX = 2 };
#endif
// Type of buffer read_ references:
enum ReadBufferType { BT_INVALID, BT_CACHE_BUFFER, BT_SWAP_BUFFER,
BT_WRITE_BUFFER };
// Attempt to save a full write buffer in the read cache.
bool cacheWriteBuffer(void);
IoStatus completeFetch(bool* newReadBuffer = NULL);
atp_struct* getAtp(const BufferReference& br);
// Set up initial write_ buffer. Failure is fatal.
void getInitialBuffer(void);
// Return the type of buffer read_ references
ReadBufferType getReadBufferType(void);
// Does read_ buffer have unread tuple data?
bool canReadTuples(void);
bool isReadBuffer(char* buffer);
bool isReadBuffer(const BufferReference &br);
bool isWriteBuffer(char* buffer);
bool isWriteBuffer(const BufferReference &br);
// Ensure the write_ buffer has space to store a tuple.
IoStatus makeRoom(void);
IoStatus nextReadBuffer(void);
void promoteSwapBuffer(void);
void reset(bool allDone);
void resetAtp(void);
void reuseCacheBuffers(void);
void setInitialBuffer(char* buffer);
private:
UInt64 currentTuple_; // current tuple number (0..N-1)
UInt64 nTuples_; // number of tuples in TupleSpace
atp_struct* atp_; // ATP for accessing tuple data
ex_expr* copyExpr_; // cached copyExpr()
Allocator memory_; // memory allocator
bool overflowEnabled_; // is overflow enabled?
BufferReference read_; // read position
BufferList readCache_; // read buffer cache
BufferReference start_; // start of data
SwapSpace swap_; // swapped out buffer manager
ByteCount tupleLen_; // bytes per tuple
BufferReference write_; // write position
};
inline
bool
TupleSpace::empty(void)
{
return (nTuples_ == 0);
}
inline
bool
TupleSpace::canReadTuples(void)
{
return (read_.bytesAvailable() >= tupleLen_);
}
inline
bool
TupleSpace::isReadBuffer(char* buffer)
{
return BufferReference::sameBuffer(read_, buffer);
}
inline
bool
TupleSpace::isReadBuffer(const BufferReference& br)
{
return BufferReference::sameBuffer(read_, br);
}
inline
bool
TupleSpace::isWriteBuffer(char* buffer)
{
return BufferReference::sameBuffer(write_, buffer);
}
inline
bool
TupleSpace::isWriteBuffer(const BufferReference& br)
{
return BufferReference::sameBuffer(write_, br);
}
}
#endif