Files
secondo/Algebras/BTree2/op_insertbtree.cpp
2026-01-23 17:03:45 +08:00

392 lines
10 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
//paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}]
//paragraph [10] Footnote: [{\footnote{] [}}]
//[TOC] [\tableofcontents]
[1] Implementation of the insertbtree and insertbtree2 Operators
[TOC]
0 Overview
1 Defines and Includes
*/
#include "op_insertbtree.h"
#include "ListUtils.h"
#include "QueryProcessor.h"
#include "Algebras/Relation-C++/RelationAlgebra.h"
#include "Algebras/TupleIdentifier/TupleIdentifier.h"
#include "Symbols.h"
#include "BTree2.h"
extern NestedList* nl;
extern QueryProcessor *qp;
using namespace std;
namespace BTree2Algebra {
namespace Operators {
/*
2 Operators ~insertbtree~ and ~insertbtree2~
Inserts the entries from the stream into the btree2.
Signatures are
----
insertbtree: stream(tuple(T)) x (btree2 Tk Td u) x ak x ad -->
stream(tuple(T))
insertbtree2: stream(tuple(X@[TID tid])) x (btree2 Tk tid multiple)
x ak --> stream(tuple(X@[TID tid]))
----
2.1 TypeMapping
*/
ListExpr insertbtree::TypeMappingAll(ListExpr args, bool wrapper)
{
if (wrapper){
if(nl->ListLength(args) != 3){
return listutils::typeError("Operator insertbtree expects 3 arguments.");
}
}
else{
if(nl->ListLength(args) != 4){
return listutils::typeError("Operator insertbtree2 expects"
" 4 arguments.");
}
}
/* Split argument in four parts */
ListExpr streamDescription = nl->First(args);
ListExpr btreeDescription = nl->Second(args);
ListExpr nameOfKeyAttribute = nl->Third(args);
ListExpr attrType;
if(!listutils::isTupleStream(streamDescription)){
return listutils::typeError("first arguments must be a tuple stream");
}
ListExpr attrList = nl->Second(nl->Second(streamDescription)); // get attrlist
if (wrapper){
if(nl->ListLength(attrList)<=1){
return listutils::typeError("stream must contain at least 2 attributes");
}
ListExpr rest = nl->Second(nl->Second(streamDescription));
ListExpr next = nl->First(rest);
while (!(nl->IsEmpty(rest)))
{
next = nl->First(rest);
rest = nl->Rest(rest);
}
if(!listutils::isSymbol(nl->Second(next),TupleIdentifier::BasicType())){
return listutils::typeError("last attribute must be of type tid");
}
}
if(!listutils::isBTree2Description(btreeDescription)){
return listutils::typeError("second argument is not a valid btree2");
}
ListExpr btreeValue = nl->Third(btreeDescription);
if (wrapper){
if(!listutils::isSymbol(btreeValue, TupleIdentifier::BasicType())){
return listutils::typeError("Value type of btree has to b tid");
}
if(!listutils::isSymbol(nl->Fourth(btreeDescription), "multiple")){
return listutils::typeError("Keys have to be multiple");
}
}
if(!listutils::isSymbol(nameOfKeyAttribute)){
return listutils::typeError("invalid name for key attribute");
}
/*
Check key
*/
string name;
nl->WriteToString(name, nameOfKeyAttribute);
int keyIndex = listutils::findAttribute(attrList, name, attrType);
if(keyIndex <= 0){
return listutils::typeError("Tuples do not contain an attribute named "
+ name + ".");
}
ListExpr btreeKey = nl->Second(btreeDescription);
if(!nl->Equal(attrType, btreeKey)){
return listutils::typeError( "Key in tuple is "
"different from btree2 key.");
}
/*
Check value-types
*/
int valueIndex = 0;
if (!wrapper){
ListExpr nameOfDataAttribute = nl->Fourth(args);
if(!listutils::isSymbol(nameOfDataAttribute)){
return listutils::typeError("invalid name for data attribute");
}
nl->WriteToString(name, nameOfDataAttribute);
if (name == "none"){
if(!nl->Equal(nameOfDataAttribute, btreeValue)){
return listutils::typeError("Argument value type is different"
" from btree value type.");
}
}
else {
valueIndex = listutils:: findAttribute(attrList, name, attrType);
if(valueIndex <= 0){
return listutils::typeError("Tuples do not contain an "
"attribute named " +
name + ".");
}
if(!nl->Equal(attrType, btreeValue)){
return listutils::typeError("Value type in tuple is "
"different from btree2 value type.");
}
}
}
if (wrapper){
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
nl->TwoElemList(nl->IntAtom(keyIndex), nl->
IntAtom(nl->ListLength(attrList))), streamDescription);
}
else{
return nl->ThreeElemList(nl->SymbolAtom(Symbol::APPEND()),
nl->TwoElemList(nl->IntAtom(keyIndex),
nl->IntAtom(valueIndex)), streamDescription);
}
}
/*
2.1.1 Type map for insertbtree
*/
ListExpr insertbtree::TypeMapping1(ListExpr args){
return insertbtree::TypeMappingAll(args);
}
/*
2.1.2 Type map for insertbtree2
*/
ListExpr insertbtree::TypeMapping2(ListExpr args){
return insertbtree::TypeMappingAll(args, false);
}
/*
2.2 Value mapping for insertbtree
*/
struct vmInfo{
BTree2* btree;
int keyIndex;
int valueIndex;
vmInfo(BTree2* b, int k, int v) : btree(b), keyIndex(k), valueIndex(v) {}
};
int
insertbtree::ValueMapping1(Word* args, Word& result, int message,
Word& local, Supplier s)
{
vmInfo* info;
Tuple* tuple;
Word elem;
Attribute* key;
Attribute* value;
switch (message)
{
case OPEN :
{
BTree2* btree = (BTree2*)args[1].addr;
int k = ((CcInt*)args[3].addr)->GetIntval();
int v = ((CcInt*)args[4].addr)->GetIntval();
info = new vmInfo(btree, k - 1, v - 1);
local.addr = info;
qp->Open(args[0].addr);
return 0;
}
case REQUEST :
{
qp->Request(args[0].addr, elem);
if (qp->Received(args[0].addr))
{
info = (vmInfo*)local.addr;
tuple = (Tuple*)elem.addr;
key = tuple->GetAttribute(info->keyIndex);
value = tuple->GetAttribute(info->valueIndex);
if (((TupleIdentifier*)value)->GetTid() == 0){
tuple->DeleteIfAllowed();
return CANCEL;
}
info->btree->AppendGeneric(key, value);
result.setAddr(tuple);
return YIELD;
}
return CANCEL;
}
case CLOSE :
{
if (local.addr){
info = (vmInfo*)local.addr;
delete info;
local.setAddr(0);
}
qp->Close(args[0].addr);
return 0;
}
}
return 0;
}
/*
2.3 Valuemapping for insertbtree2
*/
int
insertbtree::ValueMapping2(Word* args, Word& result, int message,
Word& local, Supplier s)
{
vmInfo* info;
Tuple* tuple;
Word elem;
Attribute* key;
Attribute* value;
switch (message)
{
case OPEN :
{
BTree2* btree = (BTree2*)args[1].addr;
int k = ((CcInt*)args[4].addr)->GetIntval();
int v = ((CcInt*)args[5].addr)->GetIntval();
info = new vmInfo(btree, k - 1, v - 1);
local.addr = info;
qp->Open(args[0].addr);
return 0;
}
case REQUEST :
{
qp->Request(args[0].addr, elem);
if (qp->Received(args[0].addr))
{
info = (vmInfo*)local.addr;
tuple = (Tuple*)elem.addr;
key = tuple->GetAttribute(info->keyIndex);
if (info->valueIndex == -1){
info->btree->AppendGeneric(key, 0);
}
else{
value = tuple->GetAttribute(info->valueIndex);
info->btree->AppendGeneric(key, value);
}
result.setAddr(tuple);
return YIELD;
}
return CANCEL;
}
case CLOSE :
{
if (local.addr){
info = (vmInfo*)local.addr;
delete info;
local.setAddr(0);
}
qp->Close(args[0].addr);
return 0;
}
}
return 0;
}
/*
2.4 Operator specifications
*/
struct getInsertBTree2Info : OperatorInfo {
getInsertBTree2Info() : OperatorInfo()
{
name = "insertbtree2";
signature = "stream(tuple(T)) x (btree2 Tk Td u) x ak x ad ->"
" stream(tuple(T))";
syntax = "_ _ insertbtree2 [ _, _ ]";
meaning = "Inserts the pairs of values/keys specified by the "
"arguments into the BTree2";
example = "query Staedte feed staedte_btree2 insertbtree2 "
"[SName, Bev] count;";
}
};
struct getInsertBTreeInfo : OperatorInfo {
getInsertBTreeInfo() : OperatorInfo()
{
name = "insertbtree";
signature = "stream(tuple(X@[TID tid])) x (btree2 Tk tid multiple) x ak"
" -> stream(tuple(X@[TID tid]))";
syntax = "_ _ insertbtree [ _ ]";
meaning = "Inserts the pairs of values/keys specified by the "
"arguments into the BTree2";
example = "query Staedte feed addid staedte_btree2_tid "
"insertbtree [SName] count";
}
};
Operator insertbtree::insertbtree1 (getInsertBTreeInfo(), insertbtree::
ValueMapping1, insertbtree::TypeMapping1);
Operator insertbtree::insertbtree2 (getInsertBTree2Info(), insertbtree::
ValueMapping2, insertbtree::TypeMapping2);
} // end namespace operators
} // end namespace btree2algebra