<commit_before><?php

namespace Sokil\FraudDetector\Collector;

class PdoMysqlCollector extends AbstractPdoCollector
{
    private $gcCheckInterval = 1200;

    private $gcSessionInterval = 1200;

    public function setGarbageCollector($checkInterval, $sessionInterval)
    {
        $this->gcCheckInterval = (int) $checkInterval;
        $this->gcSessionInterval = (int) $sessionInterval;
        return $this;
    }

    public function isRateLimitExceed()
    {
        $timeNow = microtime(true);

        $query = 'SELECT 1
            FROM ' . $this->getTableName() . '
            WHERE
                `key` = :key AND
                `expired` >= :timeNow AND
                `requestNum` >= :maxRequestNum';

        $parameters = array(
            ':key' => $this->key,
            ':maxRequestNum' => $this->requestNum,
            ':timeNow' => $timeNow,
        );

        try {
            $stmt = $this->storage->prepare($query);
            $result = @$stmt->execute($parameters);
            if(!$result) {
                throw new \PDOException('Table not exists');
            }
        } catch (\PDOException $e) {
            // if exception occurs, than no table still created
            return false;
        }

        // if record found than key has exceed requests
        if(!$stmt->rowCount()) {
            return false;
        }

        return true;
    }

    private function createTable()
    {
        $this->storage->query('
            CREATE TABLE ' . $this->getTableName() . '(
                `key` varchar(255) PRIMARY KEY NOT NULL,
                `requestNum` int NOT NULL DEFAULT 0,
                `expired` numeric(13, 3)
            ) ENGINE=Memory CHARSET=utf8;
        ');

    }

    public function collect()
    {
        $timeNow = microtime(true);

        // check if record already exists and get current values
        try {
            $query = '
                SELECT requestNum, expired
                FROM ' . $this->getTableName() . '
                WHERE `key` = :key
                FOR UPDATE';

            $stmt = $this->storage->prepare($query);
            $result = @$stmt->execute(array(
                ':key' => $this->key,
            ));

            if(!$result) {
                throw new \PDOException('Table not exists');
            }


        } catch (\PDOException $e) {
            // table yet not created
            $this->createTable();
            $this->collect();
            return;
        }

        $row = $stmt->fetch(\PDO::FETCH_ASSOC);

        if(!$row) {
            // record not exists
            $query = '
                INSERT INTO ' . $this->getTableName() . '(`key`, `requestNum`, `expired`)
                VALUES (:key, 1, :expired)
                ON DUPLICATE KEY UPDATE requestNum = requestNum + 1
            ';

            $stmt = $this->storage->prepare($query);
            $stmt->bindValue(':key', $this->key);
            $stmt->bindValue(':expired', $timeNow + $this->timeInterval);
            $stmt->execute();

            return;

        }

        $expiredTimestamp = (float) $row['expired'];

        if($timeNow <= $expiredTimestamp) {
            // in time slot - increment
            $query = '
                UPDATE ' . $this->getTableName() . '
                SET requestNum = requestNum + 1
                WHERE `key` = :key
            ';
            $parameters = array(
                ':key' => $this->key,
            );
        } else {
            //outside time slot - set new
            $query = '
                UPDATE ' . $this->getTableName() . '
                SET
                    requestNum = 1,
                    expired = :expired
                WHERE `key` = :key
            ';
            $parameters = array(
                ':key' => $this->key,
                ':expired' => $timeNow + $this->timeInterval,
            );
        }

        $stmt = $this->storage->prepare($query);
        $stmt->execute($parameters);


        // garbage collector
        if($timeNow % $this->gcCheckInterval === 0) {
            $query = '
                DELETE FROM ' . $this->getTableName() . '
                WHERE expired < ' . ($timeNow - $this->gcSessionInterval);
        }

    }
}<commit_msg>Update PdoMysqlCollector.php<commit_after><?php

namespace Sokil\FraudDetector\Collector;

/**
 * Using memory table of MySQL storate as collector
 * Amount of space on memory table limited by `max_heap_table_size`, so set prefered value.
 */
class PdoMysqlCollector extends AbstractPdoCollector
{
    private $gcCheckInterval = 1200;

