things we need to do: - decide what nodes to decode and encode - of the resulting (and existing) chunks, decide which to keep on the server - decide what uploads and downloads to start ============================== MC::classify() classify nodes as PRESENT/RECOVERABLE/UNRECOVERABLE, and compute recovery sets and recovery cost NOTE: recovery cost should take into account uploads in progress (treat them as zero cost) for each chunk C C.new_present_on_server = C.present_on_server if C.status == PRESENT and need more replicas or download in progress C.keep_present = true // set need_recon, needed_by_parent, keep_present, need_present // MC::decide_reconstruct if some child is UNREC if PRESENT need_recon = true else if RECOVERABLE need_present = true for children C in recovery set if C is PRESENT C.keep_present = true else C.need_present = true; if needed_by_parent need_recon = true if need_recon and not bottom-level mark N PRESENT children as needed_by_parent if keep_present mark N PRESENT children as keep_present if not bottom-level recurse // - do encoding and decoding; // - delete all meta-chunk files when done; // - delete unneeded chunks // - set new_present_on_server // MC::reconstruct_and_cleanup recurse if need_recon decode this.expand() if !needed_by_parent delete this if bottom level npresent = M for each child C if C.status != UNREC && !C.keep_present if !keep_present or npresent > N delete C npresent-- C.new_present_on_server = false // called if this unit has been reconstructed. // Expand (i.e. encode) it if needed, and recurse. // Clean up unneeded files. // MC::expand if bottom-level if some child C is not PRESENT and needs more replicas encode for each child C if need more replicas or download in progress C.new_present_on_server = true else C.new_present_on_server = false delete C else if some child is UNREC encode for each child C with status != UNREC delete C for each child C with status == UNREC C.expand() delete C start_xfers_and_update_db for each chunk C if C.new_present_on_server and need more replicas start downloads of C if C.need_present start upload(s) of C if C.new_present_on_server != C.present_on_server C.update() MC::compute_min_failures recurse present, recoverable: lists of chunks if bottom-level for each child C if C.new_present_on_server add C to present else if C has N replicas C.min_failures = N add C to recoverable else for each child C if PRESENT, add C to present if RECO, add C to recoverable if size(present) >= N status = PRESENT min_failures = INT_MAX else if size(present) + size(recoverable)