attrs.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:13k
- //
- // 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.7 2005/09/13 04:53:49 tomh 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.
- //
- // Linking this file statically or dynamically with other modules is making
- // a combined work based on this file. Thus, the terms and conditions of
- // the GNU General Public License cover the whole combination.
- //
- // In addition, as a special exception, the copyright holders of this file
- // give you permission to combine this file with free software programs or
- // libraries that are released under the GNU LGPL and with code included in
- // the standard release of ns-2 under the Apache 2.0 license or under
- // otherwise-compatible licenses with advertising requirements (or modified
- // versions of such code, with unchanged license). You may copy and
- // distribute such a system following the terms of the GNU GPL for this
- // file and the licenses of the other code concerned, provided that you
- // include the source code of that other code when and as the GNU GPL
- // requires distribution of source code.
- //
- // Note that people who make modified versions of this file are not
- // obligated to grant this special exception for their modified versions;
- // it is their choice whether to do so. The GNU General Public License
- // gives permission to release a modified version without this exception;
- // this exception also makes it possible to release a modified version
- // which carries forward this exception.
- //
- #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 #%dn", counter);
- counter++;
- DiffPrint(DEBUG_ALWAYS, "-------------n");
- DiffPrint(DEBUG_ALWAYS, "Type = %dn", aux->getType());
- DiffPrint(DEBUG_ALWAYS, "Key = %dn", aux->getKey());
- DiffPrint(DEBUG_ALWAYS, "Op = %dn", aux->getOp());
- DiffPrint(DEBUG_ALWAYS, "Len = %dn", aux->getLen());
- switch(aux->getType()){
- case NRAttribute::INT32_TYPE:
- DiffPrint(DEBUG_ALWAYS, "Val = %dn",
- ((NRSimpleAttribute<int> *)aux)->getVal());
- break;
- case NRAttribute::FLOAT32_TYPE:
- DiffPrint(DEBUG_ALWAYS, "Val = %fn",
- ((NRSimpleAttribute<float> *)aux)->getVal());
- break;
- case NRAttribute::FLOAT64_TYPE:
- DiffPrint(DEBUG_ALWAYS, "Val = %fn",
- ((NRSimpleAttribute<double> *)aux)->getVal());
- break;
- case NRAttribute::STRING_TYPE:
- DiffPrint(DEBUG_ALWAYS, "Val = %sn",
- ((NRSimpleAttribute<char *> *)aux)->getVal());
- break;
- case NRAttribute::BLOB_TYPE:
- DiffPrint(DEBUG_ALWAYS, "Val = %sn",
- ((NRSimpleAttribute<void *> *)aux)->getVal());
- break;
- default:
- DiffPrint(DEBUG_ALWAYS, "Val = Unknownn");
- 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;
- }