From: bdemsky Date: Thu, 16 Jul 2009 10:00:58 +0000 (+0000) Subject: try to get another bm for ppopp paper X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5eb02486f866192a872921b47638eb9f2a4f8dbf;p=IRC.git try to get another bm for ppopp paper --- diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/Client.java b/Robust/src/Benchmarks/SingleTM/Vacation/Client.java new file mode 100644 index 00000000..52a27723 --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/Client.java @@ -0,0 +1,292 @@ +/* ============================================================================= + * + * client.c + * + * ============================================================================= + * + * Copyright (C) Stanford University, 2006. All Rights Reserved. + * Author: Chi Cao Minh + * + * ============================================================================= + * + * For the license of bayes/sort.h and bayes/sort.c, please see the header + * of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of kmeans, please see kmeans/LICENSE.kmeans + * + * ------------------------------------------------------------------------ + * + * For the license of ssca2, please see ssca2/COPYRIGHT + * + * ------------------------------------------------------------------------ + * + * For the license of lib/mt19937ar.c and lib/mt19937ar.h, please see the + * header of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of lib/rbtree.h and lib/rbtree.c, please see + * lib/LEGALNOTICE.rbtree and lib/LICENSE.rbtree + * + * ------------------------------------------------------------------------ + * + * Unless otherwise noted, the following license applies to STAMP files: + * + * Copyright (c) 2007, Stanford University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Stanford University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * ============================================================================= + */ + + +public class Client extends Thread { + int id; + Manager managerPtr; + Random randomPtr; + int numOperation; + int numQueryPerTransaction; + int queryRange; + int percentUser; + + public Client() {} + +/* ============================================================================= + * client_alloc + * -- Returns NULL on failure + * ============================================================================= + */ + public Client(int id, + Manager managerPtr, + int numOperation, + int numQueryPerTransaction, + int queryRange, + int percentUser) { + this.randomPtr = new Random(); + this.randomPtr.random_alloc(); + this.id=id; + this.managerPtr = managerPtr; + randomPtr.random_seed(id); + this.numOperation = numOperation; + this.numQueryPerTransaction = numQueryPerTransaction; + this.queryRange = queryRange; + this.percentUser = percentUser; + } + + +/* ============================================================================= + * selectAction + * ============================================================================= + */ + public int selectAction (int r, int percentUser) { + if (r < percentUser) { + return ACTION_MAKE_RESERVATION; + } else if ((r & 1)==1) { + return ACTION_DELETE_CUSTOMER; + } else { + return ACTION_UPDATE_TABLES; + } + } + + +/* ============================================================================= + * client_run + * -- Execute list operations on the database + * ============================================================================= + */ + public void run() { + int myId = id; + + Manager managerPtr = this.managerPtr; + Random randomPtr = this.randomPtr; + + int numOperation = this.numOperation; + int numQueryPerTransaction = this.numQueryPerTransaction; + int queryRange = this.queryRange; + int percentUser = this.percentUser; + + int types[] = new int[numQueryPerTransaction]; + int ids[] = new int[numQueryPerTransaction]; + int ops[] = new int[numQueryPerTransaction]; + int prices[] = new int[numQueryPerTransaction]; + + for (int i = 0; i < numOperation; i++) { + int r = randomPtr.posrandom_generate() % 100; + int action = selectAction(r, percentUser); + + switch (action) { + case ACTION_MAKE_RESERVATION: { + int maxPrices[]=new int[NUM_RESERVATION_TYPE]; + int maxIds[]=new int[NUM_RESERVATION_TYPE]; + maxPrices[0]=-1; + maxPrices[1]=-1; + maxPrices[2]=-1; + maxIds[0]=-1; + maxIds[1]=-1; + maxIds[2]=-1; + int n; + int numQuery = randomPtr.posrandom_generate() % numQueryPerTransaction + 1; + int customerId = randomPtr.posrandom_generate() % queryRange + 1; + for (n = 0; n < numQuery; n++) { + types[n] = randomPtr.random_generate() % NUM_RESERVATION_TYPE; + ids[n] = (randomPtr.random_generate() % queryRange) + 1; + } + boolean isFound = false; + //atomic + { + for (n = 0; n < numQuery; n++) { + int t = types[n]; + int id = ids[n]; + int price = -1; + switch (t) { + case RESERVATION_CAR: + if (managerPtr.manager_queryCar(id) >= 0) { + price = managerPtr.manager_queryCarPrice(id); + } + break; + case RESERVATION_FLIGHT: + if (managerPtr.manager_queryFlight(id) >= 0) { + price = managerPtr.manager_queryFlightPrice(id); + } + break; + case RESERVATION_ROOM: + if (managerPtr.manager_queryRoom(id) >= 0) { + price = managerPtr.manager_queryRoomPrice(id); + } + break; + default: + //assert(0); + } + if (price > maxPrices[t]) { + maxPrices[t] = price; + maxIds[t] = id; + isFound = true; + } + } /* for n */ + if (isFound) { + managerPtr.manager_addCustomer(customerId); + } + if (maxIds[RESERVATION_CAR] > 0) { + managerPtr.manager_reserveCar(customerId, maxIds[RESERVATION_CAR]); + } + if (maxIds[RESERVATION_FLIGHT] > 0) { + managerPtr.manager_reserveFlight(customerId, maxIds[RESERVATION_FLIGHT]); + } + if (maxIds[RESERVATION_ROOM] > 0) { + managerPtr.manager_reserveRoom(customerId, maxIds[RESERVATION_ROOM]); + } + } + break; + } + + case ACTION_DELETE_CUSTOMER: { + int customerId = randomPtr.posrandom_generate() % queryRange + 1; + //atomic + { + int bill = managerPtr.manager_queryCustomerBill(customerId); + if (bill >= 0) { + managerPtr.manager_deleteCustomer(customerId); + } + } + break; + } + + case ACTION_UPDATE_TABLES: { + int numUpdate = randomPtr.posrandom_generate() % numQueryPerTransaction + 1; + int n; + for (n = 0; n < numUpdate; n++) { + types[n] = randomPtr.posrandom_generate() % NUM_RESERVATION_TYPE; + ids[n] = (randomPtr.posrandom_generate() % queryRange) + 1; + ops[n] = randomPtr.posrandom_generate() % 2; + if (ops[n]==1) { + prices[n] = ((randomPtr.posrandom_generate() % 5) * 10) + 50; + } + } + //atomic + { + for (n = 0; n < numUpdate; n++) { + int t = types[n]; + int id = ids[n]; + int doAdd = ops[n]; + if (doAdd==1) { + int newPrice = prices[n]; + switch (t) { + case RESERVATION_CAR: + managerPtr.manager_addCar(id, 100, newPrice); + break; + case RESERVATION_FLIGHT: + managerPtr.manager_addFlight(id, 100, newPrice); + break; + case RESERVATION_ROOM: + managerPtr.manager_addRoom(id, 100, newPrice); + break; + default: + //assert(0); + } + } else { /* do delete */ + switch (t) { + case RESERVATION_CAR: + managerPtr.manager_deleteCar(id, 100); + break; + case RESERVATION_FLIGHT: + managerPtr.manager_deleteFlight(id); + break; + case RESERVATION_ROOM: + managerPtr.manager_deleteRoom(id, 100); + break; + default: + //assert(0); + } + } + } + } + break; + } + + default: + //assert(0); + } /* switch (action) */ + } /* for i */ + } + Barrier.enterBarrier(); +} + +/* ============================================================================= + * + * End of client.c + * + * ============================================================================= + */ + + + + diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/Customer.java b/Robust/src/Benchmarks/SingleTM/Vacation/Customer.java new file mode 100644 index 00000000..f9f0ce2a --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/Customer.java @@ -0,0 +1,161 @@ +/* ============================================================================= + * + * customer.c + * -- Representation of customer + * + * ============================================================================= + * + * Copyright (C) Stanford University, 2006. All Rights Reserved. + * Author: Chi Cao Minh + * + * ============================================================================= + * + * For the license of bayes/sort.h and bayes/sort.c, please see the header + * of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of kmeans, please see kmeans/LICENSE.kmeans + * + * ------------------------------------------------------------------------ + * + * For the license of ssca2, please see ssca2/COPYRIGHT + * + * ------------------------------------------------------------------------ + * + * For the license of lib/mt19937ar.c and lib/mt19937ar.h, please see the + * header of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of lib/rbtree.h and lib/rbtree.c, please see + * lib/LEGALNOTICE.rbtree and lib/LICENSE.rbtree + * + * ------------------------------------------------------------------------ + * + * Unless otherwise noted, the following license applies to STAMP files: + * + * Copyright (c) 2007, Stanford University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Stanford University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * ============================================================================= + */ + + +public class Customer { + + + /* ============================================================================= + * compareReservationInfo + * ============================================================================= + */ + int id; + List_t reservationInfoListPtr; + +/* ============================================================================= + * customer_alloc + * ============================================================================= + */ + public Customer(int id) { + this.id=id; + reservationInfoListPtr = new List_t(); + } + + +/* ============================================================================= + * customer_compare + * -- Returns -1 if A < B, 0 if A = B, 1 if A > B + * ============================================================================= + */ + int customer_compare (Customer aPtr, Customer bPtr) { + return (aPtr.id - bPtr.id); + } + + +/* ============================================================================= + * customer_addReservationInfo + * -- Returns true if success, else FALSE + * ============================================================================= + */ + boolean customer_addReservationInfo (int type, int id, int price) { + Reservation reservationInfoPtr; + + reservationInfoPtr = new Reservation(type, id, price); + // assert(reservationInfoPtr != NULL); + + return reservationInfoListPtr.insert(reservationInfoPtr); + } + + +/* ============================================================================= + * customer_removeReservationInfo + * -- Returns true if success, else FALSE + * ============================================================================= + */ + boolean customer_removeReservationInfo (int type, int id) { + Reservation_Info findReservationInfo =new Reservation_Info(type, id, 0); + + Reservation_Info reservationInfoPtr = (Reservation_Info)reservationInfoListPtr.find(findReservationInfo); + + if (reservationInfoPtr == null) { + return false; + } + + boolean status = reservationInfoListPtr.remove(findReservationInfo); + if (!status) { + System.out.println("TMRESTART"); + System.exit(-1); + } + + return true; + } + + +/* ============================================================================= + * customer_getBill + * -- Returns total cost of reservations + * ============================================================================= + */ + int customer_getBill () { + int bill = 0; + List_Node it; + + it=reservationInfoListPtr.head; + while (it.nextPtr!=null) { + it=it.nextPtr; + Reservation_Info reservationInfoPtr = + (Reservation_Info)it.dataPtr; + bill += reservationInfoPtr.price; + } + + return bill; + } +} diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/List_Node.java b/Robust/src/Benchmarks/SingleTM/Vacation/List_Node.java new file mode 100644 index 00000000..806baa19 --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/List_Node.java @@ -0,0 +1,10 @@ + +public class List_Node { + Object dataPtr; + List_Node nextPtr; + + public List_Node() { + dataPtr = null; + nextPtr = null; + } +} diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/List_t.java b/Robust/src/Benchmarks/SingleTM/Vacation/List_t.java new file mode 100644 index 00000000..0d6e75d4 --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/List_t.java @@ -0,0 +1,310 @@ +/* ============================================================================= + * + * List_t.java + * -- Sorted singly linked list + * -- Options: duplicate allowed + * (DLIST_NO_DUPLICATES) is no implemented yet (default: allow duplicates) + * + * ============================================================================= + * + * Copyright (C) Stanford University, 2006. All Rights Reserved. + * Author: Chi Cao Minh + * + * ============================================================================= + * + * For the license of bayes/sort.h and bayes/sort.c, please see the header + * of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of kmeans, please see kmeans/LICENSE.kmeans + * + * ------------------------------------------------------------------------ + * + * For the license of ssca2, please see ssca2/COPYRIGHT + * + * ------------------------------------------------------------------------ + * + * For the license of lib/mt19937ar.c and lib/mt19937ar.h, please see the + * header of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of lib/rbtree.h and lib/rbtree.c, please see + * lib/LEGALNOTICE.rbtree and lib/LICENSE.rbtree + * + * ------------------------------------------------------------------------ + * + * Unless otherwise noted, the following license applies to STAMP files: + * + * Copyright (c) 2007, Stanford University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Stanford University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * ============================================================================= + */ + + +public class List_t { + + public List_Node head; + int size; + + public List_t() { + head = new List_Node(); + } + + + /* ======================================================================= + * allocNode + * -- Returns null on failure + * ======================================================================= + */ + private List_Node allocNode(Object dataPtr) + { + List_Node nodePtr = new List_Node(); + + if(nodePtr == null) { + return null; + } + + nodePtr.dataPtr = dataPtr; + nodePtr.nextPtr = null; + + return nodePtr; + } + + +/* ============================================================================= + * list_alloc + * -- If NULL passed for 'compare' function, will compare data pointer addresses + * -- Returns NULL on failure + * ============================================================================= + * list_t* list_alloc (long (*compare)(const void*, const void*)); + * + * + */ + + public static List_t alloc() + { + List_t listPtr = new List_t(); + + if(listPtr == null) { + return null; + } + + listPtr.head.dataPtr = null; + listPtr.head.nextPtr = null; + listPtr.size = 0; + + return listPtr; + } + +/* ============================================================================= + * list_free + * -- If NULL passed for 'compare' function, will compare data pointer addresses + * -- Returns NULL on failure + * ============================================================================= + * void list_free (list_t* listPtr); + */ + public static void free(List_t listPtr) + { + listPtr = null; + } + +// privae freeList + +/* ============================================================================= + * list_isEmpty + * -- Return TRUE if list is empty, else FALSE + * ============================================================================= + * bool_t list_isEmpty (list_t* listPtr); + */ + public boolean isEmpty() + { + return (head.nextPtr == null); + } + +/* ============================================================================= + * list_getSize + * -- Returns size of list + * ============================================================================= + * long list_getSize (list_t* listPtr); + */ + public int getSize() { + return size; + } + +/* ============================================================================= + * findPrevious + * ============================================================================= + * void* list_find (list_t* listPtr, void* dataPtr); + */ + private List_Node findPrevious(Object dataPtr) + { + List_Node prevPtr = head; + List_Node nodePtr = prevPtr.nextPtr; + + for(; nodePtr != null; nodePtr = nodePtr.nextPtr) { + if (compare(nodePtr.dataPtr,dataPtr) >= 0) { + return prevPtr; + } + prevPtr = nodePtr; + } + + return prevPtr; + } + + /* ============================================================================= + * list_find + * -- Returns NULL if not found, else returns pointer to data + * ============================================================================= + * void* list_find (list_t* listPtr, void* dataPtr); + */ + public Object find(Object dataPtr) { + List_Node nodePtr; + List_Node prevPtr = findPrevious(dataPtr); + + nodePtr = prevPtr.nextPtr; + + if((nodePtr == null) || + (compare(nodePtr.dataPtr,dataPtr) != 0)) { + return null; + } + + return (nodePtr.dataPtr); + } + + public int compare(Object obj1,Object obj2) + { + Reservation_Info aPtr=(Reservation_Info)obj1; + Reservation_Info bPtr=(Reservation_Info)obj2; + int typeDiff; + + typeDiff = aPtr.type - bPtr.type; + + return ((typeDiff != 0) ? (typeDiff) : (aPtr.id - bPtr.id)); + } + +/* ============================================================================= + * list_insert + * -- Return TRUE on success, else FALSE + * ============================================================================= + * bool_t list_insert (list_t* listPtr, void* dataPtr); + */ + public boolean insert(Object dataPtr) { + List_Node prevPtr; + List_Node nodePtr; + List_Node currPtr; + + prevPtr = findPrevious(dataPtr); + currPtr = prevPtr.nextPtr; + + nodePtr = allocNode(dataPtr); + if (nodePtr == null) { + return false; + } + + nodePtr.nextPtr = currPtr; + prevPtr.nextPtr = nodePtr; + size++; + + return true; + } + + +/* ============================================================================= + * list_remove + * -- Returns TRUE if successful, else FALSE + * ============================================================================= + * bool_t list_remove (list_t* listPtr, void* dataPtr); + */ + public boolean remove(Object dataPtr) + { + List_Node prevPtr; + List_Node nodePtr; + + prevPtr = findPrevious(dataPtr); + + nodePtr = prevPtr.nextPtr; + + if((nodePtr != null) && + (compare(nodePtr.dataPtr,dataPtr) == 0)) + { + prevPtr.nextPtr = nodePtr.nextPtr; + nodePtr.nextPtr = null; + nodePtr = null; + size--; + + return true; + } + + return false; + } + + int compareObject(Object obj1,Object obj2) { + return 1; + } + + +/* ============================================================================= + * list_clear + * -- Removes all elements + * ============================================================================= + * void list_clear (list_t* listPtr); + */ + public void clear() { + head = new List_Node(); + size = 0; + } + +/* ============================================================================= + * + * End of list.java + * + * ============================================================================= + */ + + /* Test list */ + + public static void main(String[] argv) { + List_t listPtr; + int[] data1 = new int[5]; + int[] data2 = new int[6]; + + int i; + + System.out.println("Starting..."); + } + +} + + + diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/Manager.java b/Robust/src/Benchmarks/SingleTM/Vacation/Manager.java new file mode 100644 index 00000000..cab10aa0 --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/Manager.java @@ -0,0 +1,605 @@ +/* ============================================================================= + * + * manager.c + * -- Travel reservation resource manager + * + * ============================================================================= + * + * Copyright (C) Stanford University, 2006. All Rights Reserved. + * Author: Chi Cao Minh + * + * ============================================================================= + * + * For the license of bayes/sort.h and bayes/sort.c, please see the header + * of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of kmeans, please see kmeans/LICENSE.kmeans + * + * ------------------------------------------------------------------------ + * + * For the license of ssca2, please see ssca2/COPYRIGHT + * + * ------------------------------------------------------------------------ + * + * For the license of lib/mt19937ar.c and lib/mt19937ar.h, please see the + * header of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of lib/rbtree.h and lib/rbtree.c, please see + * lib/LEGALNOTICE.rbtree and lib/LICENSE.rbtree + * + * ------------------------------------------------------------------------ + * + * Unless otherwise noted, the following license applies to STAMP files: + * + * Copyright (c) 2007, Stanford University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Stanford University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * ============================================================================= + */ + +/* ============================================================================= + * DECLARATION OF TM_CALLABLE FUNCTIONS + * ============================================================================= + */ +public class Manager { + RBTree carTablePtr; + RBTree roomTablePtr; + RBTree flightTablePtr; + RBTree customerTablePtr; + + /* ============================================================================= + * manager_alloc + * ============================================================================= + */ + public Manager() { + carTablePtr = new RBTree(); + roomTablePtr = new RBTree(); + flightTablePtr = new RBTree(); + customerTablePtr = new RBTree(); + } + +/* ============================================================================= + * addReservation + * -- If 'num' > 0 then add, if < 0 remove + * -- Adding 0 seats is error if does not exist + * -- If 'price' < 0, do not update price + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean addReservation (RBTree tablePtr, int id, int num, int price) { + Reservation reservationPtr; + + reservationPtr = (Reservation)tablePtr.find(id); + if (reservationPtr == null) { + /* Create new reservation */ + if (num < 1 || price < 0) { + return false; + } + reservationPtr = new Reservation(id, num, price); + // assert(reservationPtr != NULL); + tablePtr.insert(id, reservationPtr); + } else { + /* Update existing reservation */ + if (!reservationPtr.reservation_addToTotal(num)) { + return false; + } + if (reservationPtr.numTotal == 0) { + boolean status = tablePtr.remove(id); + if (!status) { + System.out.println("TMRESTART"); + System.exit(-1); + } + } else { + reservationPtr.reservation_updatePrice(price); + } + } + + return true; + } + + + /* ============================================================================= + * manager_addCar + * -- Add cars to a city + * -- Adding to an existing car overwrite the price if 'price' >= 0 + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_addCar (int carId, int numCars, int price) { + return addReservation(carTablePtr, carId, numCars, price); + } + + +/* ============================================================================= + * manager_deleteCar + * -- Delete cars from a city + * -- Decreases available car count (those not allocated to a customer) + * -- Fails if would make available car count negative + * -- If decresed to 0, deletes entire entry + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_deleteCar (int carId, int numCar) { + /* -1 keeps old price */ + return addReservation(carTablePtr, carId, -numCar, -1); + } + + +/* ============================================================================= + * manager_addRoom + * -- Add rooms to a city + * -- Adding to an existing room overwrite the price if 'price' >= 0 + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_addRoom(int roomId, int numRoom, int price) { + return addReservation(roomTablePtr, roomId, numRoom, price); + } + + + + +/* ============================================================================= + * manager_deleteRoom + * -- Delete rooms from a city + * -- Decreases available room count (those not allocated to a customer) + * -- Fails if would make available room count negative + * -- If decresed to 0, deletes entire entry + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_deleteRoom(int roomId, int numRoom) { + /* -1 keeps old price */ + return addReservation(roomTablePtr, roomId, -numRoom, -1); + } + + +/* ============================================================================= + * manager_addFlight + * -- Add seats to a flight + * -- Adding to an existing flight overwrite the price if 'price' >= 0 + * -- Returns TRUE on success, FALSE on failure + * ============================================================================= + */ + boolean manager_addFlight(int flightId, int numSeat, int price) { + return addReservation(flightTablePtr, flightId, numSeat, price); + } + + + +/* ============================================================================= + * manager_deleteFlight + * -- Delete an entire flight + * -- Fails if customer has reservation on this flight + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_deleteFlight(int flightId) { + Reservation reservationPtr = (Reservation)flightTablePtr.find(flightId); + if (reservationPtr == null) { + return false; + } + + if (reservationPtr.numUsed > 0) { + return false; /* somebody has a reservation */ + } + + return addReservation(flightTablePtr, + flightId, + -reservationPtr.numTotal, + -1 /* -1 keeps old price */); + } + + +/* ============================================================================= + * manager_addCustomer + * -- If customer already exists, returns failure + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_addCustomer(int customerId) { + Customer customerPtr; + boolean status; + + if (customerTablePtr.contains(customerId)) { + return false; + } + + customerPtr = new Customer(customerId); + // assert(customerPtr != null); + status = customerTablePtr.insert(customerId, customerPtr); + if (!status) { + System.out.println("TMRESTART"); + System.exit(-1); + } + + return true; + } + + +/* ============================================================================= + * manager_deleteCustomer + * -- Delete this customer and associated reservations + * -- If customer does not exist, returns success + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_deleteCustomer (int customerId) { + Customer customerPtr; + RBTree reservationTables[]=new RBTree[NUM_RESERVATION_TYPE]; + List_t reservationInfoListPtr; + List_Node it; + boolean status; + + customerPtr = (Customer) customerTablePtr.find(customerId); + if (customerPtr == null) { + return false; + } + + reservationTables[RESERVATION_CAR] = carTablePtr; + reservationTables[RESERVATION_ROOM] = roomTablePtr; + reservationTables[RESERVATION_FLIGHT] = flightTablePtr; + + /* Cancel this customer's reservations */ + reservationInfoListPtr = customerPtr.reservationInfoListPtr; + it=reservationInfoListPtr.head; + while (it.nextPtr!=null) { + Reservation_Info reservationInfoPtr; + Reservation reservationPtr; + it=it.nextPtr; + reservationInfoPtr =(Reservation_Info)it.dataPtr; + reservationPtr = (Reservation)reservationTables[reservationInfoPtr.type].find(reservationInfoPtr.id); + if (reservationPtr == null) { + System.out.println("TMRESTART"); + System.exit(-1); + } + status = reservationPtr.reservation_cancel(); + + if (!status) { + System.out.println("TMRESTART"); + System.exit(-1); + } + } + + status = customerTablePtr.remove(customerId); + if (!status) { + System.out.println("TMRESTART"); + System.exit(-1); + } + return true; + } + + +/* ============================================================================= + * QUERY INTERFACE + * ============================================================================= + */ + + +/* ============================================================================= + * queryNumFree + * -- Return numFree of a reservation, -1 if failure + * ============================================================================= + */ + int queryNumFree(RBTree tablePtr, int id) { + int numFree = -1; + Reservation reservationPtr = (Reservation)tablePtr.find(id); + if (reservationPtr != null) { + numFree = reservationPtr.numFree; + } + + return numFree; + } + + +/* ============================================================================= + * queryPrice + * -- Return price of a reservation, -1 if failure + * ============================================================================= + */ + int queryPrice (RBTree tablePtr, int id) { + int price = -1; + Reservation reservationPtr=(Reservation) tablePtr.find(id); + if (reservationPtr != null) { + price = reservationPtr.price; + } + + return price; + } + + +/* ============================================================================= + * manager_queryCar + * -- Return the number of empty seats on a car + * -- Returns -1 if the car does not exist + * ============================================================================= + */ + int manager_queryCar (int carId) { + return queryNumFree(carTablePtr, carId); + } + + +/* ============================================================================= + * manager_queryCarPrice + * -- Return the price of the car + * -- Returns -1 if the car does not exist + * ============================================================================= + */ + int manager_queryCarPrice (int carId) { + return queryPrice(carTablePtr, carId); + } + + +/* ============================================================================= + * manager_queryRoom + * -- Return the number of empty seats on a room + * -- Returns -1 if the room does not exist + * ============================================================================= + */ + int manager_queryRoom (int roomId) { + return queryNumFree(roomTablePtr, roomId); + } + + +/* ============================================================================= + * manager_queryRoomPrice + * -- Return the price of the room + * -- Returns -1 if the room does not exist + * ============================================================================= + */ + int manager_queryRoomPrice (int roomId) { + return queryPrice(roomTablePtr, roomId); + } + + +/* ============================================================================= + * manager_queryFlight + * -- Return the number of empty seats on a flight + * -- Returns -1 if the flight does not exist + * ============================================================================= + */ + int manager_queryFlight (int flightId) { + return queryNumFree(flightTablePtr, flightId); + } + + +/* ============================================================================= + * manager_queryFlightPrice + * -- Return the price of the flight + * -- Returns -1 if the flight does not exist + * ============================================================================= + */ + int manager_queryFlightPrice(int flightId) { + return queryPrice(flightTablePtr, flightId); + } + + + /* ============================================================================= + * manager_queryCustomerBill + * -- Return the total price of all reservations held for a customer + * -- Returns -1 if the customer does not exist + * ============================================================================= + */ + int manager_queryCustomerBill(int customerId) { + int bill = -1; + Customer customerPtr; + + customerPtr = (Customer) customerTablePtr.find(customerId); + + if (customerPtr != null) { + bill = customerPtr.customer_getBill(); + } + + return bill; + } + + +/* ============================================================================= + * RESERVATION INTERFACE + * ============================================================================= + */ + + +/* ============================================================================= + * reserve + * -- Customer is not allowed to reserve same (type, id) multiple times + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + static boolean reserve (RBTree tablePtr, RBTree customerTablePtr, + int customerId, int id, int type) { + Customer customerPtr; + Reservation reservationPtr; + + customerPtr = (Customer)customerTablePtr.find(customerId); + + if (customerPtr == null) { + return false; + } + + reservationPtr = (Reservation)tablePtr.find(id); + if (reservationPtr == null) { + return false; + } + + if (!reservationPtr.reservation_make()) { + return false; + } + + if (!customerPtr.customer_addReservationInfo(type, + id, + reservationPtr.price)) { + /* Undo previous successful reservation */ + boolean status = reservationPtr.reservation_cancel(); + if (!status) { + System.out.println("TMRESTART"); + System.exit(-1); + } + return false; + } + + return true; + } + + +/* ============================================================================= + * manager_reserveCar + * -- Returns failure if the car or customer does not exist + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_reserveCar (int customerId, int carId) { + return reserve(carTablePtr, + customerTablePtr, + customerId, + carId, + RESERVATION_CAR); + } + + +/* ============================================================================= + * manager_reserveRoom + * -- Returns failure if the room or customer does not exist + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_reserveRoom (int customerId, int roomId) { + return reserve(roomTablePtr, + customerTablePtr, + customerId, + roomId, + RESERVATION_ROOM); + } + + +/* ============================================================================= + * manager_reserveFlight + * -- Returns failure if the flight or customer does not exist + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_reserveFlight (int customerId, int flightId) { + return reserve(flightTablePtr, + customerTablePtr, + customerId, + flightId, + RESERVATION_FLIGHT); + } + + +/* ============================================================================= + * cancel + * -- Customer is not allowed to cancel multiple times + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + static boolean cancel (RBTree tablePtr, RBTree customerTablePtr, + int customerId, int id, int type) { + Customer customerPtr; + Reservation reservationPtr; + + customerPtr = (Customer) customerTablePtr.find(customerId); + if (customerPtr == null) { + return false; + } + + reservationPtr = (Reservation) tablePtr.find(id); + if (reservationPtr == null) { + return false; + } + + if (!reservationPtr.reservation_cancel()) { + return false; + } + + if (!customerPtr.customer_removeReservationInfo(type, id)) { + /* Undo previous successful cancellation */ + boolean status = reservationPtr.reservation_make(); + if (!status) { + System.out.println("TMRESTART"); + System.exit(-1); + } + return false; + } + + return true; + } + + +/* ============================================================================= + * manager_cancelCar + * -- Returns failure if the car, reservation, or customer does not exist + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_cancelCar(int customerId, int carId) { + return cancel(carTablePtr, + customerTablePtr, + customerId, + carId, + RESERVATION_CAR); + } + + +/* ============================================================================= + * manager_cancelRoom + * -- Returns failure if the room, reservation, or customer does not exist + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_cancelRoom (int customerId, int roomId) { + return cancel(roomTablePtr, + customerTablePtr, + customerId, + roomId, + RESERVATION_ROOM); + } + + + + /* ============================================================================= + * manager_cancelFlight + * -- Returns failure if the flight, reservation, or customer does not exist + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean manager_cancelFlight(int customerId, int flightId) { + return cancel(flightTablePtr, + customerTablePtr, + customerId, + flightId, + RESERVATION_FLIGHT); + } +} \ No newline at end of file diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/Node.java b/Robust/src/Benchmarks/SingleTM/Vacation/Node.java new file mode 100644 index 00000000..8e02de9f --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/Node.java @@ -0,0 +1,13 @@ + + +public class Node { + int k; // key + Object v; // val + Node p; // parent + Node l; // left + Node r; // right + int c; // color + + public Node() {} + +} diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/RBTree.java b/Robust/src/Benchmarks/SingleTM/Vacation/RBTree.java new file mode 100644 index 00000000..f7826c8f --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/RBTree.java @@ -0,0 +1,694 @@ +/* ============================================================================= + * + * rbtree.java + * -- Red-black balanced binary search tree + * + * ============================================================================= + * + * Copyright (C) Sun Microsystems Inc., 2006. All Rights Reserved. + * Authors: Dave Dice, Nir Shavit, Ori Shalev. + * + * STM: Transactional Locking for Disjoint Access Parallelism + * + * Transactional Locking II, + * Dave Dice, Ori Shalev, Nir Shavit + * DISC 2006, Sept 2006, Stockholm, Sweden. + * + * ============================================================================= + * + * Modified by Chi Cao Minh + * + * ============================================================================= + * + * For the license of bayes/sort.h and bayes/sort.c, please see the header + * of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of kmeans, please see kmeans/LICENSE.kmeans + * + * ------------------------------------------------------------------------ + * + * For the license of ssca2, please see ssca2/COPYRIGHT + * + * ------------------------------------------------------------------------ + * + * For the license of lib/mt19937ar.c and lib/mt19937ar.h, please see the + * header of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of lib/rbtree.h and lib/rbtree.c, please see + * lib/LEGALNOTICE.rbtree and lib/LICENSE.rbtree + * + * ------------------------------------------------------------------------ + * + * Unless otherwise noted, the following license applies to STAMP files: + * + * Copyright (c) 2007, Stanford University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Stanford University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * ============================================================================= + */ + +#define RED 0 +#define BLACK 1 + + +public class RBTree { + Node root; + int compID; + + public RBTree() {} + + /* private Methods */ + /* lookup */ + private Node lookup(int k) + { + Node p = root; + + while(p != null) { + int cmp = compare(k,p.k); + if(cmp == 0) { + return p; + } + p = (cmp < 0) ? p.l : p.r; + } + + return null; + } + + + /* rotateLeft */ + private void rotateLeft(Node x) + { + Node r = x.r; + Node rl = r.l; + x.r = rl; + if(rl != null) { + rl.p = x; + } + + Node xp = x.p; + r.p = xp; + if (xp == null) { + root = r; + } else if (xp.l == x) { + xp.l = r; + } else { + xp.r = r; + } + r.l = x; + x.p = r; + } + + /* rotateRight */ + private void rotateRight(Node x) + { + Node l = x.l; + Node lr = l.r; + x.l = lr; + if (lr != null) { + lr.p = x; + } + Node xp = x.p; + l.p = xp; + if (xp == null) { + root = l; + } else if (xp.r == x) { + xp.r = l; + } else { + xp.l = l; + } + + l.r = x; + x.p = l; + } + + /* parentOf */ + private Node parentOf (Node n) + { + return ((n!=null) ? n.p : null); + } + + /* leftOf */ + private Node leftOf (Node n) + { + return ((n != null)? n.l : null); + } + + /* rightOf */ + private Node rightOf(Node n) + { + return ((n!= null) ? n.r : null); + } + + /* colorOf */ + private int colorOf(Node n) + { + return ((n!=null) ? n.c : BLACK); + } + + /* setColor */ + private void setColor(Node n, int c) + { + if ( n != null) { + n.c = c; + } + } + + /* fixAfterInsertion */ + private void fixAfterInsertion(Node x) + { + x.c = RED; + + while (x != null && x != root) { + Node xp = x.p; + if(xp.c != RED) { + break; + } + + if(parentOf(x) == leftOf(parentOf(parentOf(x)))) { + Node y = rightOf(parentOf(parentOf(x))); + if(colorOf(y) == RED) { + setColor(parentOf(x),BLACK); + setColor(y,BLACK); + setColor(parentOf(parentOf(x)),RED); + x = parentOf(parentOf(x)); + } else { + if ( x== rightOf(parentOf(x))) { + x = parentOf(x); + rotateLeft(x); + } + setColor(parentOf(x),BLACK); + setColor(parentOf(parentOf(x)),RED); + if(parentOf(parentOf(x)) != null) { + rotateRight(parentOf(parentOf(x))); + } + } + } else { + Node y = leftOf(parentOf(parentOf(x))); + if(colorOf(y) == RED) { + setColor(parentOf(x),BLACK); + setColor(y,BLACK); + setColor(parentOf(parentOf(x)),RED); + x = parentOf(parentOf(x)); + } else { + if (x == leftOf(parentOf(x))) { + x = parentOf(x); + rotateRight(x); + } + setColor(parentOf(x),BLACK); + setColor(parentOf(parentOf(x)),RED); + if (parentOf(parentOf(x)) != null) { + rotateLeft(parentOf(parentOf(x))); + } + } + } + } + + Node ro = root; + if(ro.c != BLACK) { + ro.c = BLACK; + } + } + + private Node insert(int k,Object v,Node n) + { + Node t = root; + if (t== null) { + if (n == null) { + return null; + } + /* Note: the following STs don't really need to be transactional */ + n.l = null; + n.r = null; + n.p = null; + n.k = k; + n.v = v; + n.c = BLACK; + root = n; + return null; + } + + while(true) { + int cmp = compare(k,t.k); + if (cmp == 0) { + return t; + } else if (cmp < 0) { + Node tl = t.l; + if (tl != null) { + t = tl; + } else { + n.l = null; + n.r = null; + n.k = k; + n.v = v; + n.p = t; + t.l = n; + fixAfterInsertion(n); + return null; + } + } else { /* cmp > 0 */ + Node tr = t.r; + if (tr != null) { + t = tr; + } else { + n.l = null; + n.r = null; + n.k = k; + n.v = v; + n.p = t; + t.r = n; + fixAfterInsertion(n); + return null; + } + } + } + } + + /* successor */ + private Node successor(Node t) + { + if ( t == null) { + return null; + } else if( t.r != null) { + Node p = t.r; + while (p.l != null) { + p = p.l; + } + return p; + } else { + Node p = t.p; + Node ch = t; + while (p != null && ch == p.r) { + ch = p; + p = p.p; + } + return p; + } + + } + + /* fixAfterDeletion */ + private void fixAfterDeletion(Node x) + { + while (x != root && colorOf(x) == BLACK) { + if ( x == leftOf(parentOf(x))) { + Node sib = rightOf(parentOf(x)); + if (colorOf(sib) == RED) { + setColor(sib,BLACK); + setColor(parentOf(x),RED); + rotateLeft(parentOf(x)); + sib = rightOf(parentOf(x)); + } + if(colorOf(leftOf(sib)) == BLACK && + colorOf(rightOf(sib)) == BLACK) { + setColor(sib,RED); + x = parentOf(x); + } else { + if(colorOf(rightOf(sib)) == BLACK) { + setColor(leftOf(sib),BLACK); + setColor(sib,RED); + rotateRight(sib); + sib = rightOf(parentOf(x)); + } + setColor(sib,colorOf(parentOf(x))); + setColor(parentOf(x),BLACK); + setColor(rightOf(sib),BLACK); + rotateLeft(parentOf(x)); + x = root; + } + } else { /* symmetric */ + Node sib = leftOf(parentOf(x)); + if(colorOf(sib) == RED) { + setColor(sib,BLACK); + setColor(parentOf(x),RED); + rotateRight(parentOf(x)); + sib = leftOf(parentOf(x)); + } + if (colorOf(rightOf(sib)) == BLACK && + colorOf(leftOf(sib)) == BLACK) { + setColor(sib,RED); + x = parentOf(x); + } else { + if(colorOf(leftOf(sib)) == BLACK) { + setColor(rightOf(sib), BLACK); + setColor(sib,RED); + rotateLeft(sib); + sib = leftOf(parentOf(x)); + } + setColor(sib,colorOf(parentOf(x))); + setColor(parentOf(x),BLACK); + setColor(leftOf(sib),BLACK); + rotateRight(parentOf(x)); + x = root; + } + } + } + + if (x != null && x.c != BLACK) { + x.c = BLACK; + } + } + + private Node deleteNode(Node p) { + /* + * If strictly internal, copy successor's element to p and then make p + * point to successor + */ + if(p.l != null && p.r != null) { + Node s = successor(p); + p.k = s.k; + p.v = s.v; + p = s; + } /* p has 2 children */ + + /* Start fixup at replacement node, if it exists */ + Node replacement = (p.l != null)? p.l : p.r; + + if (replacement != null) { + /* Link replacement to parent */ + replacement.p = p.p; + Node pp = p.p; + if(pp == null) { + root = replacement; + } else if( p == pp.l) { + pp.l = replacement; + } else { + pp.r = replacement; + } + + /* Null out links so they are OK to use by fixAfterDeletion */ + p.l = null; + p.r = null; + p.p = null; + + /* Fix replacement */ + if(p.c == BLACK) { + fixAfterDeletion(replacement); + } + } else if(p.p == null) { /* return if we are the only node */ + root = null; + } else { /* No children. Use self as phantom replacement and unlink */ + if (p.c == BLACK) { + fixAfterDeletion(p); + } + Node pp = p.p; + if(pp != null) { + if( p == pp.l) { + pp.l = null; + } else if( p == pp.r) { + pp.r = null; + } + p.p = null; + } + } + return p; + } + + + /* + * Diagnostic section + */ + + /* firstEntry */ + + private Node firstEntry() + { + Node p = root; + if( p != null) { + while ( p.l != null) { + p = p.l; + } + } + return p; + } + + /* verifyRedBlack */ + + private int verifyRedBlack(Node root,int depth) + { + int height_left; + int height_right; + + if ( root == null) { + return 1; + } + + height_left = verifyRedBlack(root.l,depth+1); + height_right = verifyRedBlack(root.r,depth+1); + if(height_left == 0 || height_right == 0) { + return 0; + } + if (height_left != height_right) { + System.out.println(" Imbalace @depth = " + depth + " : " + height_left + " " + height_right); + } + + if (root.l != null && root.l.p != root) { + System.out.println(" lineage"); + } + if (root.r != null && root.r.p != root) { + System.out.println(" lineage"); + } + + /* Red-Black alternation */ + if (root.c == RED) { + if (root.l != null && root.l.c != BLACK) { + System.out.println("VERIFY in verifyRedBlack"); + return 0; + } + + if (root.r != null && root.r.c != BLACK) { + System.out.println("VERIFY in verifyRedBlack"); + return 0; + } + return height_left; + } + if(root.c != BLACK) { + System.out.println("VERIFY in verifyRedBlack"); + return 0; + } + + return (height_left + 1); + } + + /* compareKeysDefault */ + private int compare(int a,int b) { + return a - b; + } + + + + + + +/***************************************** + * public methods + *****************************************/ + + +/* ============================================================================= + * rbtree_verify + * ============================================================================= + long rbtree_verify (rbtree_t* s, long verbose); + */ + public int verify(int verbose) + { + if ( root == null) { + return 1; + } + if(verbose != 0) { + System.out.println("Integrity check: "); + } + + if (root.p != null) { + System.out.println(" (WARNING) root = " + root + " parent = " + root.p); + return -1; + } + if (root.c != BLACK) { + System.out.println(" (WARNING) root = " + root + " color = " + root.c); + } + + /* Weak check of binary-tree property */ + int ctr = 0; + Node its = firstEntry(); + while (its != null) { + ctr++; + Node child = its.l; + if ( child != null && child.p != its) { + System.out.println("bad parent"); + } + child = its.r; + if ( child != null && child.p != its) { + System.out.println("Bad parent"); + } + Node nxt = successor(its); + if (nxt == null) { + break; + } + if( compare(its.k,nxt.k) >= 0) { + System.out.println("Key order " + its + " ("+its.k+" "+its.v+") " + + nxt + " ("+nxt.k+" "+nxt.v+") "); + return -3; + } + its = nxt; + } + + int vfy = verifyRedBlack(root, 0); + if(verbose != 0) { + System.out.println(" Nodes = " + ctr + " Depth = " + vfy); + } + + return vfy; + + } + +/* ============================================================================= + * rbtree_alloc + * ============================================================================= + * rbtree_t* rbtree_alloc (long (*compare)(const void*, const void*)); + */ + public static RBTree alloc(int compID) + { + RBTree n = new RBTree(); + if (n != null) { + n.compID = compID; + n.root = null; + } + + return n; + } + + + +/* ============================================================================= + * rbtree_free + * ============================================================================= + * void rbtree_free (rbtree_t* r); + */ + + + +/* ============================================================================= + * rbtree_insert + * -- Returns TRUE on success + * ============================================================================= + * bool_t rbtree_insert (rbtree_t* r, void* key, void* val); + */ + public boolean insert(int key,Object val) + { + Node node = new Node(); + Node ex = insert(key,val,node); + if ( ex != null) { + node = null; + } + return ((ex == null) ? true : false); + } + + +/* ============================================================================= + * rbtree_delete + * ============================================================================= + * bool_t rbtree_delete (rbtree_t* r, void* key); + */ + public boolean remove(int key) + { + Node node = null; + node = lookup(key); + + if(node != null) { + node = deleteNode(node); + } + //if(node != null) { + //this should do a release + //} + return node != null; + } + + + +/* ============================================================================= + * rbtree_update + * -- Return FALSE if had to insert node first + * ============================================================================= + * bool_t rbtree_update (rbtree_t* r, void* key, void* val); + */ + public boolean update(int key,Object val) + { + Node nn = new Node(); + Node ex = insert(key,val,nn); + if (ex != null) { + ex.v = val; + nn = null; + return true; + } + return false; + } + + + +/* ============================================================================= + * rbtree_get + * ============================================================================= + * void* rbtree_get (rbtree_t* r, void* key); + */ + public Object find(int key) { + Node n = lookup(key); + if (n != null) { + Object val = n.v; + return val; + } + return null; + } + + + +/* ============================================================================= + * rbtree_contains + * ============================================================================= + * bool_t rbtree_contains (rbtree_t* r, void* key); + */ + public boolean contains(int key) + { + Node n = lookup(key); + + return (n != null); + } + +} + +/* ============================================================================= + * + * End of rbtree.java + * + * ============================================================================= + */ diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/README b/Robust/src/Benchmarks/SingleTM/Vacation/README new file mode 100644 index 00000000..af9515a3 --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/README @@ -0,0 +1,86 @@ +Introduction +------------ + +This benchmark implements a travel reservation system powered by a +non-distributed database. The workload consists of several client threads +interacting with the database via the system's transaction manager. + +The database is consists of four tables: cars, rooms, flights, and customers. +The first three have relations with fields representing a unique ID number, +reserved quantity, total available quantity, and price. The table of customers +tracks the reservations made by each customer and the total price of the +reservations they made. The tables are implemented as Red-Black trees. + +When using this benchmark, please cite [1]. + + +Compiling and Running +--------------------- + +To build the application, simply run: + + make -f + +in the source directory. For example, for the sequential flavor, run: + + make -f Makefile.seq + +By default, this produces an executable named "vacation", which can then be +run in the following manner: + + ./vacation -n \ + -q <%_of_relations_queried> \ + -r \ + -u <%_of_user_tasks> \ + -t + +The following values are recommended for simulated runs: + + low contention: -n2 -q90 -u98 -r16384 -t4096 + high contention: -n4 -q60 -u90 -r16384 -t4096 + +For non-simulator runs, larger values for -r and -t can be used: + + low contention: -n2 -q90 -u98 -r1048576 -t4194304 + high contention: -n4 -q60 -u90 -r1048576 -t4194304 + + +Workload Characteristics +------------------------ + +The initial size of the database is determined by -r, which is the number of +entries with which the tree will be initialized. The number of total tasks that +the travel reservation system performs is controlled by -t. There are four +different possible tasks: + + 1) Make Reservation -- The client checks the price of -n items, and + reserves a few of them. + + 2) Delete Customer -- The total cost of a customer's reservations is + computed and then the customer is removed from the system. + + 3) Add to Item Tables -- Add -n new items for reservation, where + an item is one of {car, flight, room} and has a unique ID number. + + 4) Remove from Item Tables -- Remove -n new items for reservation, where + an item is one of {car, flight, room} and has a unique ID number. + +The distribution of tasks can be adjusted with the -u option. For example, +an argument of U gives the following distribution: + + U % ---------- Make Reservation + (100-U)/2 % -- Delete Customer + (100-U)/4 % -- Add to Item Tables + (100-U)/4 % -- Remove from Item Tables + +The -q option controls the range of values from which the clients generate +queries; thus, smaller values for -q generate higher contention workloads. + + +References +---------- + +[1] C. Cao Minh, J. Chung, C. Kozyrakis, and K. Olukotun. STAMP: Stanford + Transactional Applications for Multi-processing. In IISWC '08: Proceedings + of The IEEE International Symposium on Workload Characterization, + September 2008. diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/Reservation.java b/Robust/src/Benchmarks/SingleTM/Vacation/Reservation.java new file mode 100644 index 00000000..8157d1fc --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/Reservation.java @@ -0,0 +1,205 @@ +/* ============================================================================= + * + * reservation.c + * -- Representation of car, flight, and hotel relations + * + * ============================================================================= + * + * Copyright (C) Stanford University, 2006. All Rights Reserved. + * Author: Chi Cao Minh + * + * ============================================================================= + * + * For the license of bayes/sort.h and bayes/sort.c, please see the header + * of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of kmeans, please see kmeans/LICENSE.kmeans + * + * ------------------------------------------------------------------------ + * + * For the license of ssca2, please see ssca2/COPYRIGHT + * + * ------------------------------------------------------------------------ + * + * For the license of lib/mt19937ar.c and lib/mt19937ar.h, please see the + * header of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of lib/rbtree.h and lib/rbtree.c, please see + * lib/LEGALNOTICE.rbtree and lib/LICENSE.rbtree + * + * ------------------------------------------------------------------------ + * + * Unless otherwise noted, the following license applies to STAMP files: + * + * Copyright (c) 2007, Stanford University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Stanford University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * ============================================================================= + */ + +public class Reservation { + public Reservation(int id, int numTotal, int price) { + this.id=id; + this.numUsed=0; + this.numFree=numTotal; + this.numTotal=numTotal; + this.price=price; + } + + int id; + int numUsed; + int numFree; + int numTotal; + int price; + +/* ============================================================================= + * checkReservation + * -- Check if consistent + * ============================================================================= + */ + public void checkReservation() { + int numUsed = this.numUsed; + if (numUsed < 0) { + System.out.println("TMRESTART"); + System.exit(-1); + } + + int numFree = this.numFree; + if (numFree < 0) { + System.out.println("TMRESTART"); + System.exit(-1); + } + + int numTotal = this.numTotal; + if (numTotal < 0) { + System.out.println("TMRESTART"); + System.exit(-1); + } + + if ((numUsed + numFree) != numTotal) { + System.out.println("TMRESTART"); + System.exit(-1); + } + + int price = this.price; + if (price < 0) { + System.out.println("TMRESTART"); + System.exit(-1); + } + } + + + /* ============================================================================= + * reservation_addToTotal + * -- Adds if 'num' > 0, removes if 'num' < 0; + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean reservation_addToTotal (int num) { + if (numFree + num < 0) { + return false; + } + + numFree+=num; + numTotal+=num; + return true; + } + + + /* ============================================================================= + * reservation_make + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + public boolean reservation_make() { + if (numFree < 1) { + return false; + } + numUsed++; + numFree--; + return true; + } + + +/* ============================================================================= + * reservation_cancel + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean reservation_cancel() { + if (numUsed < 1) { + return false; + } + numUsed--; + numFree++; + return false; + } + + +/* ============================================================================= + * reservation_updatePrice + * -- Failure if 'price' < 0 + * -- Returns TRUE on success, else FALSE + * ============================================================================= + */ + boolean reservation_updatePrice (int newPrice) { + if (newPrice < 0) { + return false; + } + + this.price=newPrice; + return true; + } + + +/* ============================================================================= + * reservation_compare + * -- Returns -1 if A < B, 0 if A = B, 1 if A > B + * ============================================================================= + */ + int reservation_compare (Reservation aPtr, Reservation bPtr) { + return aPtr.id-bPtr.id; + } + + +/* ============================================================================= + * reservation_hash + * ============================================================================= + */ + int reservation_hash() { + return id; + } + +} diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/Reservation_Info.java b/Robust/src/Benchmarks/SingleTM/Vacation/Reservation_Info.java new file mode 100644 index 00000000..cd951305 --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/Reservation_Info.java @@ -0,0 +1,38 @@ + +/* ============================================================================= + * reservation_info_alloc + * -- Returns NULL on failure + * ============================================================================= + */ +public class Reservation_Info { + int id; + int type; + int price; + + public Reservation_Info(int type, int id, int price) { + this.type=type; + this.id=id; + this.price=price; + } + + +/* ============================================================================= + * reservation_info_compare + * -- Returns -1 if A < B, 0 if A = B, 1 if A > B + * ============================================================================= + */ + public static int reservation_info_compare (Reservation_Info aPtr, Reservation_Info bPtr) { + int typeDiff; + + typeDiff = aPtr.type - bPtr.type; + + return ((typeDiff != 0) ? (typeDiff) : (aPtr.id - bPtr.id)); + } + + +} +/* ============================================================================= + * reservation_alloc + * -- Returns NULL on failure + * ============================================================================= + */ diff --git a/Robust/src/Benchmarks/SingleTM/Vacation/Vacation.java b/Robust/src/Benchmarks/SingleTM/Vacation/Vacation.java new file mode 100644 index 00000000..67f8675a --- /dev/null +++ b/Robust/src/Benchmarks/SingleTM/Vacation/Vacation.java @@ -0,0 +1,325 @@ +/* ============================================================================= + * + * vacation.c + * + * ============================================================================= + * + * Copyright (C) Stanford University, 2006. All Rights Reserved. + * Author: Chi Cao Minh + * + * ============================================================================= + * + * For the license of bayes/sort.h and bayes/sort.c, please see the header + * of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of kmeans, please see kmeans/LICENSE.kmeans + * + * ------------------------------------------------------------------------ + * + * For the license of ssca2, please see ssca2/COPYRIGHT + * + * ------------------------------------------------------------------------ + * + * For the license of lib/mt19937ar.c and lib/mt19937ar.h, please see the + * header of the files. + * + * ------------------------------------------------------------------------ + * + * For the license of lib/rbtree.h and lib/rbtree.c, please see + * lib/LEGALNOTICE.rbtree and lib/LICENSE.rbtree + * + * ------------------------------------------------------------------------ + * + * Unless otherwise noted, the following license applies to STAMP files: + * + * Copyright (c) 2007, Stanford University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Stanford University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * ============================================================================= + */ + + + + +public class Vacation { +/* ============================================================================= + * displayUsage + * ============================================================================= + */ + + public static void displayUsage (String appName) { + System.out.println("Usage: %s [options]\n"+ appName); + System.out.println("\nOptions: (defaults)\n"); + System.out.println(" c Number of [c]lients (%i)\n"+ + PARAM_DEFAULT_CLIENTS); + System.out.println(" n [n]umber of user queries/transaction (%i)\n"+ + PARAM_DEFAULT_NUMBER); + System.out.println(" q Percentage of relations [q]ueried (%i)\n"+ + PARAM_DEFAULT_QUERIES); + System.out.println(" r Number of possible [r]elations (%i)\n"+ + PARAM_DEFAULT_RELATIONS); + System.out.println(" t Number of [t]ransactions (%i)\n"+ + PARAM_DEFAULT_TRANSACTIONS); + System.out.println(" u Percentage of [u]ser transactions (%i)\n"+ + PARAM_DEFAULT_USER); + System.exit(1); + } + + +/* ============================================================================= + * setDefaultParams + * ============================================================================= + */ + + int CLIENTS; + int NUMBER; + int QUERIES; + int RELATIONS; + int TRANSACTIONS; + int USER; + + public void setDefaultParams () { + CLIENTS = PARAM_DEFAULT_CLIENTS; + NUMBER = PARAM_DEFAULT_NUMBER; + QUERIES = PARAM_DEFAULT_QUERIES; + RELATIONS = PARAM_DEFAULT_RELATIONS; + TRANSACTIONS = PARAM_DEFAULT_TRANSACTIONS; + USER = PARAM_DEFAULT_USER; + } + + +/* ============================================================================= + * parseArgs + * ============================================================================= + */ + public void parseArgs (String argv[]) { + int opterr = 0; + + setDefaultParams(); + for(int i=0;i0) { + displayUsage(argv[0]); + } + } + + +/* ============================================================================= + * addCustomer + * -- Wrapper function + * ============================================================================= + */ + public static boolean addCustomer (Manager managerPtr, int id, int num, int price) { + return managerPtr.manager_addCustomer(id); + } + + +/* ============================================================================= + * initializeManager + * ============================================================================= + */ + public Manager initializeManager () { + int i; + int t; + System.out.println("Initializing manager... "); + + Random randomPtr = new Random(); + randomPtr.random_alloc(); + Manager managerPtr = new Manager(); + + int numRelation = RELATIONS; + int ids[] = new int[numRelation]; + for (i = 0; i < numRelation; i++) { + ids[i] = i + 1; + } + + for (t = 0; t < 4; t++) { + + /* Shuffle ids */ + for (i = 0; i < numRelation; i++) { + int x = randomPtr.posrandom_generate() % numRelation; + int y = randomPtr.posrandom_generate() % numRelation; + int tmp = ids[x]; + ids[x] = ids[y]; + ids[y] = tmp; + } + + /* Populate table */ + for (i = 0; i < numRelation; i++) { + boolean status; + int id = ids[i]; + int num = ((randomPtr.posrandom_generate() % 5) + 1) * 100; + int price = ((randomPtr.posrandom_generate() % 5) * 10) + 50; + switch(t) { + case 0: + status=managerPtr.manager_addCar(id, num, price); + break; + case 1: + status=managerPtr.manager_addFlight(id, num, price); + break; + case 2: + status=managerPtr.manager_addRoom(id, num, price); + break; + case 3: + status=managerPtr.manager_addCustomer(id); + break; + } + //assert(status); + } + + } /* for t */ + + System.out.println("done."); + } + + +/* ============================================================================= + * initializeClients + * ============================================================================= + */ + public Client[] initializeClients (Manager managerPtr) { + Random randomPtr; + Client clients[]; + int i; + int numClient = CLIENTS; + int numTransaction = TRANSACTIONS; + int numTransactionPerClient; + int numQueryPerTransaction = NUMBER; + int numRelation = RELATIONS; + int percentQuery = QUERIES; + int queryRange; + int percentUser = USER; + + System.out.println("Initializing clients... "); + + randomPtr = new Random(); + randomPtr.random_alloc(); + + clients = new Client[numClient]; + + numTransactionPerClient = (int)((double)numTransaction / (double)numClient + 0.5); + queryRange = (int)((double)percentQuery / 100.0 * (double)numRelation + 0.5); + + for (i = 0; i < numClient; i++) { + clients[i] = new Client(i, + managerPtr, + numTransactionPerClient, + numQueryPerTransaction, + queryRange, + percentUser); + } + + System.out.println("done."); + System.out.println(" Transactions = "+ numTransaction); + System.out.println(" Clients = "+ numClient); + System.out.println(" Transactions/client = "+ numTransactionPerClient); + System.out.println(" Queries/transaction = "+ numQueryPerTransaction); + System.out.println(" Relations = "+ numRelation); + System.out.println(" Query percent = "+ percentQuery); + System.out.println(" Query range = "+ queryRange); + System.out.println(" Percent user = "+ percentUser); + + return clients; +} + + + + /* ============================================================================= + * main + * ============================================================================= + */ + public static void main(String argv[]) { + Manager managerPtr; + Client clients[]; + long start; + long stop; + + /* Initialization */ + Vacation vac=new Vacation(); + vac.parseArgs(argv); + managerPtr = vac.initializeManager(); + clients = vac.initializeClients(managerPtr); + int numThread = vac.CLIENTS; + + /* Run transactions */ + System.out.println("Running clients... "); + start=System.currentTimeMillis(); + + // Barrier.setBarrier(numThread); + + for(int i=1;i Client.j + cat defines Manager.java > Manager.j + cat defines Vacation.java > Vacation.j + cpp -P -CC Client.j > tmpClient.java + cpp -P -CC Manager.j > tmpManager.java + cpp -P -CC Vacation.j > tmpVacation.java + cpp -P -CC RBTree.java > tmpRBTree.java + +clean: + rm -rf tmpbuilddirectory + rm *.bin *.j tmp*.java + +test: +