DataObjects.borg

DataObjects.borg


`---------------------------------------
` FILE:        DataObjects.borg
` AUTHOR:        Pieter Verheyden
` E-MAIL:        pverheyd@vub.ac.be
` LAST CHANGED:    18/12/2001
`---------------------------------------

{

load("DateFunctions.borg");

` ----------------------------
`    VOID TABLE OBJECT
` ----------------------------

makeVoidTable(thesize):: {
    
    voidtable_[thesize]:void;
    free:1;

    ` return voidtable_
    returnVoidTable():: 
        voidtable_;

    ` get the size of voidtable_
    getSizeVoidTable():: 
        size(voidtable_);

    ` get the element at given index
    ` returns false if the given index is beyond the size of voidtable_
    getElement(index)::
        if(index>size(voidtable_), false, voidtable_[index]);

    ` set given element at given index
    ` returns false if the given index is beyond the size of voidtable_
    setElement(index, element)::
         if(index>size(voidtable_), false, { voidtable_[index]:=element; true });
    
    ` NOTICE: 
    ` "elements" in next functions are non-void elements

    ` get the number of elements in voidtable_
    ` returns 0 if voidtable_ only contains voids
    getNumberElements():: {
        nbr:free-1;
        nbr
    };

    ` check whether an element is in voidtable_
    ` - returns false if the element is not found
    ` - returns the index of the element when found
    elementInVoidTable(element):: {
        found:false;
        for(i:1, ((i<=getNumberElements()) & (found~false)), i:=i+1,
            {
            celement: voidtable_[i];
            if(celement~element, found:=i)
            }
        );
        found
    };

    ` increase the size of voidtable_ by 2
    ` returns void
    increaseVoidTable():: {
        newsize:(size(voidtable_)*2);
        newtable[newsize]:void;
        for(i:1, i<=size(voidtable_), i:=i+1,
            {
            celement: voidtable_[i];
            newtable[i]:= celement
            }
        );
        voidtable_:=newtable;
        void
    };

    ` decrease the size of voidtable_ by 2
    ` returns void
    decreaseVoidTable():: {
        newsize:(size(voidtable_)//2);
        newtable[newsize]:void;
        for(i:1, i<=size(newtable), i:=i+1,
            {
            celement: voidtable_[i];
            newtable[i]:= celement
            }
        );
        voidtable_:=newtable;
        void
    };

    ` add an element to voidtable_
    ` if there are no voids left, voidtable_ should be increased
    ` returns index of next free index    
    addElement(element)::{
        if(free>size(voidtable_), increaseVoidTable());
        voidtable_[free]:=element;
        free:=free+1            
    };

    ` delete an element in voidtable_
    ` leaves no voids between elements
    ` when there are 3 times more voids than elements and the size of voidtable_ != thesize, 
    ` voidtable_ should be decreased
    ` returns false if element is not in voidtable_, else void
    deleteElement(element):: {
        lim:size(voidtable_);
        indexel: elementInVoidTable(element);
        if(!is_false(indexel),
            {
            if(indexel=lim,
                voidtable_[indexel]:=void,
                {    
                i:indexel+1;
                for(i, ((i<=lim) & (!is_void(voidtable_[i]))), i:=i+1, voidtable_[i-1]:=voidtable_[i]);
                voidtable_[i-1]:=void;
                ` decrease the void table if necessary
                if(((lim>thesize) & ((lim/(i-1))>3)), decreaseVoidTable())
                }
            );
            free:=free-1
            },
            false
        )
    };

    ` delete an element at a given index in voidtable_
    ` leaves no voids between elements
    ` when there are 3 times more voids than elements and the size of voidtable_ != thesize, 
    ` voidtable_ should be decreased
    ` returns false if element is not in voidtable_, else void
    deleteElementAtIndex(index):: {
        lim:size(voidtable_);
        if(index<=lim,
            {
            if(index=lim,
                voidtable_[index]:=void,    
                {
                i:index+1;
                for(i, ((i<=lim) & (!is_void(voidtable_[i]))), i:=i+1, voidtable_[i-1]:=voidtable_[i]);
                voidtable_[i-1]:=void;
                ` decrease the void table if necessary
                if(((lim>thesize) & ((lim/(i-1))>3)), decreaseVoidTable())
                }
            );
            free:=free-1
            },
            false
        )
    };

    clone()
};
        


` -----------------------------
`    MEETING TABLE OBJECT
` -----------------------------
 
makeMeetingTable(thesize, callerflag):: {
    
    ` callerflag is a boolean
    ` only the caller may kill meetingagents
    
    ` voidtable to hold the meetings
    meetingtable_: makeVoidTable(thesize);

    ` return meetingtable_
    returnMeetingTable():: meetingtable_.returnVoidTable();

    ` elements of meetingtable : ["tag", , datetable]
    ` tag can be:
    `     R (reservation)
    `     P (participation)
    `     W (waiting)
    addReservation(meetingagent, datetable):: {
        rtable: ["R", meetingagent, datetable];
        meetingtable_.addElement(rtable)
    };

    addWaitingMeetingAgent(meetingagent, datetable):: {
        wtable: ["W", meetingagent, datetable];
        meetingtable_.addElement(wtable)
    };
    
    ` 'reservation' set to 'participation'
    setParticipation(meetingagent):: {
        set:false;
        for(i:1, ((i<=(meetingtable_.getNumberElements())) & (is_false(set))), i:=i+1,
            {
            ctable: meetingtable_.getElement(i);
            if(ctable[1]="R",
                if(ctable[2]~meetingagent, { ctable[1]:="P"; meetingtable_.setElement(i, ctable); set:=true })
            )
            }
        );
        set
    };

    ` check whether a given meetingagent is in meetingtable_
    ` returns the index of the meetingagent when found, if not, false
    meetingAgentInMeetingTable(meetingagent):: {
        found:false;
        for(i:1, ((i<=(meetingtable_.getNumberElements())) & (is_false(found))), i:=i+1,
            {
            ctable: meetingtable_.getElement(i);
            if(ctable[2]~meetingagent, found:=i)
            }
        );
        found
    };

    ` get meetingagent with given datetable in meetingtable_
    ` functions on date(table)s are in DateFunctions.borg
    ` returns the index of the meetingagent if found, if not, false
    getMeetingAgent(datetable):: {
        found:false;
        for(i:1, ((i<=(meetingtable_.getNumberElements())) & (is_false(found))), i:=i+1,
            {
            ctable: meetingtable_.getElement(i);
            if(sameDates(datetable, ctable[3]), found:=ctable[2])
            }
        );
        found
    };

    ` get all participating meetingagents of a given date (day/month/year)
    ` if the meeting is over, the meetingagent is deleted from meetingtable_ (and killed when callerflag true)
    getPMeetingAgents(day, month, year):: {
        meetingagents_: makeVoidTable(4);
        for(i:1, i<=(meetingtable_.getNumberElements()), i:=i+1,
            {
            ctable: meetingtable_.getElement(i);
            if(oldDate(ctable[3]), 
                { 
                if(callerflag, ctable[2]->agentdie());
                meetingtable_.deleteElementAtIndex(i); 
                i:=i-1 
                },
                  {
                cdatetable: ctable[3];
                if(((ctable[1]="P") & (cdatetable[1]=day) & (cdatetable[2]=month) & (cdatetable[3]=year)), meetingagents_.addElement(ctable[2]))
                }
            )
            }
        );
        meetingagents_
    };

    ` check whether a given date does not overlap with the other dates meetingtable_
    ` when an old meetingagent is found, it is deleted from meetingtable_ (and killed when callerflag true)
    checkForFreeTime(datetable):: {
        free:true;
        for(i:1, ((i<=(meetingtable_.getNumberElements())) & free), i:=i+1,
            {
            ctable: meetingtable_.getElement(i);
            if(oldDate(ctable[3]), 
                { 
                if(callerflag, ctable[2]->agentdie());
                meetingtable_.deleteElementAtIndex(i); 
                i:=i-1 
                },
                if(overlappingDates(ctable[3], datetable), free:=false)
            )
            }
        );
        free
    };
    
    ` delete a meetingagent from meetingtable_
    ` returns false if meetingagent is not in meetingtable_
    deleteMeetingAgent(meetingagent):: {
        indexel: meetingAgentInMeetingTable(meetingagent);
        if(!is_false(indexel),
            meetingtable_.deleteElementAtIndex(indexel),
            false
        )
    };

    clone()
}

}