package org.freertr.tab; import org.freertr.addr.addrPrefix; import org.freertr.addr.addrType; import org.freertr.util.bits; import org.freertr.util.cmds; import org.freertr.util.counter; /** * one index to prefix entry * * @param type of address * @author matecsaba */ public class tabIndex implements Comparable> { /** * index */ public final int index; /** * prefix */ public final addrPrefix prefix; /** * neighbors */ public tabGen> neighs; /** * bitmap */ public int bitmap; /** * connected */ public boolean conned; /** * counter */ public counter cntr = new counter(); /** * hardware counter */ public counter hwCntr; /** * create entry * * @param idx index * @param prf prefix */ public tabIndex(int idx, addrPrefix prf) { index = idx; prefix = prf; } public String toString() { return index + " " + prefix; } /** * copy entry * * @return copy */ public tabIndex copyBytes() { tabIndex n = new tabIndex(index, prefix.copyBytes()); n.conned = conned; n.bitmap = bitmap; if (neighs != null) { n.neighs = new tabGen>(neighs); } return n; } /** * compare to entry * * @param o other entry * @return true if differs, false if equals */ public boolean differs(tabIndex o) { if (bitmap != o.bitmap) { return true; } if (conned != o.conned) { return true; } if (prefix == null) { if (o.prefix != null) { return true; } } else { if (o.prefix == null) { return true; } if (prefix.compareTo(o.prefix) != 0) { return true; } } if (neighs == null) { if (o.neighs != null) { return true; } } else { if (o.neighs == null) { return true; } if (neighs.size() != o.neighs.size()) { return true; } for (int i = 0; i < neighs.size(); i++) { if (neighs.get(i).index != o.neighs.get(i).index) { return true; } } } return false; } public int compareTo(tabIndex o) { if (index < o.index) { return -1; } if (index > o.index) { return +1; } return 0; } /** * is better than other * * @param o other entry * @return true if better, false if not */ public boolean isBetter(tabIndex o) { if (prefix.maskLen < o.prefix.maskLen) { return false; } if (prefix.maskLen > o.prefix.maskLen) { return true; } return prefix.compareTo(o.prefix) < 0; } /** * merge tables * * @param type of address * @param trg target table * @param src source entry * @return true if added, false if not */ public static boolean add2table(tabGen> trg, tabIndex src) { tabIndex old = trg.add(src); if (old == null) { return true; } if (!src.isBetter(old)) { return false; } trg.put(src); return true; } /** * merge tables * * @param type of address * @param trg target table * @param src source table * @return entries added */ public static int mergeTable(tabGen> trg, tabGen> src) { if (src == null) { return -1; } int cnt = 0; for (int i = 0; i < src.size(); i++) { tabIndex ntry = src.get(i); if (add2table(trg, ntry.copyBytes())) { cnt++; } } return cnt; } /** * convert tables * * @param type of address * @param src source list * @return converted */ public static String convertTable(tabGen> src) { if (src == null) { return "null"; } String a = ""; for (int i = 0; i < src.size(); i++) { a += " " + src.get(i).index; } if (src.size() > 0) { a = a.substring(1, a.length()); } return a; } /** * convert tables * * @param type of address * @param cmd source list * @return converted */ public static tabGen> convertTable(cmds cmd) { tabGen> res = new tabGen>(); for (;;) { String a = cmd.word(); if (a.length() < 1) { break; } tabIndex ntry = new tabIndex(bits.str2num(a), null); res.put(ntry); } return res; } /** * compare tables * * @param type of address * @param t1 first table * @param t2 second table * @return true if differs, false if equals */ public static boolean compareTables(tabGen> t1, tabGen> t2) { if ((t1 == null) && (t2 == null)) { return false; } if (t1 == null) { return true; } if (t2 == null) { return true; } if (t1.size() != t2.size()) { return true; } for (int i = 0; i < t1.size(); i++) { tabIndex ntry = t1.get(i); if (ntry.differs(t2.get(i))) { return true; } } return false; } }