blob: 7659a1b4e434dc36d602852ddd840ac0dcf8715d [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 @@@
**********************************************************************/
/* -*-C++-*-
****************************************************************************
*
* File: ComQueue.h
* Description:
*
* Created: 5/6/98
* Language: C++
*
*
*
*
****************************************************************************
*/
#ifndef COMQUEUE_H
#define COMQUEUE_H
#include "NABasicObject.h"
#include "NAVersionedObject.h"
// ---------------------------------------------------------------------
// The PackQueue macros provide a way to really pack the "whole" queue.
// This includes the backbone of the queue as well as objects referenced
// by the (void *) in the Q_Entry's. The real class identity of those
// objects is passed as a parameter to the macros. Depending on whether
// those objects belong to a derived class of NAVersionedObject or not,
// either drivePack() or pack() will be called. Note that queuePtr has
// to be of type "QueuePtr".
// ---------------------------------------------------------------------
#define PackQueueOfNAVersionedObjects(queuePtr, space, Type) \
if (queuePtr) \
{ \
Type * entry; \
queuePtr->position(); \
while ((entry = (Type *)(queuePtr->getNext())) != NULL) \
entry->drivePack(space); \
queuePtr.pack(space); \
}
#define PackQueueOfNonNAVersionedObjects(queuePtr, space, Type) \
if (queuePtr) \
{ \
Type * entry; \
queuePtr->position(); \
while ((entry = (Type *)(queuePtr->getNext())) != NULL) \
entry->pack(space); \
queuePtr.pack(space); \
}
#define UnpackQueueOfNAVersionedObjects(queuePtr, base, Type, Reallocator) \
if (queuePtr) \
{ \
if(queuePtr.unpack(base,reallocator)) return -1; \
Type * entry; \
queuePtr->position(); \
while ((entry = (Type *)(queuePtr->getNext())) != NULL) \
{ \
Type obj; \
entry->driveUnpack(base,&obj,reallocator); \
} \
}
#define UnpackQueueOfNonNAVersionedObjects(queuePtr, base, Type) \
if (queuePtr) \
{ \
if(queuePtr.unpack(base)) return -1; \
Type * entry; \
queuePtr->position(); \
while ((entry = (Type *)(queuePtr->getNext())) != NULL) \
{ \
entry->fixupVTblPtr(); \
entry->unpack(base); \
} \
}
// ---------------------------------------------------------------------
// Template instantiation to produce a 64-bit pointer emulator class
// for Q_Entry
// ---------------------------------------------------------------------
class Q_Entry;
typedef NAOpenObjectPtrTempl<Q_Entry> Q_EntryPtr;
class Q_Entry
{
friend class Queue;
NABasicPtr entry; // 00-07
Q_EntryPtr prev; // 08-15
Q_EntryPtr next; // 16-23
UInt32 packedLength_; // 24-27
char fillersQ_Entry_[20]; // 28-47
public:
Q_Entry(void * entry_, Q_Entry * prev_, Q_Entry * next_);
~Q_Entry();
Long pack(void *space);
Lng32 unpack(void *base);
ULng32 packedLength() { return packedLength_; }
};
class Queue : public NAVersionedObject
{
Q_EntryPtr head; // 00-07
Q_EntryPtr tail; // 08-15
Q_EntryPtr curr; // 16-23
CollHeap *heap_;
Int32 numEntries_; // 32-35
// length of queue in 'packed' (contiguous) form.
// This field is updated whenever a new queue entry is added (removed).
UInt32 packedLength_; // 36-39
UInt16 flags_; // 40-41
char fillersQueue_[14]; // 42-55
enum {
// if set, then remove doesn't deletes Q_Entry, only makes the
// entry pointer NULL.
// Insert is done at the first empty Q_Entry.
// remove removes the head entry and moves it to the end
// of the list.
DO_SPACE_OPT = 0x0001
};
public:
Queue();
// ---------------------------------------------------------------------
// Redefine virtual functions required for Versioning.
//----------------------------------------------------------------------
virtual unsigned char getClassVersionID()
{
return 1;
}
virtual void populateImageVersionIDArray()
{
setImageVersionID(0,getClassVersionID());
}
virtual short getClassSize() { return (short)sizeof(Queue); }
Queue(CollHeap * heap);
~Queue();
// inserts at tail
void insert(const void * entry_, ULng32 entryPackedLength = 0);
// inserts at tail, returns addr of Queue entry inserted
void insert(const void * entry_, ULng32 entryPackedLength,
void ** queueEntry);
// returns the head entry
void * get();
// returns the i'th entry. 0 based. First entry is i = 0
void * get(ULng32 i);
// returns the head entry
void * getHead();
// returns the tail(last) entry
void * getTail();
// positions on the head entry
void position();
// positions on a specified Queue entry
void position(void * queueEntry);
// returns the current entry
void * getCurr();
// advances the current entry
void advance();
// returns the current entry and advances curr
void * getNext();
// returns -1, if all entries have been returned.
short atEnd();
// removes the head entry
void remove();
// removes the head entry
void removeHead() { remove(); };
// removes the tail entry
void removeTail();
void removeWithSpaceOpt();
// removes the 'entry' entry
NABoolean remove(void * entry);
virtual Long pack(void * space);
virtual Lng32 unpack(void * base, void * reallocator);
// returns -1, if queue is empty. Otherwise, returns 0.
Int32 isEmpty()
{
return ((numEntries() == 0) ? -1 : 0);
}
Lng32 numEntries() { return numEntries_;}
Lng32 entries() { return numEntries();}
ULng32 packedLength() { return packedLength_; }
void setDoSpaceOpt(short v) {(v ? flags_ |= DO_SPACE_OPT : flags_ &= ~DO_SPACE_OPT); };
NABoolean doSpaceOpt() { return (flags_ & DO_SPACE_OPT) != 0; };
};
// ---------------------------------------------------------------------
// Template instantiation to produce a 64-bit pointer emulator class
// for Queue
// ---------------------------------------------------------------------
typedef NAVersionedObjectPtrTempl<Queue> QueuePtr;
// A HashQueue is basically a container which is accessed by
// hashing. It is introduced here to speed up the statement
// and descriptor lookup in the sqlcli. The statement- and
// descriptor lists were originally implemented as Queues. Lookup
// was always just a sequential search in this list. Note
// that the following is a quick and dirty implementation
// to eliviate this performance problem. If we would only
// have more time (sigh), a better design would be a template
// based implementation of containers (lists, arrays, queues,
// stacks, you name it) for the executor similar to the collections
// in the compiler.
class HashQueueEntry {
friend class HashQueue;
public:
HashQueueEntry(void * entry,
HashQueueEntry * prev,
HashQueueEntry * next,
ULng32 hashValue)
: entry_(entry),
prev_(prev),
next_(next),
hashValue_(hashValue) {
};
~HashQueueEntry() {
};
private:
HashQueueEntry * prev_;
HashQueueEntry * next_;
void * entry_;
ULng32 hashValue_;
};
class HashQueue : public NABasicObject {
public:
HashQueue(CollHeap * heap, ULng32 hashTableSize = 513);
HashQueue(const NABoolean shadowCopy,
const HashQueue &other);
~HashQueue();
ULng32 entries() { return entries_; }
ULng32 size() { return hashTableSize_; }
void insert(const char * data, ULng32 dataLength, void * entry);
// position by hashing
void position(const char * data, ULng32 dataLength);
// position globally
void position();
void * getNext();
// returns the current entry
void * getCurr();
// advances the current entry
void advance();
void remove(void * entry);
// To remove the last returned entry via getNext() in case of global scan
// of hash queue
void remove();
// To remove the entry by passing in the hashing fields and the corresponding entry
void remove(const char *data, ULng32 dataLength, void *entry);
Lng32 numEntries() { return (Lng32)entries_;}
NABoolean sequentialAdd() { return (flags_ & SEQUENTIAL_ADD) != 0; }
void setSequentialAdd(NABoolean v)
{ (v ? flags_ |= SEQUENTIAL_ADD : flags_ &= ~SEQUENTIAL_ADD); }
Int32 isEmpty() { return ((entries_ == 0) ? -1 : 0); }
private:
enum Flags
{
// add hash entries in a sequential order (the same order in which
// they are inserted).
SEQUENTIAL_ADD = 0x0001
};
ULng32 entries_; // number of entries in this HashQueue
ULng32 hashTableSize_; // size of the hash table
HashQueueEntry ** hashTable_; // the hash table itself
HashQueueEntry * lastReturned_; // the last entry returned by getNext()
HashQueueEntry * current_; // points to the current entry
ULng32 currentChain_; // the chain were current_ is located
ULng32 hashValue_; // hash value of the last position
NABoolean globalScan_; // if true, getNext ignores hashValue
CollHeap * heap_; // the heap a HashQueue allocates from
NABoolean shadowCopy_; // TRUE if constructed by shadow copy
ULng32 flags_;
void getHashValue(const char * data, ULng32 dataLength);
void removeLastReturned();
};
class SyncHashQueue : public HashQueue {
public:
SyncHashQueue(CollHeap * heap, ULng32 hashTableSize = 513);
void position(const char * data, ULng32 dataLength);
void position();
void remove(void * entry);
void remove();
void remove(const char *data, ULng32 dataLength, void *entry);
void insert(const char * data, ULng32 dataLength, void * entry);
};
#endif