Olay tarihine göre tarih aralığını aramak için Algoritma

3 Cevap php

Ben var datestamp dayalı uygulama gitmeli hangi DB shard aramak için türlü bir tablo kullanmak bir PHP işlevi yazıyorum.

Shard yapılandırma gibi bir şey bu (pseudo-code): İlk sütun ben arıyorum olayın tarih ve 2 olay in bulunduğu shard olduğunu

pre-2008 -> shard1
2008-2009 -> shard2
2009_01-2009_06 -> shard3
2009_07 -> shard4
2009_08 -> shard5
2009_09 and up -> shard6

Gördüğünüz gibi, ben istiyorum yapılandırması oldukça esnek - bu, herhangi bir tarih aralığı almak ancak küçük ya da büyük bir kırıkta eşleyebilir.

Ben belirli bir tarihte dayalı bir arama yapmak için hızlı bir yol arıyorum.

Benim tarih 2009-05-02 Örneğin, Sonra ben shard shard3 olduğunu. Tarih 2007-08-01 ise, o zaman shard1 bulunuyor.

Uygulama PHP olduğu gibi gerçek PHP kodu için bonus puan.

Teşekkür ederim.

3 Cevap

I am guessing that you don't want to have holes in date ranges, so I propose that you just need to specify an end date for each shard, and explicitly name one Default Shard which holds everything that is too new to fit into one of the other shards.

// configure shards
$SHARDS = array(
        // <end date>   => <shard number>
        '2007-12-31'    => 'shard1', // shard1 - up to end of 2007
        '2008-12-31'    => 'shard2', // shard2 - up to end of 2008
        '2009-06-30'    => 'shard3', // shard3 - up to end of June 09
        '2009-07-31'    => 'shard4', // shard4 - up to end of July 2009
        '2009-08-31'    => 'shard5', // shard4 - up to end of August 2009
        'DEFAULT'       => 'shard6', // everything else in shard 6
        );

Bu tarihler sağ olsun kolaylaştırır, ve tarihe dayalı bir Shard bulmak için kod basittir:

function findShardByDate($date) {
    static $default = false;
    static $sorted = false;
    if($sorted === false) {
        // copy of global $SHARDS
        $SHARDS = $GLOBALS['SHARDS'];
        $default = $SHARDS['DEFAULT'];
        unset($SHARDS['DEFAULT']);
        // make sure $SHARDS is sorted
        ksort($SHARDS);
        $sorted = $SHARDS;
        unset($SHARDS);
    }
    // find the first shard which would contain that date
    foreach($sorted as $endDate => $shardName)
        if($endDate >= $date)
            return $shardName;
    // no shard found - use the default shard
    return $default;
}

Bu sıralama yalnızca bir kez yapılır böylece Edit: statik değişkenler kullanılır.

<?php

function get_shard($datetime)
{
    $timestamp = strtotime($datetime);

    $shards = array(array('start' => null, 'end' => '2007-12-31'),
                    array('start' => '2008-01-01', 'end' => '2008-12-31'),
                    array('start' => '2009-01-01', 'end' => '2009-06-30'),
                    array('start' => '2009-07-01', 'end' => '2009-07-31'),
                    array('start' => '2009-08-01', 'end' => '2009-08-31'),
                    array('start' => '2009-09-01', 'end' => null),
                    );
    foreach ($shards as $key => $range) {
        $start = strtotime($range['start']);
        $end = strtotime($range['end']);
        if ($timestamp >= $start && $timestamp <= $end) {
            return $key + 1;
        }
        if ($timestamp >= $start && $end === false) {
            return $key + 1;
        }
    }
}


$datetime = '2007-08-01';
echo 'shard' . get_shard($datetime) . "\n";

$datetime = '2009-05-02';
echo 'shard' . get_shard($datetime) . "\n";

$datetime = '2010-01-01';
echo 'shard' . get_shard($datetime) . "\n";

?>

Çıkışlar:

shard1
shard3
shard6

Lütfen kırıkları kesinlikle sipariş edilebilir olduğundan, bir ikili ağacın saklayarak ve sonra sadece o ağaç ile bir ikili arama koşma gibi size hızlı sonuç verecek gibi görünüyor.