public function add($data, $shard = NULL) { $id = $this->core->add($data, $shard); $this->cache->set($id, $data); list($shard, $sequence) = Util::parseId($id); $shardkey = 'shard_' . $shard; $this->cache->set($shardkey, $sequence, $this->ttl); $shards = $this->cache->get('shards'); if (!is_array($shards)) { return $id; } if (!isset($shards[$shard])) { $shards[$shard] = 1; $this->cache->set('shards', $shards, $this->ttl); } return $id; }
/** * update an existing entry based on id. It does an insert or update just in case the record is missing in the db. */ public function store($id, $data) { $ids = Util::validateIds($this->shardSequences(), array($id)); if (!in_array($id, $ids)) { throw new Exception('invalid id', $id); } list($shard, $sequence) = Util::parseId($id); $table = $this->table($shard); $db = $this->db($table); if (DB\Transaction::inProgress()) { DB\Transaction::add($db); } $sql = "INSERT INTO {$table} (thread, sequence, data) VALUES (%i, %i, %s) ON DUPLICATE KEY UPDATE `data` = VALUES(`data`)"; $db->execute($sql, $this->thread, $sequence, $this->serialize($data)); return TRUE; }
public static function parseIds(array $ids) { $info = array(); foreach ($ids as $id) { list($shard, $sequence) = Util::parseId($id); if (!$shard || !$sequence) { continue; } if (!isset($info[$shard])) { $info[$shard] = array(); } $info[$shard][] = $sequence; } return $info; }
$skein->filter(array('sort' => 'descending', 'process' => $cb, 'start_after' => $ids[5])); $expected_sum = 0; foreach (array_slice(array_reverse($batch, TRUE), 5) as $data) { $expected_sum = bcadd($expected_sum, $data['foo']); } Tap::is($ct, 6, 'filter descending with start_after iterated the correct number of rows'); Tap::is($sum, $expected_sum, 'sum from filter with start_after arrived at the correct amount'); $generated_ids = $post_processed_ids = array(); $generate = function (array $params) use($skein, &$generated_ids, &$post_processed_ids) { $return = array(); $ids = $skein->ids($params); foreach ($ids as $id) { $generated_ids[] = $id; if ($id % 2 == 0) { $post_processed_ids[] = $return[] = $id; } } return $return; }; $processed_ids = array(); $process = function ($id, $data) use(&$processed_ids) { $processed_ids[] = $id; }; $skein->filter(array('process' => $process, 'generate' => $generate)); Tap::is($generated_ids, $ids, 'generate filter gets all the ids'); Tap::is($processed_ids, $post_processed_ids, 'process filter gets only the ids returned by generate'); $shard = mt_rand(1, 100); $id = $skein->add($data = array('foo' => mt_rand(1, 1000000000)), $shard); $parts = Skein\Util::parseId($id); Tap::is($parts[0], $shard, 'created a new entry, using a custom shard'); Tap::is($skein->get($id), $data, 'read back the entry with custom shard');
/** * update an existing entry based on id. It does an insert or update just in case the record is missing in the db. */ public function store($id, $data) { $ids = Util::validateIds($this->shardSequences(), array($id)); if (!in_array($id, $ids)) { throw new Exception('invalid id', $id); } list($shard, $sequence) = Util::parseId($id); $table = $this->table($shard); $db = $this->db($table); if (DB\Transaction::inProgress()) { DB\Transaction::add($db); } $sql = "INSERT OR IGNORE INTO {$table} (thread, sequence, data) VALUES (%i, %i, %s)"; $data = $this->serialize($data); $rs = $db->execute($sql, $this->thread, $sequence, $data); if (!$rs->affected()) { $sql = "UPDATE {$table} SET `data` = %s WHERE `thread` = %i AND `sequence` = %i"; $db->execute($sql, $data, $this->thread, $sequence); } return TRUE; }