public Filesystem(Stream basestream, string pswd, int seglen, long partitionLen) { _seglen = seglen; bool empty = basestream.Length <16389; Stream mstream = SeekableCryptoStream.CreateUltraSecureStream(pswd,seglen, basestream); fstream = mstream; if (empty) { BinaryWriter mwriter = new BinaryWriter(fstream); mwriter.Write("IC80v3"); long cpos = fstream.Position; mwriter.Write(new char[256]); mwriter.Write(partitionLen); mwriter.Write(false); fragments.Add(-1, new List<IC80Fragment>()); IC80Fragment lament = new IC80Fragment(); lament.name = -1; lament.size = partitionLen; lament.FragmentPosition = cpos; fragments[-1].Add(lament); mwriter.Flush(); } else { BinaryReader mreader = new BinaryReader(fstream); string xt = mreader.ReadString(); if (xt != "IC80v3") { throw new Exception("This library only supports IC80 version 3 file systems."); } while (true) { IC80Fragment mf = new IC80Fragment(); mf.Read(mreader); if (!fragments.ContainsKey(mf.name)) { fragments.Add(mf.name, new List<IC80Fragment>()); } fragments[mf.name].Add(mf); if (!mf.hasNextFile) { break; }else { fstream.Position +=mf.size; } } } FreeSpace.ToString(); }
/// <summary> /// Allocs a contiguous region of free space /// </summary> /// <param name='file'> /// File name /// </param> /// <param name='len'> /// Length to allocate (in bytes) /// </param> public void AllocSpace(long file,long len) { if(!fragments.ContainsKey(file)) { fragments.Add(file,new List<IC80Fragment>()); } lock(fragments[-1]) { foreach (IC80Fragment et in fragments[-1]) { if (et.size > len + IC80Fragment.GetSize()) { fragments[-1].Remove(et); et.name = file; et.haschanged = true; et.hasNextFile = true; IC80Fragment freefrag = new IC80Fragment(); freefrag.name = -1; freefrag.haschanged = true; //Compute fragment position. Immediately after this file freefrag.FragmentPosition = len + et.FragmentPosition + IC80Fragment.GetSize(); freefrag.size = et.size - len; et.size = len; fragments[file].Add(et); Console.WriteLine("File " + file.ToString() + " has " + fragments[file].Count.ToString() + " fragments"); fragments[-1].Add(freefrag); break; } } } }
IC80Fragment GetAdjacentFragment(IC80Fragment src) { foreach(KeyValuePair<long,List<IC80Fragment>> et in fragments) { foreach(IC80Fragment ett in et.Value) { if(ett.FragmentPosition >= src.FragmentPosition+src.size+IC80Fragment.GetSize()) { return ett; } } } return null; }
/// <summary> /// Allocs a contiguous region of free space /// </summary> /// <param name='file'> /// File name /// </param> /// <param name='len'> /// Length to allocate (in bytes) /// </param> public void AllocSpace(long file,long len) { if(!fragments.ContainsKey(file)) { fragments.Add(file,new List<IC80Fragment>()); } lock(fragments[-1]) { if (fragments[file].Count > 0) { IC80Fragment endfrag = null; long maxpos = -8; foreach(IC80Fragment et in fragments[file]) { if(et.FragmentPosition>maxpos) { maxpos = et.FragmentPosition; endfrag = et; } } long lastfrag_end = endfrag.FragmentPosition + endfrag.size + IC80Fragment.GetSize(); foreach (IC80Fragment et in fragments[-1]) { //TODO: This has been disabled for testing purposes break; bool foundbug = false; if (et.FragmentPosition == lastfrag_end && et.size>len) { //Resize existing fragment, without creating a new one foreach(KeyValuePair<long,List<IC80Fragment>> fraglist in fragments) { foreach(IC80Fragment frag in fraglist.Value) { if(frag !=et) { if(et.FragmentPosition+len>=frag.FragmentPosition && et.size+et.FragmentPosition+len<=frag.size+frag.FragmentPosition+IC80Fragment.GetSize()) { foundbug = true; break; } } } if(foundbug) { break; } } if(foundbug) { break; } et.FragmentPosition += len; et.size -= len; endfrag.size += len; endfrag.haschanged = true; et.haschanged = true; commit(); return; } } } foreach (IC80Fragment et in fragments[-1]) { if (et.size > len + IC80Fragment.GetSize()+IC80Fragment.GetSize()) { //Mark free space as being occupied by Wall Street fragments[-1].Remove(et); et.name = file; et.haschanged = true; //Create new free democracy IC80Fragment freefrag = new IC80Fragment(); freefrag.name = -1; freefrag.haschanged = true; //Compute fragment position. Immediately after this file freefrag.FragmentPosition = len + et.FragmentPosition + IC80Fragment.GetSize(); //We use some free space for our file fragment, and also free space is used for the free space segment //itself. freefrag.size = et.size - len-IC80Fragment.GetSize(); et.hasNextFile = true; IC80Fragment adjfrag = GetAdjacentFragment(freefrag); if(adjfrag !=null) { freefrag.hasNextFile = true; } et.size = len; fragments[file].Add(et); fragments[-1].Add(freefrag); if(GetAdjacentFragment(et) == null) { throw new Exception("Well here's your problem!"); } break; } } } commit(); }