在ASP.NET MVC 3中存储,加载和更新Trie

时间:2011-06-01 22:56:22

标签: asp.net-mvc-3 architecture concurrency trie

我有一个基于特里的单词检测算法,用于自定义词典。请注意,正则表达式对于此字典来说太脆弱,因为条目可能包含空格,句点等。

我在本地C#应用程序中实现了该算法,该应用程序从文件中读取字典并将trie存储在内存中(它是紧凑的,所以根本没有RAM大小问题)。现在我想在像AppHarbor这样的云主机上的MVC 3应用程序中使用这个算法,我想要一个Web界面来添加/编辑单词。

每次用户上传文本时,从文件加载字典并构建trie的速度都不够快(在我的笔记本电脑上<1s)。但是,如果我想让管理员通过Web界面编辑字典,那么这似乎很棘手,因为当用户尝试上传文本进行分析时,字典可能会更新。

在MVC 3应用程序中存储,加载和更新trie的最佳策略是什么?

4 个答案:

答案 0 :(得分:1)

我不确定您是否正在寻找具体的实施细节,或者更多关于如何处理的概念性想法,但我现在会抛出一些想法。

实际特里课程 - 这是一个很好的C# example of classes for setting up a Trie。听起来你已经知道了这部分。

存储:我会将trie数据保存到XML,除非您已经在使用数据库并且需要将它放在dbms中。 XML在MVC应用程序中很容易使用,您无需担心数据库连接问题或数据库的额外成本。我在服务器上还有两个版本的trie数据,一个生产副本和一个生产支持副本,第二个是你的管理员可以执行交易的。

正在加载在应用程序的管理模块中,您可以实现将trie数据加载到内存中的功能,数据加载的频率取决于您的应用程序需求。它可以安排或作为手动功能使用。与wordpress网站一样,如果用户在更新时应访问它,则会收到该网站正在进行维护的消息。您可以选择仅按需加载到内存中,并始终保持trie加载,除非出现问题。

正在更新 - 我有第二个用于应用更新的数据库(或XML文件)。将更新应用于生产的方法部分取决于更新的频率,数量和时间。一种安全的方法可能是存储管理员输入的交易。 例如:

  • trie.put(“John”,112);
  • trie.put(“Doe”,222);
  • trie.Remove( “约翰”);

然后根据需要通过管理功能将这些事务应用于您的生产数据。如果需要,请将您的网站置于“maint”模式。如果更新很少且速度很快,您可以对站点进行编码,以便在处理事务之前保持所有工作,用户可能需要等待几毫秒才能得到结果,但您不必担心变异数据问题。

这很模糊,但只是抛出一些想法......如果你提出意见我会尝试提供更多。

答案 1 :(得分:1)

1将trie存储在缓存中: 它不是动态数据,缓存可以帮助我们完成其他任务(例如管理员和用户对trie的并发访问)

2访问缓存清除:

public class TrieHelper
{
public Trie MyTrie
{
    get
    {
        if (HttpContext.Current.Cache["myTrieKey"] == null)
            HttpContext.Current.Cache["myTrieKey"] = LoadTrieFromFile(); //Returns Trie object
        return (Trie)HttpContext.Current.Cache["myTrieKey"];
    }
}

3在添加正在进行的操作时锁定对象

public void AddWordToTrie(string word)
{
    var trie = MyTrie;
    lock (HttpContext.Current.Cache["myTrieKey"])
    {
    trie.AddWord(word);
    } // notify that trie object locking when write data to file is not reuired
    WriteNewWordToTrieFile(word); // should lock FileWriter object
    }
}

4如果一次由1个管理员执行编辑 - 在xml文件中存储trie - 将很容易实现搜索元素的逻辑,在你应该添加单词之后(你可以创建函数,将使用MyTrie对象在内存中),并使用linq将其添加到xml。

答案 2 :(得分:0)

我有一种相同但却大10倍的东西:)

客户设计自己的日历,问题和可能的答案,同时一些是在线的,并由普通用户使用。

我提出的是测试部署。管理员输入日历值并正确设置,然后他可以使用预览按钮查看是否需要/想要,然后,为了使更改对所有最终用户有效,他需要推动部署

作为ADMIN,他会知道,在推送DEPLOY按钮之前,访问日历的所有用户都将具有旧值。很快他点击部署全部在数据库中设置,并将他上传的文件推送到Amazon S3(以便更快地访问)。

我使用新日历更新缓存,并缓存新的Calendar对象,直到App池另有说明或再次点击Deploy按钮。

你可以这样做。

答案 3 :(得分:0)

当您要在云环境中执行应用程序时,我建议您查看CQRS和持久消息传递并提供一些并发模型(可能是乐观并发和智能冲突检测http://skillsmatter.com/podcast/design-architecture/cqrs-not-just-for-server-systems 5 :00)

另外,显然,您需要更准确地分析您的业务需求,因为,Udi Dahan mentioned,竞争条件是缺乏业务分析的结果。