internal void WriteByteTo(IJournalledResource data, long position, int b) { if (PARANOID_CHECKS) { lock (write_lock) { if (write_lock_count == 0) { Console.Out.WriteLine("Write without a Lock!"); Console.Out.WriteLine(new ApplicationException().StackTrace); } } } long page_number = position / page_size; BMPage page = FetchPage(data, page_number); lock (page) { try { page.Initialize(); page.Write((int)(position % page_size), (byte)b); } finally { page.Dispose(); } } }
/// <summary> ///Constructs the page. /// </summary> /// <param name="data"></param> /// <param name="page"></param> /// <param name="page_size"></param> internal BMPage(IJournalledResource data, long page, int page_size) { this.data = data; this.data_id = data.Id; this.page = page; this.reference_count = 0; this.page_size = page_size; Reset(); }
public JournalledFileStore(String resource_name, LoggingBufferManager buffer_manager, bool read_only) : base(read_only) { this.resource_name = resource_name; this.buffer_manager = buffer_manager; // Create the store resource object for this resource name this.store_resource = buffer_manager.CreateResource(resource_name); }
internal void WriteByteArrayTo(IJournalledResource data, long position, byte[] buf, int off, int len) { if (PARANOID_CHECKS) { lock (write_lock) { if (write_lock_count == 0) { Console.Out.WriteLine("Write without a Lock!"); Console.Out.WriteLine(new ApplicationException().StackTrace); } } } long page_number = position / page_size; int start_offset = (int)(position % page_size); int to_write = System.Math.Min(len, page_size - start_offset); BMPage page = FetchPage(data, page_number); lock (page) { try { page.Initialize(); page.Write(start_offset, buf, off, to_write); } finally { page.Dispose(); } } len -= to_write; while (len > 0) { off += to_write; position += to_write; ++page_number; to_write = System.Math.Min(len, page_size); page = FetchPage(data, page_number); lock (page) { try { page.Initialize(); page.Write(0, buf, off, to_write); } finally { page.Dispose(); } } len -= to_write; } }
// ------ // Buffered access methods. These are all thread safe methods. When a page // is accessed the page is synchronized so no 2 or more operations can // Read/Write from the page at the same time. An operation can Read/Write to // different pages at the same time, however, and this requires thread safety // at a lower level (in the IJournalledResource implementation). // ------ internal int ReadByteFrom(IJournalledResource data, long position) { long page_number = position / page_size; int v; BMPage page = FetchPage(data, page_number); lock (page) { try { page.Initialize(); v = ((int)page.Read((int)(position % page_size))) & 0x0FF; } finally { page.Dispose(); } } return(v); }
internal int ReadByteArrayFrom(IJournalledResource data, long position, byte[] buf, int off, int len) { int orig_len = len; long page_number = position / page_size; int start_offset = (int)(position % page_size); int to_read = System.Math.Min(len, page_size - start_offset); BMPage page = FetchPage(data, page_number); lock (page) { try { page.Initialize(); page.Read(start_offset, buf, off, to_read); } finally { page.Dispose(); } } len -= to_read; while (len > 0) { off += to_read; position += to_read; ++page_number; to_read = System.Math.Min(len, page_size); page = FetchPage(data, page_number); lock (page) { try { page.Initialize(); page.Read(0, buf, off, to_read); } finally { page.Dispose(); } } len -= to_read; } return(orig_len); }
internal long GetDataAreaSize(IJournalledResource data) { return(data.Size); }
internal void SetDataAreaSize(IJournalledResource data, long new_size) { data.SetSize(new_size); }
internal int ReadByteArrayFrom(IJournalledResource data, long position, byte[] buf, int off, int len) { int orig_len = len; long page_number = position / page_size; int start_offset = (int)(position % page_size); int to_read = System.Math.Min(len, page_size - start_offset); BMPage page = FetchPage(data, page_number); lock (page) { try { page.Initialize(); page.Read(start_offset, buf, off, to_read); } finally { page.Dispose(); } } len -= to_read; while (len > 0) { off += to_read; position += to_read; ++page_number; to_read = System.Math.Min(len, page_size); page = FetchPage(data, page_number); lock (page) { try { page.Initialize(); page.Read(0, buf, off, to_read); } finally { page.Dispose(); } } len -= to_read; } return orig_len; }
/// <summary> /// Fetches and returns a page from a store. /// </summary> /// <param name="data"></param> /// <param name="page_number"></param> /// <remarks> /// Pages may be cached. If the page is not available in the cache then a new /// <see cref="BMPage"/> object is created for the page requested. /// </remarks> /// <returns></returns> private BMPage FetchPage(IJournalledResource data, long page_number) { long id = data.Id; BMPage prev_page = null; bool new_page = false; BMPage page; lock (page_map) { // Generate the hash code for this page. int p = (CalcHashCode(id, page_number) & 0x07FFFFFFF) % page_map.Length; // Search for this page in the hash page = page_map[p]; while (page != null && !page.IsPage(id, page_number)) { prev_page = page; page = page.hash_next; } // Page isn't found so create it and add to the cache if (page == null) { page = new BMPage(data, page_number, page_size); // Add this page to the map page.hash_next = page_map[p]; page_map[p] = page; } else { // Move this page to the head if it's not already at the head. if (prev_page != null) { prev_page.hash_next = page.hash_next; page.hash_next = page_map[p]; page_map[p] = page; } } lock (page) { // If page not in use then it must be newly setup, so add a // reference. if (page.NotInUse) { page.Reset(); new_page = true; page.ReferenceAdd(); } // Add a reference for this fetch page.ReferenceAdd(); } // If the page is new, if (new_page) { PageCreated(page); } else { PageAccessed(page); } } // Return the page. return(page); }
internal long GetDataAreaSize(IJournalledResource data) { return data.Size; }
/// <summary> /// Fetches and returns a page from a store. /// </summary> /// <param name="data"></param> /// <param name="page_number"></param> /// <remarks> /// Pages may be cached. If the page is not available in the cache then a new /// <see cref="BMPage"/> object is created for the page requested. /// </remarks> /// <returns></returns> private BMPage FetchPage(IJournalledResource data, long page_number) { long id = data.Id; BMPage prev_page = null; bool new_page = false; BMPage page; lock (page_map) { // Generate the hash code for this page. int p = (CalcHashCode(id, page_number) & 0x07FFFFFFF) % page_map.Length; // Search for this page in the hash page = page_map[p]; while (page != null && !page.IsPage(id, page_number)) { prev_page = page; page = page.hash_next; } // Page isn't found so create it and add to the cache if (page == null) { page = new BMPage(data, page_number, page_size); // Add this page to the map page.hash_next = page_map[p]; page_map[p] = page; } else { // Move this page to the head if it's not already at the head. if (prev_page != null) { prev_page.hash_next = page.hash_next; page.hash_next = page_map[p]; page_map[p] = page; } } lock (page) { // If page not in use then it must be newly setup, so add a // reference. if (page.NotInUse) { page.Reset(); new_page = true; page.ReferenceAdd(); } // Add a reference for this fetch page.ReferenceAdd(); } // If the page is new, if (new_page) { PageCreated(page); } else { PageAccessed(page); } } // Return the page. return page; }
// ------ // Buffered access methods. These are all thread safe methods. When a page // is accessed the page is synchronized so no 2 or more operations can // Read/Write from the page at the same time. An operation can Read/Write to // different pages at the same time, however, and this requires thread safety // at a lower level (in the IJournalledResource implementation). // ------ internal int ReadByteFrom(IJournalledResource data, long position) { long page_number = position / page_size; int v; BMPage page = FetchPage(data, page_number); lock (page) { try { page.Initialize(); v = ((int)page.Read((int)(position % page_size))) & 0x0FF; } finally { page.Dispose(); } } return v; }