'Returns and claims up to limit unclaimed records for timeout seconds.
Returns a list of records which are now "claimed", a claimed record will
generally be unavailable to be claimed until the claim times out. Note
however that in case of an unexpected timeout or other error a record might
be claimed twice at the same time. For this reason it should be considered
weaker than a true lock.
Args:
limit: The number of records to claim.
timeout: The duration of the claim.
start_time: The time to start claiming records at. Only records with a
timestamp after this point will be claimed.
record_filter: A filter method to determine if the record should be
returned. It will be called serially on each record and the record will
be filtered (not returned or locked) if it returns True.
max_filtered: If non-zero, limits the number of results read when
filtered. Specifically, if max_filtered filtered results are read
sequentially without any unfiltered results, we stop looking for
results.
Returns:
A list (id, record) where record is a self.rdf_type and id is a record
identifier which can be used to delete or release the record.
Raises:
LockError: If the queue is not locked.'

def ClaimRecords(self, limit=10000, timeout='30m', start_time=None, record_filter=(lambda x: False), max_filtered=1000):

    if (not self.locked):
        raise aff4.LockError('Queue    must    be    locked    to    claim    records.')
    now = rdfvalue.RDFDatetime.Now()
    after_urn = None
    if start_time:
        after_urn = self._MakeURN(self.urn, start_time.AsMicroSecondsFromEpoch(), 0)
    results = []
    filtered_count = 0
    for (subject, values) in data_store.DB.ScanAttributes(self.urn.Add('Records'), [self.VALUE_ATTRIBUTE, self.LOCK_ATTRIBUTE], max_records=(4 * limit), after_urn=after_urn, token=self.token):
        if (self.VALUE_ATTRIBUTE not in values):
            data_store.DB.DeleteAttributes(subject, [self.LOCK_ATTRIBUTE], token=self.token)
            continue
        if (self.LOCK_ATTRIBUTE in values):
            timestamp = rdfvalue.RDFDatetime.FromSerializedString(values[self.LOCK_ATTRIBUTE][1])
            if (timestamp > now):
                continue
        rdf_value = self.rdf_type.FromSerializedString(values[self.VALUE_ATTRIBUTE][1])
        if record_filter(rdf_value):
            filtered_count += 1
            if (max_filtered and (filtered_count >= max_filtered)):
                break
            continue
        results.append((subject, rdf_value))
        filtered_count = 0
        if (len(results) >= limit):
            break
    expiration = (rdfvalue.RDFDatetime.Now() + rdfvalue.Duration(timeout))
    with data_store.DB.GetMutationPool(token=self.token) as mutation_pool:
        for (subject, _) in results:
            mutation_pool.Set(subject, self.LOCK_ATTRIBUTE, expiration)
    return results
