thobbs / phpcassa

PHP client library for Apache Cassandra
thobbs.github.com/phpcassa
MIT License
248 stars 78 forks source link

Using C extension "thrift_protocol" causes timestamp corruption #26

Closed snelson21 closed 13 years ago

snelson21 commented 13 years ago

With C extension "thrift_protocol" enabled all timestamps generated with CassandraUtil::get_time() are corrupted to become negative numbers. Columns were not able to be removed either. I could make it work by passing my own timestamp generated with time(), but that didn't give enough precision and there is also no way to pass a custom timestamp into the remove() function.

Once thrift_protocol was disabled in php.ini everything worked perfectly without the need to pass in my own timestamps at all.

thobbs commented 13 years ago

Ah, so that's what's going on. Thanks for looking in to this. Are you on a 32bit or 64bit system? What version of php are you using?

snelson21 commented 13 years ago

No problem, thanks for all your work. I am using Arch Linux 32bit and php 5.3.6.

edit -- Sorry I accidentally hit the close button

thobbs commented 13 years ago

It's almost certainly a 32 bit problem with php (as you probably know, php doesn't have universal support for 64 bit integers), but I'll look into it. In the meantime (and in general), I would recommend using 64bit systems if you're going to use php with Cassandra.

Timandes commented 13 years ago

Is this function helpful?i wrote it to create a under-control timestamp when comparator of column family in my website is 'LongType':

/**
 * 获取长整型的Unix时间戳记
 *
 * @param string $sMicrotime microtime()函数的返回值(默认为空,取当前时间)
 * @return string 低位在前的方式保存的长整型
 */
public static function getTimestampLong($sMicrotime = '', $bLittleEndianByteOrder = TRUE) {
    if(!$sMicrotime) {
        $sMicrotime = microtime();
    }

    list($usec, $sec) = explode(" ", $sMicrotime);

    $iHi = (int)((float)$sec / 4294.967296);

    $fRemain = (float)(((float)$sec - (float)$iHi * 4294.967296 + (float)$usec) * 100.0);
    $iMed = (int)($fRemain / 6.5536);

    $fRemain = (float)($fRemain - (float)$iMed * 6.5536);
    $iLow = (int)($fRemain * 10000.0 + 0.5);

    if($bLittleEndianByteOrder) {
        return (pack("v", $iLow) . pack("v", $iMed) . pack("V", $iHi));
    } else {
        return (pack("N", $iHi) . pack("n", $iMed) . pack("n", $iLow));
    }
}

it is used like this when i need inserting a timestamp as column name: $ts = xxxx::getTimestampLong("", FALSE); $timeline->insert($sUserID, array($ts => $sFeedID));

thobbs commented 13 years ago

Sorry, for some reason I did not see this comment until just now. I apologize for the slow response! I'm looking it over now.

thobbs commented 13 years ago

I set up a good 32bit environment and tested out Thrift 0.7.0, which just came out a few days ago and patches the C extension. With Thrift 0.6.1, the timestamp corruption occurred, but with Thrift 0.7.0, it does not.

I would prefer to use a solution that's included in the mainstream Thrift library instead of using custom builds. However, I sincerely appreciate your proposed contribution here.

Thanks again!

Timandes commented 13 years ago

You're welcome. I'm a real beginner of GitHub & PHP & C. I really hope i can help a little.