如何根据年龄删除Perl哈希或数组项?

时间:2009-11-18 11:08:06

标签: perl algorithm

如何删除我不感兴趣的数组项?如果我要离开他们 - 我的记忆会被不必要的物品所淹没。

我需要在Perl中实现一项任务。一个文件不断填充包含以下内容的消息:

 "IP - URL"

我需要不断阅读此文件,并测量是否有超过五个相同IP - URL对,例如五秒间隔。

如果我每五秒从最后一个位置读取文件并计算重复数据,那么我可以遇到五秒钟内有八个相同线对的情况,但在第一次读取时有四个,另外四个在第二次读取期间五秒钟后因此,我需要检查最后五个重复行之间的间隔。

我能做什么:

$pairs[$ip_url_line] = ['time-stamp',....,'time-stamp-N']

然后获取此哈希键的最后五个数组项并计算时移。如果它超过五秒 - 做一些事情。

当然,我可以遍历循环中的所有哈希元素和所有数组项,并检查它是否超过5秒,但它的资源太贵了。

3 个答案:

答案 0 :(得分:5)

  1. 按顺序存储每个IP地址的时间戳。无论如何你可能会这样做。
  2. 每当您获得日志行并添加新条目时,请在检查有多少条目之前删除那里的所有陈旧条目。您可以使用grep轻松完成。
  3. 定期(每分钟一次?)从哈希中删除超过5分钟前​​最后(最新)时间戳的所有IP地址,因为这意味着所有条目超过5分钟一段时间没有看到旧的和那个地址。
  4. 这很简单,很容易证明是正确的,它试图避免一次做太多的工作,并且它会使你的桌子变得不合理地大。步骤3的间隔为1分钟,没有条目可能超过11分钟。 (如果在00:00:00添加了1.2.3.4的第一个条目,则可以添加最新的条目而不会将第一个条目添加为00:04:59。最新的步骤3扫描可以在不删除的情况下运行然后整个数组将是00:09:58;假设最坏的情况,下一次扫描将在00:10:58。)如果你可以在内存中保留11分钟的数据,那你就是金色的。

答案 1 :(得分:4)

#!/usr/bin/perl

use strict; use warnings;

my @ts;

for (1 .. 10) {
    push @ts, time;
    sleep rand 3;
}

my $now = time;
@ts = grep { $now - $_ <= 5 } @ts;

print $_, "\n" for @ts;

答案 2 :(得分:1)

这听起来像你想要某种最近最少使用(LRU)的缓存。虽然我不经常推荐它,但我认为这是绑定哈希或数组的工作。您STORE新元素,当您这样做时,您将清除旧元素。这使得较高元素的复杂性并将其隐藏在正常数组或散列访问之后。请查看Tie::Cache以获取示例。

或者,您可以保留某种FIFO,从阵列的一端添加新元素,然后检查另一端是否删除项目。