// file: $isip/class/asr/AnnotationIndex/anno_5.cc // version: $Id: andx_05.cc 8785 2002-11-13 00:21:46Z alphonso $ // // isip include files // #include "AnnotationIndex.h" // method: clear // // arguments: // Integral::CMODE cmode: (input) clear mode // // return: logical error status // // this method clears the content of the current object // bool8 AnnotationIndex::clear(Integral::CMODE cmode_a) { // declare local variables // bool8 status = false; status = ancrset_d.clear(cmode_a); status &= ancr_by_id_d.clear(cmode_a); status &= ancrset_by_offset_d.clear(cmode_a); status &= anno_by_id_d.clear(cmode_a); status &= anno_by_type_d.clear(cmode_a); status &= start_by_offset_d.clear(cmode_a); status &= end_by_offset_d.clear(cmode_a); status &= incoming_d.clear(cmode_a); status &= outgoing_d.clear(cmode_a); status &= by_feature_d.clear(cmode_a); // return the ;ogical status // return status; } // method: eq // // arguments: // const AnnotationIndex& arg: (input) annotation Index // // return: logical error status // // method determines if the input and the current graphs are equal // bool8 AnnotationIndex::eq(const AnnotationIndex& arg_a) const { // determine if the member data are equal // if (!ancrset_d.eq(arg_a.ancrset_d)) { return false; } if (!ancr_by_id_d.eq(arg_a.ancr_by_id_d)) { return false; } if (!ancrset_by_offset_d.eq(arg_a.ancrset_by_offset_d)) { return false; } if (!anno_by_id_d.eq(arg_a.anno_by_id_d)) { return false; } if (!anno_by_type_d.eq(arg_a.anno_by_type_d)) { return false; } if (!start_by_offset_d.eq(arg_a.start_by_offset_d)) { return false; } if (!end_by_offset_d.eq(arg_a.end_by_offset_d)) { return false; } if (!incoming_d.eq(arg_a.incoming_d)) { return false; } if (!outgoing_d.eq(arg_a.outgoing_d)) { return false; } if (!by_feature_d.eq(by_feature_d)) { return false; } // return the logical status // return true; } // method: assign // // arguments: // const AnnotationIndex& arg: (input) annotation Index // // return: logical error status // // method assigns the input annotation Index to the current one // bool8 AnnotationIndex::assign(const AnnotationIndex& arg_a) { // declare local variables // bool8 status = false; // assign the member data // status = ancrset_d.assign(arg_a.ancrset_d); status &= ancr_by_id_d.assign(arg_a.ancr_by_id_d); status &= ancrset_by_offset_d.assign(arg_a.ancrset_by_offset_d); status &= anno_by_id_d.assign(arg_a.anno_by_id_d); status &= anno_by_type_d.assign(arg_a.anno_by_type_d); status &= start_by_offset_d.assign(arg_a.start_by_offset_d); status &= end_by_offset_d.assign(arg_a.end_by_offset_d); status &= incoming_d.assign(arg_a.incoming_d); status &= outgoing_d.assign(arg_a.outgoing_d); status &= by_feature_d.assign(by_feature_d); // return the logical status // return status; } // method: add // // arguments: // Annotation* anno: (input) annotation to be added // // return: logical error status // // method to add an annotation to the indexes // bool8 AnnotationIndex::add(Annotation* anno_a) { // declare local variables // Vector keys; HashKey hashkey; HashTable features; DoubleLinkedList tmplist(DstrBase::USER); tmplist.insert(anno_a); // get the start and end anchors of the annotation // Anchor* start_anchor = anno_a->getStartAnchor(); Anchor* end_anchor = anno_a->getEndAnchor(); // hash the annotation via the identifier // anno_by_id_d.insert(anno_a->getId(), anno_a); // hash the annotation via the type // if (anno_by_type_d.containsKey(anno_a->getType())) { if (!anno_by_type_d.get(anno_a->getType())->contains(anno_a)) { anno_by_type_d.get(anno_a->getType())->insert(anno_a); } } else { anno_by_type_d.insert(anno_a->getType(), &tmplist); } // hash the features for the annotation // features = anno_a->getFeatureMap(); features.keys(keys); for (int i=0; i < keys.length(); i++) { addFeature(anno_a, keys(i), *features.get(keys(i))); } // hash the annotation by the start offset if it is anchored // if (start_anchor->getAnchored()) { if (start_by_offset_d.containsKey(start_anchor->getOffset())) { if (!start_by_offset_d.get(start_anchor->getOffset())->contains(anno_a)) { start_by_offset_d.get(start_anchor->getOffset())->insert(anno_a); } } else { start_by_offset_d.insert(start_anchor->getOffset(), &tmplist); } } // hash the annotation by the end offset if it is anchored // if (end_anchor->getAnchored()) { if (end_by_offset_d.containsKey(end_anchor->getOffset())) { if (!end_by_offset_d.get(end_anchor->getOffset())->contains(anno_a)) { end_by_offset_d.get(end_anchor->getOffset())->insert(anno_a); } } else { end_by_offset_d.insert(end_anchor->getOffset(), &tmplist); } } // the annotation leaves the start anchor - add it to the outgoing list // hashkey.assign(start_anchor); if (outgoing_d.containsKey(hashkey)) { if (!outgoing_d.get(hashkey)->contains(anno_a)) { outgoing_d.get(hashkey)->insert(anno_a); } } else { outgoing_d.insert(hashkey, &tmplist); } // the annotation enters the end anchor - add it to the incoming list // hashkey.assign(end_anchor); if (incoming_d.containsKey(hashkey)) { if (!incoming_d.get(hashkey)->contains(anno_a)) { incoming_d.get(hashkey)->insert(anno_a); } } else { incoming_d.insert(hashkey, &tmplist); } // add the start anchor to the anchor set // addAnchor(start_anchor); // add the end anchor to the anchor set // addAnchor(end_anchor); // exit gracefully // return true; } // method: deleteAnnotation // // arguments: // Annotation* anno: (input) annotation to be deleted // // return: logical error status // // method to delete an annotation from the indexes // bool8 AnnotationIndex::deleteAnnotation(Annotation* anno_a) { // declare local variables // Vector keys; HashKey hashkey; HashTable features; // get the start and end anchors of the annotation // Anchor* start_anchor = anno_a->getStartAnchor(); Anchor* end_anchor = anno_a->getEndAnchor(); // delete the annotation via the identifier // if (anno_by_id_d.containsKey(anno_a->getId())) { anno_by_id_d.remove(anno_a->getId()); } // delete the annotation via the type // if (anno_by_type_d.containsKey(anno_a->getType())) { if (anno_by_type_d.get(anno_a->getType())->find(anno_a)) { anno_by_type_d.get(anno_a->getType())->remove(); } if (anno_by_type_d.get(anno_a->getType())->isEmpty()) { anno_by_type_d.remove(anno_a->getType()); } } // delete the features for the annotation // features = anno_a->getFeatureMap(); features.keys(keys); for (int i=0; i < keys.length(); i++) { deleteFeature(anno_a, keys(i)); } // delete the annotation by the start offset if it is anchored // if (start_anchor->getAnchored()) { if (start_by_offset_d.containsKey(start_anchor->getOffset())) { if (start_by_offset_d.get(start_anchor->getOffset())->find(anno_a)) { start_by_offset_d.get(start_anchor->getOffset())->remove(); } if (start_by_offset_d.get(start_anchor->getOffset())->isEmpty()) { start_by_offset_d.remove(start_anchor->getOffset()); } } } // delete the annotation by the end offset if it is anchored // if (end_anchor->getAnchored()) { if (end_by_offset_d.containsKey(end_anchor->getOffset())) { if (end_by_offset_d.get(end_anchor->getOffset())->find(anno_a)) { end_by_offset_d.get(end_anchor->getOffset())->remove(); } if (end_by_offset_d.get(end_anchor->getOffset())->isEmpty()) { end_by_offset_d.remove(end_anchor->getOffset()); } } } // the annotation leaves the start anchor - remove it to the outgoing list // hashkey.assign(start_anchor); if (outgoing_d.containsKey(hashkey)) { if (outgoing_d.get(hashkey)->find(anno_a)) { outgoing_d.get(hashkey)->remove(); } if (outgoing_d.get(hashkey)->isEmpty()) { outgoing_d.remove(hashkey); } } // the annotation enters the end anchor - remove it to the incoming list // hashkey.assign(end_anchor); if (incoming_d.containsKey(hashkey)) { if (incoming_d.get(hashkey)->find(anno_a)) { incoming_d.get(hashkey)->remove(); } if (incoming_d.get(hashkey)->isEmpty()) { incoming_d.remove(hashkey); } } // exit gracefully // return true; } // method: existsFeature // // arguments: // const String& feature: (input) annotation feature // const String& value: (input) annotation feature value // // return: logical error status // // method to check if a feature-value pair exists // bool8 AnnotationIndex::existsFeature(const String& feature_a, const String& value_a) { // declare local variables // String index; // generate the hash index // index.assign(feature_a); index.concat(value_a); // determine if the key exists // return by_feature_d.containsKey(index); } // method: addFeature // // arguments: // Annotation* anno: (input) annotation // const String& feature: (input) annotation feature // const String& value: (input) annotation feature value // // return: logical error status // // method to insert the feature-value pair into the feature map // bool8 AnnotationIndex::addFeature(Annotation* anno_a, const String& feature_a, const String& value_a) { // declare local variables // String index; DoubleLinkedList tmplist(DstrBase::USER); tmplist.insert(anno_a); // generate the hash key // index.assign(feature_a); index.concat(value_a); // hash the annotation via the feature-value pair // if (by_feature_d.containsKey(index)) { if (!by_feature_d.get(index)->contains(anno_a)) { by_feature_d.get(index)->insert(anno_a); } } else { by_feature_d.insert(index, &tmplist); } // exit gracefully // return true; } // method: deleteFeature // // arguments: // Annotation* anno: (input) annotation // const String& feature: (input) annotation feature // // return: logical error status // // method that deletes the feature-value pair from the feature map // bool8 AnnotationIndex::deleteFeature(Annotation* anno_a, const String& feature_a) { // declare local variables // String value; String index; // remove the key value pait from the annotation // if (anno_a->existsFeature(feature_a)) { // generate the hash index // value = anno_a->getFeature(feature_a); index.assign(feature_a); index.concat(value); if (by_feature_d.containsKey(index)) { if (by_feature_d.get(index)->find(anno_a)) { by_feature_d.get(index)->remove(); } if (by_feature_d.get(index)->isEmpty()) { by_feature_d.remove(index); } } } // exit gracefully // return true; } // method: getNearestOffset // // arguments: // float32 offset: (input) anchor offset // // return: logical error status // // method to get the nearest used offset to the specified offset // float32 AnnotationIndex::getNearestOffset(float32 offset_a) { // declare local variables // float32 min_offset = 0.0; float32 min_delta = 1.0e10; Vector keys; // check if the hash table of anchor sets is empty // if (ancrset_by_offset_d.isEmpty()) { return min_offset; } // get the vector of keys from the hash table // ancrset_by_offset_d.keys(keys); // loop through the set of keys and find the nearest offset // if (keys.length() == 1) { return (float32)keys(0); } for (int i=0; i < keys.length(); i++) { if (Integral::abs(keys(i) - offset_a) < min_delta) { min_offset = keys(i); min_delta = Integral::abs(keys(i) - offset_a); } } // return the nearest offset // return min_offset; } // method: getByOffset // // arguments: // float32 offset: (input) anchor offset // DoubleLinkedList& list: (input) list of annotations // // return: logical error status // // method that gets the annotations that overlap a particular time offset. // gets all annotations whose start anchor offset is smaller than or // equal to the given offset AND end anchor offset is greater than // or equal to the given offet // bool8 AnnotationIndex::getByOffset(float32 offset_a, DoubleLinkedList& list_a) { // declare local variables // Vector end_keys; Vector start_keys; Anchor* anchor = (Anchor*)NULL; Annotation* annotation = (Annotation*)NULL; DoubleLinkedList* alist; // clear the input list to begin with // list_a.clear(); // check to make sure that the offset is greater than zero // if (offset_a < 0.0) { return false; } // get the vector of keys from the start and end offset hash tables // start_by_offset_d.keys(start_keys); end_by_offset_d.keys(end_keys); // loop over the start keys and gets all annotations whose start anchor // offset is smaller than or equal to the given offset // for (int i=0; i < start_keys.length(); i++) { if (start_keys(i) <= offset_a) { // check if the end offset is greater than or equal to the given offet // alist = start_by_offset_d.get(start_keys(i)); for(bool8 more = alist->gotoFirst(); more; more = alist->gotoNext()) { annotation = alist->getCurr(); anchor = annotation->getEndAnchor(); if ((anchor != (Anchor*)NULL) && (anchor->getOffset() >= offset_a)) { if (!list_a.contains(annotation)) { list_a.insert(annotation); } } } } } // loop over all end keys and gets all annotations whose end anchor // offset is greater than or equal to the given offet // for (int i=0; i < end_keys.length(); i++) { if (end_keys(i) >= offset_a) { // check if the start offset is smaller than or equal to the given offset // alist = end_by_offset_d.get(end_keys(i)); for(bool8 more = alist->gotoFirst(); more; more = alist->gotoNext()) { annotation = alist->getCurr(); anchor = annotation->getStartAnchor(); if ((anchor != (Anchor*)NULL) && (anchor->getOffset() <= offset_a)) { if (!list_a.contains(annotation)) { list_a.insert(annotation); } } } } } // exit gracefully // return true; } // method: getAnnotationByOffset // // arguments: // float32 offset: (input) anchor offset // // return: logical error status // // method get one of the annotations which overlap a particular time offset. // same as getByOffset except that getAnnotationByOffset returns only // one qualified annotation while getByOffset returns all of them // Annotation* AnnotationIndex::getAnnotationByOffset(float32 offset_a) { // declare local variables // Vector end_keys; Vector start_keys; Anchor* anchor = (Anchor*)NULL; Annotation* annotation = (Annotation*)NULL; DoubleLinkedList* alist; // check to make sure that the offset is greater than zero // if (offset_a < 0.0) { return (Annotation*)NULL; } // get the vector of keys from the start offset hash tables // start_by_offset_d.keys(start_keys); // loop over the start keys and gets all annotations whose start anchor // offset is smaller than or equal to the given offset // for (int i=0; i < start_keys.length(); i++) { if (start_keys(i) <= offset_a) { // check if the end offset is greater than or equal to the given offet // alist = start_by_offset_d.get(start_keys(i)); for(bool8 more = alist->gotoFirst(); more; more = alist->gotoNext()) { annotation = alist->getCurr(); anchor = annotation->getEndAnchor(); if ((anchor != (Anchor*)NULL) && (anchor->getOffset() >= offset_a)) { return annotation; } } } } // get the vector of keys from the end offset hash tables // end_by_offset_d.keys(end_keys); // loop over all end keys and gets all annotations whose end anchor // offset is greater than or equal to the given offet // for (int i=0; i < end_keys.length(); i++) { if (end_keys(i) >= offset_a) { // check if the start offset is smaller than or equal to the given offset // alist = end_by_offset_d.get(end_keys(i)); for(bool8 more = alist->gotoFirst(); more; more = alist->gotoNext()) { annotation = alist->getCurr(); anchor = annotation->getStartAnchor(); if ((anchor != (Anchor*)NULL) && (anchor->getOffset() <= offset_a)) { return annotation; } } } } // return the annotation // return (Annotation*)NULL; } // method: existsAnnotation // // arguments: // const String& id: (input) annotation id // // return: logical error status // // method to check if the specified annotation exists // bool8 AnnotationIndex::existsAnnotation(const String& id_a) { // determine if the annotation exists // return anno_by_id_d.containsKey(id_a); } // method: existsAnchor // // arguments: // const String& id: (input) anchor id // // return: logical error status // // method to check if the specified anchor exists // bool8 AnnotationIndex::existsAnchor(const String& id_a) { // determine if the annotation exists // return ancr_by_id_d.containsKey(id_a); } // method: addAnchor // // arguments: // Anchor* ancr: (input) anchor to be added // // return: logical error status // // method to add an anchor to the indexes // bool8 AnnotationIndex::addAnchor(Anchor* ancr_a) { // declare local variables // HashKey hashkey; Float offset(ancr_a->getOffset()); DoubleLinkedList* incoming; DoubleLinkedList* outgoing; DoubleLinkedList annlist(DstrBase::USER); DoubleLinkedList tmplist(DstrBase::USER); tmplist.insert(ancr_a); // determine if the offset is present - if not then delete it // if (!ancrset_d.contains(ancr_a)) { ancrset_d.insert(ancr_a); ancr_by_id_d.insert(ancr_a->getId(), ancr_a); } // hash the anchor by the offset // if (ancr_a->getAnchored()) { if (ancrset_by_offset_d.containsKey(offset)) { if (!ancrset_by_offset_d.get(offset)->contains(ancr_a)) { ancrset_by_offset_d.get(offset)->insert(ancr_a); } } else { ancrset_by_offset_d.insert(offset, &tmplist); } // get the incoming and outgoing annotations to/from the anchor // hashkey.assign(ancr_a); incoming = incoming_d.get(hashkey); outgoing = outgoing_d.get(hashkey); // loop over all incoming annotations to the anchor and hash them // by the end anchor offset // if (incoming != (DoubleLinkedList*)NULL) { for (bool8 more = incoming->gotoFirst(); more; more = incoming->gotoNext()) { if (end_by_offset_d.containsKey(offset)) { if (!end_by_offset_d.get(offset)->contains(incoming->getCurr())) { end_by_offset_d.get(offset)->insert(incoming->getCurr()); } } else { annlist.clear(); annlist.insert(incoming->getCurr()); end_by_offset_d.insert(offset, &annlist); } } } // loop over all outgoing annotations from the anchor and hash them // by the start anchor offset // if (outgoing != (DoubleLinkedList*)NULL) { for (bool8 more = outgoing->gotoFirst(); more; more = outgoing->gotoNext()) { if (start_by_offset_d.containsKey(offset)) { if (!start_by_offset_d.get(offset)->contains(outgoing->getCurr())) { start_by_offset_d.get(offset)->insert(outgoing->getCurr()); } } else { annlist.clear(); annlist.insert(outgoing->getCurr()); start_by_offset_d.insert(offset, &annlist); } } } } // exit gracefully // return true; } // method: deleteAnchor // // arguments: // Anchor* ancr: (input) anchor to be deleted // // return: logical error status // // method to delete an anchor to the indexes // bool8 AnnotationIndex::deleteAnchor(Anchor* ancr_a) { // declare local variables // Annotation* anno; HashKey hashkey; Float offset(ancr_a->getOffset()); DoubleLinkedList* incoming; DoubleLinkedList* outgoing; // determine if the offset is present - if not then delete it // if (ancrset_d.find(ancr_a)) { ancrset_d.remove(); ancr_by_id_d.remove(ancr_a->getId()); } // delete the anchor by the offset // if (ancr_a->getAnchored()) { ancrset_by_offset_d.remove(offset); // get the incoming and outgoing annotations to/from the anchor // hashkey.assign(ancr_a); incoming = incoming_d.get(hashkey); outgoing = outgoing_d.get(hashkey); // loop over all incoming annotations to the anchor and remove them // by the end anchor offset // if (incoming != (DoubleLinkedList*)NULL) { for (bool8 more = incoming->gotoFirst(); more; more = incoming->gotoNext()) { if (end_by_offset_d.containsKey(offset)) { anno = incoming->getCurr(); if (end_by_offset_d.get(offset)->find(anno)) { end_by_offset_d.get(offset)->remove(); } if (end_by_offset_d.get(offset)->isEmpty()) { end_by_offset_d.remove(offset); } } } } // loop over all outgoing annotations from the anchor and remove them // by the start anchor offset // if (outgoing != (DoubleLinkedList*)NULL) { for (bool8 more = outgoing->gotoFirst(); more; more = outgoing->gotoNext()) { if (start_by_offset_d.containsKey(offset)) { anno = outgoing->getCurr(); if (start_by_offset_d.get(offset)->find(anno)) { start_by_offset_d.get(offset)->remove(); } if (start_by_offset_d.get(offset)->isEmpty()) { start_by_offset_d.remove(offset); } } } } } // exit gracefully // return true; }