    private $gcSessionInterval = 1200;

    public function setGarbageCollector($checkInterval, $sessionInterval)
    {
        $this->gcCheckInterval = (int) $checkInterval;
        $this->gcSessionInterval = (int) $sessionInterval;
        return $this;
    }

    public function isRateLimitExceed()
    {
        $timeNow = microtime(true);

        $query = 'SELECT 1
            FROM ' . $this->getTableName() . '
            WHERE
                `key` = :key AND
                `expired` >= :timeNow AND
                `requestNum` >= :maxRequestNum';

        $parameters = array(
            ':key' => $this->key,
            ':maxRequestNum' => $this->requestNum,
            ':timeNow' => $timeNow,
        );

        try {
            $stmt = $this->storage->prepare($query);
            $result = @$stmt->execute($parameters);
            if(!$result) {
                throw new \PDOException('Table not exists');
            }
        } catch (\PDOException $e) {
            // if exception occurs, than no table still created
            return false;
        }

        // if record found than key has exceed requests
        if(!$stmt->rowCount()) {
            return false;
        }

        return true;
    }

    private function createTable()
    {
        $this->storage->query('
            CREATE TABLE ' . $this->getTableName() . '(
                `key` varchar(255) PRIMARY KEY NOT NULL,
                `requestNum` int NOT NULL DEFAULT 0,
                `expired` numeric(13, 3)
            ) ENGINE=Memory CHARSET=utf8;
        ');

    }

    public function collect()
    {
        $timeNow = microtime(true);

        // check if record already exists and get current values
        try {
            $query = '
                SELECT requestNum, expired
                FROM ' . $this->getTableName() . '
                WHERE `key` = :key
                FOR UPDATE';

            $stmt = $this->storage->prepare($query);
            $result = @$stmt->execute(array(
                ':key' => $this->key,
            ));

            if(!$result) {
                throw new \PDOException('Table not exists');
            }


        } catch (\PDOException $e) {
            // table yet not created
            $this->createTable();
            $this->collect();
            return;
        }

        $row = $stmt->fetch(\PDO::FETCH_ASSOC);

        if(!$row) {
            // record not exists
            $query = '
                INSERT INTO ' . $this->getTableName() . '(`key`, `requestNum`, `expired`)
                VALUES (:key, 1, :expired)
                ON DUPLICATE KEY UPDATE requestNum = requestNum + 1
            ';

            $stmt = $this->storage->prepare($query);
            $stmt->bindValue(':key', $this->key);
            $stmt->bindValue(':expired', $timeNow + $this->timeInterval);
            $stmt->execute();

            return;

        }

        $expiredTimestamp = (float) $row['expired'];

        if($timeNow <= $expiredTimestamp) {
            // in time slot - increment
            $query = '
                UPDATE ' . $this->getTableName() . '
                SET requestNum = requestNum + 1
                WHERE `key` = :key
            ';
            $parameters = array(
                ':key' => $this->key,
            );
        } else {
            //outside time slot - set new
            $query = '
                UPDATE ' . $this->getTableName() . '
                SET
                    requestNum = 1,
                    expired = :expired
                WHERE `key` = :key
            ';
            $parameters = array(
                ':key' => $this->key,
                ':expired' => $timeNow + $this->timeInterval,
            );
        }

        $stmt = $this->storage->prepare($query);
        $stmt->execute($parameters);


        // garbage collector
        if($timeNow % $this->gcCheckInterval === 0) {
            $query = '
                DELETE FROM ' . $this->getTableName() . '
                WHERE expired < ' . ($timeNow - $this->gcSessionInterval);
        }

    }
}

{'fraction_non_alphanumeric': 0.1305944457195318, 'fraction_numerical': 0.005049345880192793, 'mean_word_length': 1.3896353166986564, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 99, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2630412', 'n_tokens_mistral': 2504, 'n_tokens_neox': 2274, 'n_words': 536}