package edu.lsu.cct.MCSMPGC; import java.util.ArrayDeque; import java.util.Iterator; import java.util.NoSuchElementException; public class Collector extends Thread { int address; ArrayDeque queue = new ArrayDeque(); public Collector(int address) { this.address = address; } public void run() { Node no = Main.memory.allocated.get(this.address); if (no.getSRC() == 0 && no.getWRC() > 0) { Collapse c = collapse(no); c.phase = Collapse.RECOVERY; recovery(c); delete(no, c); } else if (no.getSRC() == 0 && no.getWRC() == 0 && no.getPhantom() == 0 && no.getPhantom_self() == 0) { System.out .println("node can be deleted and started a collector when any weak link found"); } System.out.println("free " + Main.memory.free.size() + " allocated " + Main.memory.allocated.size()); } private void delete(Node no, Collapse c) { if (no.getSRC() == 0 && no.getWRC() == 0 && no.getPhantom() == 0 && no.getPhantom_self() > 0) { c.phase = Collapse.DELETE; for (int i = 0; i < no.refs.getCount(); i++) { queue.add(Main.memory.allocated.get(no.refs.links.get(i).to)); // System.out.println("added " + no.refs.links.get(i).to); if (no.refs.links.get(i).to == c.no) { no.refs.delete(no.refs.links.get(i).to, c.no); } else { no.refs.delete(no.refs.links.get(i).to); } } while (true) { try { Node current = queue.remove(); for (int i = 0; i < current.refs.getCount(); i++) { queue.add(Main.memory.allocated.get(current.refs.links .get(i).to)); if (current.refs.links.get(i).to == c.no) { current.refs.delete(current.refs.links.get(i).to, c.no); } else { current.refs.delete(current.refs.links.get(i).to); } } if (current.isDeletable()) { current.free(); } } catch (NoSuchElementException e) { break; } } } } private void recovery(Collapse c) { int flag = 0; Iterator it = c.recoveryList.iterator(); while (it.hasNext()) { Node n = (Node) it.next(); if (n.getSRC() > 0) { queue.add(n); } } while (true) { try { Node current = queue.remove(); if (current.getSRC() > 0) { flag = 1; if (current.getPhantom() == 0 && current.getPhantom_self() == 0) { current.collapseptr = -1; if (current.getPhantomLinkCount() > 0) { for (int i = 0; i < current.refs.getCount(); i++) { if (current.refs.links.get(i).isPhantomized() || current.refs.links.get(i) .isSelfPhantomized()) { Node x = Main.memory.allocated .get(current.refs.links.get(i).to); queue.add(x); boolean ps = false; if (current.refs.links.get(i).to == c.no) ps = true; int w = x.giveSupport(ps); current.refs.links.get(i).unphantomize(); current.refs.links.get(i).which = w; } } } } } } catch (NoSuchElementException e) { break; } } if(flag==1) traversal(c.no); } private void traversal(int address) { // TODO Auto-generated method stub if (Main.memory.anchors.contains(address)) { System.out.println("The object at address " + address + " is an anchor"); Node first = Main.memory.allocated.get(address); Node next = first; while (true) { System.out.print(next.value + " -> " + ((Reference) next.refs.links.get(0)).type() + " "); next = Main.memory.allocated.get(next.refs.links.get(0).to); if (next == first) { System.out.print(first.address); break; } } } } private Collapse collapse(Node no) { no.toggleWhich(); Collapse c = new Collapse(no.address); Node current = no; c.recoveryList.add(no); current.collapseptr = c.no; while (true) { for (int i = 0; i < current.refs.getCount(); i++) { if (!current.refs.links.get(i).isPhantomized() && !current.refs.links.get(i).isSelfPhantomized()) { if (current.refs.links.get(i).to != c.no) current.refs.links.get(i).phantomize(); else current.refs.links.get(i).phantomizeSelf(); queue.add(Main.memory.allocated.get(current.refs.links .get(i).to)); } else { System.out.println("output the votes back" + current.address); } } try { while (true) { Node num = queue.remove(); current = num; if (current.getSRC() > 0) { c.recoveryList.add(current); current.collapseptr = c.no; } if (current.getSRC() == 0 && current.getWRC() > 0) { c.recoveryList.add(current); current.toggleWhich(); current.collapseptr = c.no; break; } if (current.getSRC() == 0) { current.collapseptr = c.no; break; } } } catch (NoSuchElementException e) { break; } } return c; } }