public IndexTable(IStreamHandler streamCreator, int pageSize, int cacheSize) { if (pageSize % 8 != 0) { Global.Tracer.Assert(false, "Page size must be divisible by value size: {0}", 8); } m_streamCreator = streamCreator; m_stream = null; m_nextTempId = -1L; m_pageSize = pageSize; m_cacheSize = cacheSize; m_pageCache = new Dictionary <int, IndexTablePage>(m_cacheSize); m_queueFirstPage = null; m_queueLastPage = null; m_slotsPerPage = m_pageSize / 8; m_idShift = (int)Math.Log(m_slotsPerPage, 2.0); }
private IndexTablePage QueueExtractFirst() { if (m_queueFirstPage == null) { return(null); } IndexTablePage queueFirstPage = m_queueFirstPage; m_queueFirstPage = queueFirstPage.NextPage; queueFirstPage.NextPage = null; if (m_queueFirstPage == null) { m_queueLastPage = null; } else { m_queueFirstPage.PreviousPage = null; } return(queueFirstPage); }
private IndexTablePage GetPage(long id) { int num = CalcPageNum(id); IndexTablePage value = null; if (!m_pageCache.TryGetValue(num, out value)) { if (m_pageCache.Count == m_cacheSize) { if (m_stream == null) { m_stream = m_streamCreator.OpenStream(); m_streamCreator = null; if (!m_stream.CanSeek || !m_stream.CanRead || !m_stream.CanWrite) { Global.Tracer.Assert(condition: false, "Must be able to Seek, Read, and Write stream"); } } value = QueueExtractFirst(); int pageNumber = value.PageNumber; m_pageCache.Remove(pageNumber); if (value.Dirty) { long offset = CalcPageOffset(pageNumber); m_stream.Seek(offset, SeekOrigin.Begin); value.Write(m_stream); } long offset2 = CalcPageOffset(num); m_stream.Seek(offset2, SeekOrigin.Begin); value.Read(m_stream); } else { value = new IndexTablePage(m_pageSize); } value.PageNumber = num; m_pageCache[num] = value; QueueAppendPage(value); } return(value); }
public long Retrieve(ReferenceID id) { IndexTablePage page = GetPage(id.Value); return(ReadValue(id.Value, page)); }
public void Update(ReferenceID id, long value) { IndexTablePage page = GetPage(id.Value); WriteValue(id.Value, page, value); }