// 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; }
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 }