public CachePage(int size, long pageNum) { Buffer = new byte[size]; Dirty = false; NextPage = null; PageNumber = pageNum; }
public CachePage(int size, long pageNum) { this.Buffer = new byte[size]; this.Dirty = false; this.NextPage = null; this.PageNumber = pageNum; }
public override int ReadByte() { CachePage page = GetPage(m_position); int num = CalcOffsetWithinPage(m_position); UpdatePosition(1L); return(page.Buffer[num]); }
private void FlushPage(CachePage page, long pageNum) { if (page.Dirty) { long offset = CalcPageOffset(pageNum); m_stream.Seek(offset, SeekOrigin.Begin); page.Write(m_stream); } }
public override void WriteByte(byte value) { CachePage page = GetPage(m_position); int num = CalcOffsetWithinPage(m_position); UpdatePosition(1L); page.Buffer[num] = value; page.Dirty = true; }
private void ActivateBlock(int bi) { if (cache[bi] == null) { byte[] arr = new byte[_block_length]; fs.Position = bi * BlockSize; fs.Read(arr, 0, arr.Length); cache[bi] = new CachePage() { array = arr }; } }
public override void Write(byte[] buffer, int offset, int count) { long num = m_position + count; while (m_position < num) { CachePage page = GetPage(m_position); int num2 = CalcOffsetWithinPage(m_position); byte[] buffer2 = page.Buffer; int num3 = Math.Min(buffer2.Length - num2, count); Array.Copy(buffer, offset, buffer2, num2, num3); UpdatePosition(num3); count -= num3; offset += num3; page.Dirty = true; } }
private CachePage GetPage(long fileOffset) { long num = CalcPageNum(fileOffset); CachePage value = null; if (!m_pageCache.TryGetValue(num, out value)) { bool flag = false; if (m_pageCache.Count == m_pageCacheCapacity || (m_freezePageAllocations && m_pageCache.Count > 0)) { value = m_firstPageToEvict; long pageNumber = value.PageNumber; m_firstPageToEvict = value.NextPage; m_pageCache.Remove(pageNumber); FlushPage(value, pageNumber); value.PageNumber = num; } else { value = new CachePage(m_bytesPerPage, num); flag = true; } long num2 = CalcPageOffset(num); if (num2 < m_length) { m_stream.Seek(num2, SeekOrigin.Begin); value.Read(m_stream); } else if (!flag) { value.InitBuffer(); } m_pageCache[num] = value; if (m_firstPageToEvict == null) { m_firstPageToEvict = value; } if (m_lastPageToEvict != null) { m_lastPageToEvict.NextPage = value; } m_lastPageToEvict = value; } return(value); }
private CachePage GetPage(long fileOffset) { long num = this.CalcPageNum(fileOffset); CachePage cachePage = null; if (!this.m_pageCache.TryGetValue(num, out cachePage)) { bool flag = false; if (this.m_pageCache.Count == this.m_pageCacheCapacity || (this.m_freezePageAllocations && this.m_pageCache.Count > 0)) { cachePage = this.m_firstPageToEvict; long pageNumber = cachePage.PageNumber; this.m_firstPageToEvict = cachePage.NextPage; this.m_pageCache.Remove(pageNumber); this.FlushPage(cachePage, pageNumber); cachePage.PageNumber = num; } else { cachePage = new CachePage(this.m_bytesPerPage, num); flag = true; } long num2 = this.CalcPageOffset(num); if (num2 < this.m_length) { this.m_stream.Seek(num2, SeekOrigin.Begin); cachePage.Read(this.m_stream); } else if (!flag) { cachePage.InitBuffer(); } this.m_pageCache[num] = cachePage; if (this.m_firstPageToEvict == null) { this.m_firstPageToEvict = cachePage; } if (this.m_lastPageToEvict != null) { this.m_lastPageToEvict.NextPage = cachePage; } this.m_lastPageToEvict = cachePage; } return(cachePage); }
public override int Read(byte[] buffer, int offset, int count) { int result = count; long num = m_position + count; while (m_position < num) { CachePage page = GetPage(m_position); int num2 = CalcOffsetWithinPage(m_position); byte[] buffer2 = page.Buffer; int num3 = Math.Min(buffer2.Length - num2, count); Array.Copy(buffer2, num2, buffer, offset, num3); UpdatePosition(num3); count -= num3; offset += num3; } return(result); }
public void LoadCache() { if (cache == null) { ActivateCache(); } byte[] buffer = new byte[BlockSize]; int bi = 0; fs.Position = 0L; for (long coord = 0L; coord < fs.Length; coord += BlockSize) { fs.Read(buffer, 0, (int)BlockSize); cache[bi] = new CachePage() { array = new byte[BlockSize] }; Array.Copy(buffer, 0, cache[bi].array, 0, (int)BlockSize); bi++; } }
public void BigFlush() { if (false && cache != null) { int cnt = 0; for (int pi = 0; pi < cache.Count; pi++) { CachePage cp = cache[pi]; if (cp == null || !cp.changed) { continue; } fs.Position = (long)pi * BlockSize; fs.Write(cp.array, 0, (int)BlockSize); cp.changed = false; cnt++; } Console.WriteLine("Flush cnt = {0}", cnt); } this.Flush(); }
private async Task Cache(HttpContext context) { //bool useMinification = _options.EnableMinification && _minificationManagers.Count > 0; //bool useCompression = _options.EnableCompression && _compressionManager != null; var useMinification = _options.EnableMinification; var useCompression = _options.EnableCompression; var cacheSetting = _options.Setting; var currentUrl = context.Request.Path.Value; var accept = $"{context.Request.Headers["Accept"]}"; var isHtml = context.Request.Method == "GET" && !string.IsNullOrEmpty(accept) && accept.Contains("text/html") && context.Request.Headers["X-Requested-With"] != "XMLHttpRequest"; #region 做缓存处理 if (!isHtml || (!useMinification && !useCompression) || !_options.EnableCache || !cacheSetting.IgnorePages.Contains(currentUrl)) { await _next.Invoke(context); return; } #endregion var cachePage = cacheSetting.CachePages.FirstOrDefault(a => a.Url == currentUrl); if (cachePage == null) { cachePage = new CachePage() { Url = currentUrl } } ; if (cachePage.CacheTime == 0) { cachePage.CacheTime = cacheSetting.CacheTime; } var cacheKey = GetKey(context.Request, cachePage.VaryByParams); #region 判断缓存是否存在 var cacheContent = _cacheService.Get <CacheContent>(cacheKey); if (cacheContent != null) { context.Response.Headers.Add("C-Cache", "Hit"); if (cacheContent.Headers != null && cacheContent.Headers.Count > 0) { foreach (var ch in cacheContent.Headers) { context.Response.Headers.Add(ch.Key, ch.Value); } } await context.Response.Body.WriteAsync(cacheContent.Content, 0, cacheContent.Content.Length); return; } #endregion HttpRequest request = context.Request; HttpResponse response = context.Response; using (var cachedStream = new MemoryStream()) { Stream originalStream = response.Body; response.Body = cachedStream; try { await _next.Invoke(context); } catch (Exception) { response.Body = originalStream; cachedStream.Clear(); throw; } byte[] cachedBytes = cachedStream.ToArray(); int cachedByteCount = cachedBytes.Length; bool isProcessed = false; response.Body = originalStream; cachedStream.Clear(); if (cachedByteCount == 0) { return; } if (response.StatusCode == 200) { string httpMethod = request.Method; string contentType = response.ContentType; string mediaType = null; Encoding encoding = null; if (contentType != null) { MediaTypeHeaderValue mediaTypeHeader; if (MediaTypeHeaderValue.TryParse(contentType, out mediaTypeHeader)) { mediaType = mediaTypeHeader.MediaType.Value; encoding = mediaTypeHeader.Encoding; } } encoding = encoding ?? Encoding.GetEncoding(0); string content = encoding.GetString(cachedBytes); string processedContent = content; IHeaderDictionary responseHeaders = response.Headers; bool isEncodedContent = responseHeaders.IsEncodedContent(); Action <string, string> appendHttpHeader = (key, value) => { responseHeaders.Append(key, new StringValues(value)); }; #region Html压缩 if (useMinification && _options.IsAllowableResponseSize(cachedByteCount)) { var htmlMinifier = new HtmlMinifier(); var result = htmlMinifier.Minify(processedContent); if (result.Errors.Count == 0) { processedContent = result.MinifiedContent; isProcessed = true; } //foreach (IMarkupMinificationManager minificationManager in _minificationManagers) //{ // if (minificationManager.IsSupportedHttpMethod(httpMethod) // && mediaType != null && minificationManager.IsSupportedMediaType(mediaType) // && minificationManager.IsProcessablePage(currentUrl)) // { // if (isEncodedContent) // { // throw new InvalidOperationException( // string.Format( // AspNetCommonStrings.MarkupMinificationIsNotApplicableToEncodedContent, // responseHeaders["Content-Encoding"] // ) // ); // } // IMarkupMinifier minifier = minificationManager.CreateMinifier(); // MarkupMinificationResult minificationResult = minifier.Minify(processedContent, // currentUrl, encoding, minificationManager.GenerateStatistics); // if (minificationResult.Errors.Count == 0) // { // processedContent = minificationResult.MinifiedContent; // isProcessed = true; // } // } // if (isProcessed) // { // break; // } //} } #endregion byte[] processedBytes; if (isProcessed) { processedBytes = encoding.GetBytes(processedContent); } else { processedBytes = cachedBytes; } #region GZip压缩 if (useCompression && !isEncodedContent) { string acceptEncoding = request.Headers["Accept-Encoding"]; string[] encodingTokens = acceptEncoding .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(e => e.Trim().ToLowerInvariant()) .ToArray(); ICompressor compressor = null; foreach (var et in encodingTokens) { if (et == EncodingTokenConstants.Deflate) { compressor = new DeflateCompressor(new DeflateCompressionSettings() { Level = System.IO.Compression.CompressionLevel.Fastest }); break; } else if (et == EncodingTokenConstants.GZip) { compressor = new GZipCompressor(new GZipCompressionSettings() { Level = System.IO.Compression.CompressionLevel.Fastest }); } } if (compressor != null) { using (var inputStream = new MemoryStream(processedBytes)) using (var outputStream = new MemoryStream()) { using (Stream compressedStream = compressor.Compress(outputStream)) { await inputStream.CopyToAsync(compressedStream); } byte[] compressedBytes = outputStream.ToArray(); processedBytes = compressedBytes; outputStream.Clear(); inputStream.Clear(); responseHeaders["Content-Length"] = compressedBytes.Length.ToString(); compressor.AppendHttpHeaders(appendHttpHeader); await originalStream.WriteAsync(compressedBytes, 0, compressedBytes.Length); } } //using (var inputStream = new MemoryStream(processedBytes)) //using (var outputStream = new MemoryStream()) //{ // string acceptEncoding = request.Headers["Accept-Encoding"]; // ICompressor compressor = _compressionManager.CreateCompressor(acceptEncoding); // using (Stream compressedStream = compressor.Compress(outputStream)) // { // await inputStream.CopyToAsync(compressedStream); // } // byte[] compressedBytes = outputStream.ToArray(); // processedBytes = compressedBytes; // int compressedByteCount = compressedBytes.Length; // outputStream.Clear(); // inputStream.Clear(); // responseHeaders["Content-Length"] = compressedByteCount.ToString(); // compressor.AppendHttpHeaders(appendHttpHeader); // await originalStream.WriteAsync(compressedBytes, 0, compressedByteCount); //} isProcessed = true; } #endregion else { if (isProcessed) { int processedByteCount = processedBytes.Length; responseHeaders["Content-Length"] = processedByteCount.ToString(); await originalStream.WriteAsync(processedBytes, 0, processedByteCount); } } #region 保存到缓存中 cacheContent = new CacheContent() { Content = processedBytes, ContentType = contentType, Headers = new Dictionary <string, string>() }; foreach (var rh in responseHeaders) { cacheContent.Headers.Add(rh.Key, rh.Value); } await _cacheService.SetAsync(cacheKey, cacheContent, TimeSpan.FromSeconds(cachePage.CacheTime)); context.Response.Headers.Add("C-Cache", "Cached"); //Task.Factory.StartNew(obj => //{ // var cc = (CacheContent)obj; //}, cacheContent); #endregion } if (!isProcessed) { await originalStream.WriteAsync(cachedBytes, 0, cachedByteCount); } } }