📄 attrs.cc
字号:
//// attrs.cc : Attribute Functions// authors : John Heidemann and Fabio Silva//// Copyright (C) 2000-2002 by the University of Southern California// $Id: attrs.cc,v 1.12 2002/05/29 00:00:40 fabio Exp $//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License,// version 2, as published by the Free Software Foundation.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License along// with this program; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.////#include <stdlib.h>#include <stdio.h>#include "attrs.hh"class PackedAttribute {public: int32_t key_; int8_t type_; int8_t op_; int16_t len_; int32_t val_;};NRAttrVec * CopyAttrs(NRAttrVec *src_attrs){ NRAttrVec::iterator itr; NRAttrVec *dst_attrs; NRAttribute *src; dst_attrs = new NRAttrVec; for (itr = src_attrs->begin(); itr != src_attrs->end(); ++itr){ src = *itr; switch (src->getType()){ case NRAttribute::INT32_TYPE: dst_attrs->push_back(new NRSimpleAttribute<int>(src->getKey(), NRAttribute::INT32_TYPE, src->getOp(), ((NRSimpleAttribute<int> *)src)->getVal())); break; case NRAttribute::FLOAT32_TYPE: dst_attrs->push_back(new NRSimpleAttribute<float>(src->getKey(), NRAttribute::FLOAT32_TYPE, src->getOp(), ((NRSimpleAttribute<float> *)src)->getVal())); break; case NRAttribute::FLOAT64_TYPE: dst_attrs->push_back(new NRSimpleAttribute<double>(src->getKey(), NRAttribute::FLOAT64_TYPE, src->getOp(), ((NRSimpleAttribute<double> *)src)->getVal())); break; case NRAttribute::STRING_TYPE: dst_attrs->push_back(new NRSimpleAttribute<char *>(src->getKey(), NRAttribute::STRING_TYPE, src->getOp(), ((NRSimpleAttribute<char *> *)src)->getVal())); break; case NRAttribute::BLOB_TYPE: dst_attrs->push_back(new NRSimpleAttribute<void *>(src->getKey(), NRAttribute::BLOB_TYPE, src->getOp(), ((NRSimpleAttribute<void *> *)src)->getVal(), src->getLen())); break; default: DiffPrint(DEBUG_ALWAYS, "Unknown attribute type found in CopyAttrs() !\n"); break; } } return dst_attrs;}void AddAttrs(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2){ NRAttrVec *copied_attrs; NRAttrVec::iterator itr; NRAttribute *src; if (attr_vec1 == NULL) attr_vec1 = new NRAttrVec; // Check if there's something to do if (attr_vec2 == NULL) return; // Duplicate source attributes so they can be added to the dst set copied_attrs = CopyAttrs(attr_vec2); // Add all attributes in the copied set into the dst set for (itr = copied_attrs->begin(); itr != copied_attrs->end(); ++itr){ src = *itr; attr_vec1->push_back(src); } // Delete the copied_attr vector without deleting its attributes delete copied_attrs;}void ClearAttrs(NRAttrVec *attr_vec){ NRAttrVec::iterator itr; for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){ delete *itr; } attr_vec->clear();}void PrintAttrs(NRAttrVec *attr_vec){ NRAttrVec::iterator itr; NRAttribute *aux; int counter = 0; for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){ aux = *itr; DiffPrint(DEBUG_ALWAYS, "Attribute #%d\n", counter); counter++; DiffPrint(DEBUG_ALWAYS, "-------------\n"); DiffPrint(DEBUG_ALWAYS, "Type = %d\n", aux->getType()); DiffPrint(DEBUG_ALWAYS, "Key = %d\n", aux->getKey()); DiffPrint(DEBUG_ALWAYS, "Op = %d\n", aux->getOp()); DiffPrint(DEBUG_ALWAYS, "Len = %d\n", aux->getLen()); switch(aux->getType()){ case NRAttribute::INT32_TYPE: DiffPrint(DEBUG_ALWAYS, "Val = %d\n", ((NRSimpleAttribute<int> *)aux)->getVal()); break; case NRAttribute::FLOAT32_TYPE: DiffPrint(DEBUG_ALWAYS, "Val = %f\n", ((NRSimpleAttribute<float> *)aux)->getVal()); break; case NRAttribute::FLOAT64_TYPE: DiffPrint(DEBUG_ALWAYS, "Val = %f\n", ((NRSimpleAttribute<double> *)aux)->getVal()); break; case NRAttribute::STRING_TYPE: DiffPrint(DEBUG_ALWAYS, "Val = %s\n", ((NRSimpleAttribute<char *> *)aux)->getVal()); break; case NRAttribute::BLOB_TYPE: DiffPrint(DEBUG_ALWAYS, "Val = %s\n", ((NRSimpleAttribute<void *> *)aux)->getVal()); break; default: DiffPrint(DEBUG_ALWAYS, "Val = Unknown\n"); break; } DiffPrint(DEBUG_ALWAYS, "\n"); }}DiffPacket AllocateBuffer(NRAttrVec *attr_vec){ DiffPacket pkt; int len; len = CalculateSize(attr_vec); len = len + sizeof(struct hdr_diff); pkt = new int [1 + (len / sizeof(int))]; if (pkt == NULL){ DiffPrint(DEBUG_ALWAYS, "Cannot allocate memory for packet !\n"); exit(-1); } return pkt;}int CalculateSize(NRAttrVec *attr_vec){ NRAttrVec::iterator itr; NRAttribute *temp; int pad, attr_len; int total_len = 0; for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){ temp = *itr; attr_len = temp->getLen(); // We have to pad to avoid bus errors pad = 0; if (attr_len % sizeof(int)){ pad = sizeof(int) - (attr_len % sizeof(int)); } total_len = total_len + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad; } return total_len;}int PackAttrs(NRAttrVec *attr_vec, char *start_pos){ PackedAttribute *current; NRAttrVec::iterator itr; NRAttribute *temp; int32_t t; char *pos; int pad, attr_len; int total_len = 0; current = (PackedAttribute *) start_pos; for (itr = attr_vec->begin(); itr != attr_vec->end(); ++itr){ temp = *itr; current->key_ = htonl(temp->getKey()); current->type_ = temp->getType(); current->op_ = temp->getOp(); attr_len = temp->getLen(); current->len_ = htons(attr_len); if (attr_len > 0){ switch (current->type_){ case NRAttribute::INT32_TYPE: t = htonl(((NRSimpleAttribute<int> *)temp)->getVal()); memcpy(¤t->val_, &t, sizeof(int32_t)); break; default: memcpy(¤t->val_, temp->getGenericVal(), attr_len); break; } } // We have to pad in order to avoid bus errors pad = 0; if (attr_len % sizeof(int)){ pad = sizeof(int) - (attr_len % sizeof(int)); } total_len = total_len + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad; pos = (char *) current + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad; current = (PackedAttribute *) pos; } return total_len;}NRAttrVec * UnpackAttrs(DiffPacket pkt, int num_attr){ PackedAttribute *current; NRAttrVec *attr_vec; int attr_len; char *pos; int pad; attr_vec = new NRAttrVec; pos = (char *) &pkt[0]; current = (PackedAttribute *) (pos + sizeof(struct hdr_diff)); for (int i = 0; i < num_attr; i++){ switch (current->type_){ case NRAttribute::INT32_TYPE: attr_vec->push_back(new NRSimpleAttribute<int>(ntohl(current->key_), NRAttribute::INT32_TYPE, current->op_, ntohl(*(int *)¤t->val_))); break; case NRAttribute::FLOAT32_TYPE: attr_vec->push_back(new NRSimpleAttribute<float>(ntohl(current->key_), NRAttribute::FLOAT32_TYPE, current->op_, *(float *)¤t->val_)); break; case NRAttribute::FLOAT64_TYPE: attr_vec->push_back(new NRSimpleAttribute<double>(ntohl(current->key_), NRAttribute::FLOAT64_TYPE, current->op_, *(double *)¤t->val_)); break; case NRAttribute::STRING_TYPE: attr_vec->push_back(new NRSimpleAttribute<char *>(ntohl(current->key_), NRAttribute::STRING_TYPE, current->op_, (char *)¤t->val_)); break; case NRAttribute::BLOB_TYPE: attr_vec->push_back(new NRSimpleAttribute<void *>(ntohl(current->key_), NRAttribute::BLOB_TYPE, current->op_, (void *)¤t->val_, ntohs(current->len_))); break; default: DiffPrint(DEBUG_ALWAYS, "Unknown attribute type found in UnpackAttrs() !\n"); break; } attr_len = ntohs(current->len_); pad = 0; if (attr_len % sizeof(int)){ // We have to calculate how much 'padding' to skip in order to // avoid bus errors pad = sizeof(int) - (attr_len % sizeof(int)); } pos = (char *) current + sizeof(PackedAttribute) - sizeof(int32_t) + attr_len + pad; current = (PackedAttribute *) pos; } return attr_vec;}bool PerfectMatch(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2){ if (attr_vec1->size() != attr_vec2->size()) return false; if (OneWayPerfectMatch(attr_vec1, attr_vec2)) if (OneWayPerfectMatch(attr_vec2, attr_vec1)) return true; return false;}bool OneWayPerfectMatch(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2){ NRAttrVec::iterator itr1, itr2; NRAttribute *a; NRAttribute *b; for (itr1 = attr_vec1->begin(); itr1 != attr_vec1->end(); ++itr1){ // For each attribute in vec1, we look in vec2 for the same attr a = *itr1; itr2 = attr_vec2->begin(); b = a->find_matching_key_from(attr_vec2, itr2, &itr2); while (b){ // They should have the same operator and be "EQUAL" if (a->getOp() == b->getOp()) if (a->isEQ(b)) break; // Keys match but value/operator don't. Let's // Try to find another attribute with the same key itr2++; b = a->find_matching_key_from(attr_vec2, itr2, &itr2); } // Check if attribute found if (b == NULL) return false; } // All attributes match ! return true;}bool MatchAttrs(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2){ if (OneWayMatch(attr_vec1, attr_vec2)) if (OneWayMatch(attr_vec2, attr_vec1)) return true; return false;}bool OneWayMatch(NRAttrVec *attr_vec1, NRAttrVec *attr_vec2){ NRAttrVec::iterator itr1, itr2; NRAttribute *a; NRAttribute *b; bool found_attr; for (itr1 = attr_vec1->begin(); itr1 != attr_vec1->end(); ++itr1){ // For each attribute in vec1 that has an operator different // than "IS", we need to find a "matchable" one in vec2 a = *itr1; if (a->getOp() == NRAttribute::IS) continue; itr2 = attr_vec2->begin(); for (;;){ b = a->find_matching_key_from(attr_vec2, itr2, &itr2); // Found ? if (!b) return false; // If Op is not "IS" we need keep looking if (b->getOp() != NRAttribute::IS){ itr2++; continue; } // If a's Op is "EQ_ANY" that's enough if (a->getOp() == NRAttribute::EQ_ANY){ found_attr = true; break; } found_attr = false; switch (a->getOp()){ case NRAttribute::EQ: if (b->isEQ(a)) found_attr = true; break; case NRAttribute::GT: if (b->isGT(a)) found_attr = true; break; case NRAttribute::GE: if (b->isGE(a)) found_attr = true; break; case NRAttribute::LT: if (b->isLT(a)) found_attr = true; break; case NRAttribute::LE: if (b->isLE(a)) found_attr = true; break; case NRAttribute::NE: if (b->isNE(a)) found_attr = true; break; default: DiffPrint(DEBUG_ALWAYS, "Unknown operator found in OneWayMacth !\n"); break; } if (found_attr) break; itr2++; } } // All attributes found ! return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -