Ejemplo n.º 1
0
    public static BPlusTree <int, ContentNodeKit> GetTree(string filepath, bool exists, NuCacheSettings settings, ContentDataSerializer?contentDataSerializer = null)
    {
        var keySerializer   = new PrimitiveSerializer();
        var valueSerializer = new ContentNodeKitSerializer(contentDataSerializer);
        var options         = new BPlusTree <int, ContentNodeKit> .OptionsV2(keySerializer, valueSerializer)
        {
            CreateFile = exists ? CreatePolicy.IfNeeded : CreatePolicy.Always,
            FileName   = filepath,

            // read or write but do *not* keep in memory
            CachePolicy = CachePolicy.None,

            // default is 4096, min 2^9 = 512, max 2^16 = 64K
            FileBlockSize = GetBlockSize(settings),

            // HACK: Forces FileOptions to be WriteThrough here: https://github.com/mamift/CSharpTest.Net.Collections/blob/9f93733b3af7ee0e2de353e822ff54d908209b0b/src/CSharpTest.Net.Collections/IO/TransactedCompoundFile.cs#L316-L327,
            // as the reflection uses otherwise will failed in .NET Core as the "_handle" field in FileStream is renamed to "_fileHandle".
            StoragePerformance = StoragePerformance.CommitToDisk,

            // other options?
        };

        var tree = new BPlusTree <int, ContentNodeKit>(options);

        // anything?
        // btree.
        return(tree);
    }
        /// <summary>
        /// Construct a new <see cref="UmbracoXmlParser"/> instance by parsing the supplied
        /// umbraco.config XML cache file or NuCache database file.
        /// </summary>
        /// <param name="umbracoConfigOrNuCacheDb">Full path to umbraco.config XML cache file or NuCache database file.</param>
        /// <param name="options">Options to provide mappings for URL prefixes, doctypes (Umbraco 8 only) and users (Umbraco 8 only).</param>
        public UmbracoXmlParser(string umbracoConfigOrNuCacheDb, UmbracoParsingOptions options)
        {
            // Save options
            if (options != null)
            {
                Options = options;
            }

            // Remove any trailing slashes from URL prefixes as we don't want them
            if (Options.UrlPrefixMapping != null)
            {
                foreach (var key in Options.UrlPrefixMapping.Keys.ToList())
                {
                    if (Options.UrlPrefixMapping[key].EndsWith("/"))
                    {
                        Options.UrlPrefixMapping[key] = Options.UrlPrefixMapping[key].TrimEnd('/');
                    }
                }
            }

            // No file?
            if (string.IsNullOrEmpty(umbracoConfigOrNuCacheDb))
            {
                throw new ArgumentException(umbracoConfigOrNuCacheDb);
            }

            // Check first few bytes. If it's XML it will start with '<' (potentially after a BOM)
            byte[] buffer = new byte[10];
            using (var stream = new FileStream(umbracoConfigOrNuCacheDb, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                stream.Read(buffer, 0, 10);
            }

            // It's an umbraco 4 through 7 XML cache file
            if (buffer[0] == '<' ||
                buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf && buffer[3] == '<') // UTF-8 BOM
            {
                try
                {
                    // Load XML into an XDocument
                    ParsedXml = XDocument.Load(umbracoConfigOrNuCacheDb);

                    // Parse content into an in-memory dictionary of node ID and node information
                    ParseXmlIntoUmbracoNodes();

                    // Destroy
                    ParsedXml = null;
                    return;
                }
                catch (UmbracoXmlParsingException ex)
                {
                    ParsedXml = null;
                    throw new UmbracoXmlParsingException($"Could not parse {umbracoConfigOrNuCacheDb} as XML - {ex.Message}");
                }
                catch
                {
                    ParsedXml = null;
                    // Might be a NuCache file
                }
            }

            // Umbraco 8.0.1 or later NuCache db file
            try
            {
                var keySerializer    = new PrimitiveSerializer();
                var valueSerializer  = new ContentNodeKitSerializer();
                var bPlusTreeOptions = new BPlusTree <int, ContentNodeKit> .OptionsV2(keySerializer, valueSerializer)
                {
                    CreateFile = CreatePolicy.Never,
                    FileName   = umbracoConfigOrNuCacheDb,
                    ReadOnly   = true
                };

                // Read the file into a BPlusTreeObject
                ParsedTree = new BPlusTree <int, ContentNodeKit>(bPlusTreeOptions);
            }
            catch (Exception ex)
            {
                throw new UmbracoXmlParsingException($"Could not parse {umbracoConfigOrNuCacheDb} as a NuCache DB - {ex.Message}");
            }

            // Parse content into an in-memory dictionary of node ID and node information
            ParseTreeIntoUmbracoNodes();

            // Destroy
            ParsedTree.Dispose();
            ParsedTree = null;
        }
Ejemplo n.º 3
0
        public HttpResponseMessage GetNuCacheFile(string contentType)
        {
            var filePath     = Path.Combine(globalSettings.LocalTempPath, "NuCache\\NuCache." + contentType + ".db");
            var tempFileName = filePath.Replace(".db", ".Explorer.Temp.db");

            try
            {
                //Check for valid filepath
                if (File.Exists(filePath) == false)
                {
                    var message = $"No file exists on disk at {filePath}";
                    return(Request.CreateErrorResponse(HttpStatusCode.NotFound, message));
                }

                //Check for file extension ends with .db
                //Don't want to attempt to any old file type
                if (Path.GetExtension(filePath) != ".db")
                {
                    var message = $"The file {filePath} is not a .db file";
                    return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, message));
                }

                //We need to create a temp copy of the nucache DB - to avoid file locks if its in use whilst we try to read it
                //'NuCache.Content.db' will become 'NuCache.Content.Explorer.Temp.db'
                File.Copy(filePath, tempFileName, true);

                var keySerializer   = new PrimitiveSerializer();
                var valueSerializer = new ContentNodeKitSerializer();
                var options         = new BPlusTree <int, ContentNodeKit> .OptionsV2(keySerializer, valueSerializer)
                {
                    CreateFile = CreatePolicy.Never,
                    FileName   = tempFileName,

                    // default is 4096, min 2^9 = 512, max 2^16 = 64K
                    FileBlockSize = GetBlockSize(),
                };

                //Read the file into a BPlusTreeObject & select the kits
                var tree = new BPlusTree <int, ContentNodeKit>(options);
                var sw   = Stopwatch.StartNew();
                var kits = tree.Select(x => x.Value).ToArray();
                sw.Stop();
                tree.Dispose();

                DeleteTempFile(tempFileName);

                //Add to our JSON object the stopwatch clock to read the DB/dictionary file
                var response = new ApiResponse
                {
                    Items      = kits,
                    TotalItems = kits.Length,
                    StopClock  = new StopClock
                    {
                        Hours        = sw.Elapsed.Hours,
                        Minutes      = sw.Elapsed.Minutes,
                        Seconds      = sw.Elapsed.Seconds,
                        Milliseconds = sw.Elapsed.Milliseconds,
                        Ticks        = sw.Elapsed.Ticks
                    }
                };

                return(Request.CreateResponse(HttpStatusCode.OK, response));
            }
            catch (Exception e)
            {
                DeleteTempFile(tempFileName);
                return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e.Message));
            }
        }
