// Copy-assignment
ColumnBundle& ColumnBundle::operator=(const ColumnBundle &Y)
{	init(Y.nCols(), Y.colLength(), Y.basis, Y.qnum, Y.isOnGpu()); //initialize size and storage
	if(nData()) memcpy((ManagedMemory&)*this, (const ManagedMemory&)Y); //copy data
	return *this;
}
Example #2
0
void Blackboard::handlePacket(int fd, const Packet & packet) {
    if (WORDY) {
        log("%#010x => [ ", fd);
        for (unsigned int i = 0; i < packet.size(); ++i) {
            log("%02x ", packet[i]);
        }
        log("]\n");
    }

    // isolate

    Packet ret;

    switch (packet.getU32(0)) {


        case BO_CS_SUBSCRIBE_TO:
        {
            // pos     size     data
            //  0       4       COMMAND 
            //  4       4       KITAG

            log("%#010x BO_CS_SUBSCRIBE_TO requested\n", fd);

            uint32_t kiTag = packet.getU32(4);
            KnowledgeItem& ki = kiSet[kiTag];

            fdSet[fd].csList.insert(&ki);
            kiSet[kiTag].csListeners.insert(fd);

            // TODO: is there a case where this doesnt work?
            // send ACK
            ret.resize(8);
            ret.setU32(0, BO_GEN_ACK); // TODO: use a proper ACK
            ret.setU32(4, kiTag);

            break;
        }

        case BO_CS_GET_RECENT:
        {
            // pos     size     data
            //  0       4       COMMAND 
            //  4       4       KITAG
            //  8       4       NUMBER OF ELEMENTS
            log("%#010x BO_CS_GET_RECENT requested\n", fd);
            uint32_t kiTag = packet.getU32(4);
            uint32_t numElmnt = packet.getU32(8);
            KnowledgeItem& ki = kiSet[kiTag];

            std::deque<DataPoint> retSet = ki.getRecent(numElmnt);

            ret.resize(12);
            ret.setU32(0, BO_CS_RECENT);
            ret.setU32(4, kiTag);
            ret.setU32(8, retSet.size());

            // find out final packet size;
            int pktSize = 0;
            for (std::deque<DataPoint>::const_iterator it = retSet.begin(); it != retSet.end(); ++it) {
                pktSize += it->size() + sizeof (uint32_t); // add datapoint size + size of datapoint size;
            }
            log("pktSize = %d. retSet.size() = %d.\n", pktSize, (int) retSet.size());

            if (pktSize > MAX_BUFFER_SIZE) {
                log("Requested data set is too large! (%d)\n", (int) retSet.size());
                //TODO: need to do something here other than just complaining
            }

            unsigned int lastIndex = ret.size();
            ret.resize(lastIndex + pktSize);

            for (std::deque<DataPoint>::const_iterator it = retSet.begin(); it != retSet.end(); ++it) {
                //ret.insert(ret.end(), it->begin(), it->end());
                DataPoint dp = *it;

                ret.setU32(lastIndex, dp.size());
                lastIndex += 4;

                for (uint32_t i = 0; i < dp.size(); ++i) {
                    ret.setU8(lastIndex, dp[i]);
                    ++lastIndex;
                }
            }

            fdSet[fd].sendQueue.push_back(ret);

            break;
        }

        case BO_KS_SUBSCRIBE_AS:
        {
            // pos     size     data
            //  0       4       COMMAND 
            //  4       4       KITAG

            log("%#010x BO_KS_SUBSCRIBE_AS requested\n", fd);
            uint32_t kiTag = packet.getU32(4);

			//keep track of KIs by tag
			if(kiSet.count(kiTag) == 0){
				//add it to the ki of tags (confusing?)
				DataPoint dptmp;
				dptmp.wrap(kiTag);
				kiSet[BB_ALL_TAGS].update(dptmp);
			}
            KnowledgeItem& ki = kiSet[kiTag];

            // form default response packet
            ret.resize(8);
            ret.setU32(0, BO_KS_SUBSCRIPTION_FAILED);
            ret.setU32(4, kiTag);

            // attempt action and modify response  
            if (ki.ownerFd < 0) {

                fdSet[fd].ksList.insert(&ki);
                ki.ownerFd = fd;

                log("Assigned ki:%p to fd:%d\n", &ki, fd);
                ret.setU32(0, BO_KS_SUBSCRIPTION_SUCCESS);
            }

            // send packet
            fdSet[fd].sendQueue.push_back(ret);
#ifdef DEBUG
			//we want to see if we are keeping track of all the KIs...
			{
				std::map<int, ConnectionDetails>::const_iterator fdit;
				for(fdit = fdSet.begin(); fdit != fdSet.end(); ++fdit){
					//looping through all the fds...
					log("FD: %d\n", fdit->first);

					std::set<KnowledgeItem*>::const_iterator kit;
					for(kit = fdit->second.ksList.begin(); kit != fdit->second.ksList.end(); ++kit){
						//looping through all KS
						log("\tKS: %p\n", *kit);
					}
				}

				log("\nList of all KI:\n");
				std::map<bbtag, KnowledgeItem>::const_iterator kiit;
				for(kiit = kiSet.begin(); kiit != kiSet.end(); ++kiit){
					log("%d -> %p\n", kiit->first, &(kiit->second));
				}
				log("\n");
			}
#endif
            break;
        }

        case BO_KS_UPDATE:
        {
            // pos     size     data
            //  0       4       COMMAND 
            //  4       4       KITAG
            //  8       END     DATA      

            log("%#010x BO_KS_UPDATE requested\n", fd);
            uint32_t kiTag = packet.getU32(4);

            KnowledgeItem& ki = kiSet[kiTag];

            ret.resize(8);
            ret.setU32(0, BO_KS_UPDATE_FAILED);
            ret.setU32(4, kiTag);

            DataPoint nData(packet.begin() + 8, packet.end());

            // check if we are the owner of this KI
            if (ki.ownerFd == fd) {
                ret.setU32(0, BO_KS_UPDATE_SUCCESS);

                ki.update(nData);
            }

            //Acknowledge to the KS that its update was successful
            fdSet[fd].sendQueue.push_back(ret);

            //now we need to update any listeners on the KI

            for (std::set<int>::const_iterator i = ki.csListeners.begin(); i != ki.csListeners.end(); ++i) {
                int subscriber = *i;
                Packet updatePacket;
                updatePacket.resize(12 + nData.size());
                updatePacket.setU32(0, BO_CS_UPDATE);
                updatePacket.setU32(4, kiTag);
                updatePacket.setU32(8, nData.size());

                memcpy(&updatePacket.at(12), &nData.front(), nData.size());

                if (fdSet.count(subscriber) != 0) {
                    fdSet[subscriber].sendQueue.push_back(updatePacket);
                } else {
                    //TODO: handle this case
                    log("listener not in fdSet!!\n");
                }

            }

            break;
        }

#ifdef DEBUG
#define QUIETDEBUG
#endif
#ifdef QUIETDEBUG
        case BO_DEBUG_DUMP_KISET:
        {
            printf("%#010x BO_DEBUG_DUMP_KISET requested\n", fd);
            printf("kiSet:\n");
            for (std::map<bbtag, KnowledgeItem>::const_iterator knowledgeItemIterator = kiSet.begin(); knowledgeItemIterator != kiSet.end(); ++knowledgeItemIterator) {
                printf("\t%d: (%d updates)\n", knowledgeItemIterator->first, knowledgeItemIterator->second.updates);
                std::deque<DataPoint> dp = knowledgeItemIterator->second.dataChain;
                for (std::deque<DataPoint>::const_iterator dataChainIterator = dp.begin(); dataChainIterator != dp.end(); ++dataChainIterator) {
                    printf("\t[ ");
                    for (DataPoint::const_iterator dataPointIterator = dataChainIterator->begin(); dataPointIterator != dataChainIterator->end(); ++dataPointIterator) {
                        printf("%02x ", *dataPointIterator);
                    }
                    printf("]\n");
                }
            }

            break;
        }

        case BO_GEN_HUP:
        {
            log("%#010x BO_GEN_HUP requested\n", fd);

            // TODO: cleanup

            // quit without error
            exit(0);
            break;
        }
#endif
        default:
            // invalid code
            log("invalid command: %d\n", packet.getU32(0));
            ;
    }

    // end isolate
}