Ejemplo n.º 4
0
        public HttpResponseMessage GetNuCacheData(string filePath)
        {
            //Check for valid filepath
            if (File.Exists(filePath) == false)
            {
                var message = $"No file exists on disk at {filePath}";
                return(Request.CreateErrorResponse(HttpStatusCode.NotFound, message));
            }

            //Check for file extension ends with .db
            //Don't want to attempt to any old file type
            if (Path.GetExtension(filePath) != ".db")
            {
                var message = $"The file {filePath} is not a .db file";
                return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, message));
            }


            //We need to create a temp copy of the nucache DB - to avoid file locks if its in use whilst we try to read it
            //'NuCache.Content.db' will become 'NuCache.Content.Explorer.Temp.db'
            var tempFileName = filePath.Replace(".db", ".Explorer.Temp.db");

            File.Copy(filePath, tempFileName, true);

            var keySerializer   = new PrimitiveSerializer();
            var valueSerializer = new ContentNodeKitSerializer();
            var options         = new BPlusTree <int, ContentNodeKit> .OptionsV2(keySerializer, valueSerializer)
            {
                CreateFile = CreatePolicy.Never,
                FileName   = tempFileName
            };

            //Read the file into a BPlusTreeObject & select the kits
            var tree = new BPlusTree <int, ContentNodeKit>(options);
            var sw   = Stopwatch.StartNew();
            var kits = tree.Select(x => x.Value).ToArray();

            sw.Stop();
            tree.Dispose();

            //Delete the file (seems like could be a lock, so we wait 100ms between each attempt upto 10 times)
            var ok       = false;
            var attempts = 0;

            while (!ok)
            {
                System.Threading.Thread.Sleep(100);
                try
                {
                    attempts++;
                    File.Delete(tempFileName);
                    ok = true;
                }
                catch
                {
                    if (attempts == 10)
                    {
                        throw;
                    }
                }
            }

            //Add to our JSON object the stopwatch clock to read the DB/dictionary file
            var response = new ApiResponse
            {
                Items      = kits,
                TotalItems = kits.Length,
                StopClock  = new StopClock
                {
                    Hours        = sw.Elapsed.Hours,
                    Minutes      = sw.Elapsed.Minutes,
                    Seconds      = sw.Elapsed.Seconds,
                    Milliseconds = sw.Elapsed.Milliseconds,
                    Ticks        = sw.Elapsed.Ticks
                }
            };

            return(Request.CreateResponse(HttpStatusCode.OK, response));
        }