# Path: opendiamond/client/rpc.py
# class ControlConnection(_RPCClientConnection):
#     setup = _stub(25, protocol.XDR_setup, protocol.XDR_blob_list)
#     send_blobs = _stub(26, protocol.XDR_blob_data)
#     start = _stub(28, protocol.XDR_start)
#     reexecute_filters = _stub(30, protocol.XDR_reexecute,
#                               protocol.XDR_attribute_list)
#     request_stats = _stub(29, None, protocol.XDR_search_stats)
#     session_variables_get = _stub(18, None, protocol.XDR_session_vars)
#     session_variables_set = _stub(19, None, protocol.XDR_session_vars)
# 
#     # We intentionally omit the nonce argument
#     # pylint: disable=arguments-differ
#     def connect(self, address):
#         return _RPCClientConnection.connect(self, address)
# 
# class BlastConnection(_RPCClientConnection):
#     get_object = _stub(2, None, protocol.XDR_object)
# 
#     # We intentionally make the nonce mandatory
#     # pylint: disable=signature-differs
#     def connect(self, address, nonce):
#         return _RPCClientConnection.connect(self, address, nonce=nonce)
#     # pylint: enable=signature-differs
# 
# Path: opendiamond/protocol.py
# class XDR_setup(XDRStruct):
#     '''Search setup parameters'''
#     members = (
#         'cookies', XDR.array(XDR.string()),
#         'filters', XDR.array(XDR.struct(XDR_filter_config)),
#     )
# 
# class XDR_filter_config(XDRStruct):
#     '''Configuration for a single filter'''
#     members = (
#         'name', XDR.string(),
#         'arguments', XDR.array(XDR.string()),
#         'dependencies', XDR.array(XDR.string()),
#         'min_score', XDR.double(),
#         'max_score', XDR.double(),
#         'code', XDR.string(),
#         'blob', XDR.string(),
#     )
# 
# class XDR_blob_data(XDRStruct):
#     '''Blob data to be added to the blob cache'''
#     members = (
#         'blobs', XDR.array(XDR.opaque()),
#     )
# 
# class XDR_start(XDRStruct):
#     '''Start-search parameters'''
#     members = (
#         'search_id', XDR.fopaque(36),
#         'attrs', XDR.optional(XDR.array(XDR.string())),
#     )
# 
# class XDR_reexecute(XDRStruct):
#     '''Reexecute argument'''
#     members = (
#         'object_id', XDR.string(),
#         'attrs', XDR.optional(XDR.array(XDR.string())),
#     )
# 
# class DiamondRPCFCacheMiss(RPCError):
#     '''Filter code or blob argument missed in the blob cache.'''
#     code = 501
# 
# Path: opendiamond/rpc.py
# class RPCError(Exception):
#     '''Base class for RPC error codes.'''
#     code = None
# 
#     # pylint doesn't know about __subclasses__
#     # pylint: disable=no-member
#     @classmethod
#     def get_class(cls, code):
#         '''Return the error subclass for the specified code.'''
#         for c in cls.__subclasses__():
#             if c.code == code:
#                 return c
#             try:
#                 return c.get_class(code)
#             except KeyError:
#                 pass
#         raise KeyError('Error code %d' % code)
#     # pylint: enable=no-member
# 
# class ConnectionFailure(Exception):
#     '''RPC connection died.'''
# 
# Path: opendiamond/scope.py
# def get_cookie_map(cookies):
#     '''Given a list of ScopeCookies, return a dict: server ->[ScopeCookie].'''
#     map = {}
#     for cookie in cookies:
#         for server in cookie.servers:
#             map.setdefault(server, []).append(cookie)
#     return map


import binascii
import logging
import queue
import struct
import threading
import uuid
from builtins import object
from builtins import str
from collections import deque
from hashlib import sha256
from opendiamond.client.rpc import ControlConnection, BlastConnection
from opendiamond.protocol import (
    XDR_setup, XDR_filter_config, XDR_blob_data, XDR_start, XDR_reexecute,
    DiamondRPCFCacheMiss)
from opendiamond.rpc import RPCError, ConnectionFailure
from opendiamond.scope import get_cookie_map
        Return will an empty dict when search terminates.
        """
        reply = self.blast.get_object()
        dct = dict((attr.name, attr.value) for attr in reply.attrs)
        if not dct:
            # End of search
            self._finished = True
            dct = None
        elif self._should_unpack_attrs:
            dct = self.unpack_attributes(dct)
        return dct

    def evaluate(self, cookies, filters, blob, attrs=None):
        """
        Also known as re-execution.
        :param cookies:
        :param filters:
        :param blob:
        :param attrs:
        :return: A dictionary of the re-executed object's attribute-value pairs.
        """
        self.connect()
        self.setup(cookies, filters)

        # Send reexecute request
        request = XDR_reexecute(object_id=self._blob_uri(blob), attrs=attrs)
        try:
            reply = self.control.reexecute_filters(request)
        except DiamondRPCFCacheMiss:
            # Send object data and retry

# Path: opendiamond/client/rpc.py
# class ControlConnection(_RPCClientConnection):
#     setup = _stub(25, protocol.XDR_setup, protocol.XDR_blob_list)
#     send_blobs = _stub(26, protocol.XDR_blob_data)
#     start = _stub(28, protocol.XDR_start)
#     reexecute_filters = _stub(30, protocol.XDR_reexecute,
#                               protocol.XDR_attribute_list)
#     request_stats = _stub(29, None, protocol.XDR_search_stats)
#     session_variables_get = _stub(18, None, protocol.XDR_session_vars)
#     session_variables_set = _stub(19, None, protocol.XDR_session_vars)
# 
#     # We intentionally omit the nonce argument
#     # pylint: disable=arguments-differ
#     def connect(self, address):
#         return _RPCClientConnection.connect(self, address)
# 
# class BlastConnection(_RPCClientConnection):
#     get_object = _stub(2, None, protocol.XDR_object)
# 
#     # We intentionally make the nonce mandatory
#     # pylint: disable=signature-differs
#     def connect(self, address, nonce):
#         return _RPCClientConnection.connect(self, address, nonce=nonce)
#     # pylint: enable=signature-differs
# 
# Path: opendiamond/protocol.py
# class XDR_setup(XDRStruct):
#     '''Search setup parameters'''
#     members = (
#         'cookies', XDR.array(XDR.string()),
#         'filters', XDR.array(XDR.struct(XDR_filter_config)),
#     )
# 
# class XDR_filter_config(XDRStruct):
#     '''Configuration for a single filter'''
#     members = (
#         'name', XDR.string(),
#         'arguments', XDR.array(XDR.string()),
#         'dependencies', XDR.array(XDR.string()),
#         'min_score', XDR.double(),
#         'max_score', XDR.double(),
#         'code', XDR.string(),
#         'blob', XDR.string(),
#     )
# 
# class XDR_blob_data(XDRStruct):
#     '''Blob data to be added to the blob cache'''
#     members = (
#         'blobs', XDR.array(XDR.opaque()),
#     )
# 
# class XDR_start(XDRStruct):
#     '''Start-search parameters'''
#     members = (
#         'search_id', XDR.fopaque(36),
#         'attrs', XDR.optional(XDR.array(XDR.string())),
#     )
# 
# class XDR_reexecute(XDRStruct):
#     '''Reexecute argument'''
#     members = (
#         'object_id', XDR.string(),
#         'attrs', XDR.optional(XDR.array(XDR.string())),
#     )
# 
# class DiamondRPCFCacheMiss(RPCError):
#     '''Filter code or blob argument missed in the blob cache.'''
#     code = 501
# 
# Path: opendiamond/rpc.py
# class RPCError(Exception):
#     '''Base class for RPC error codes.'''
#     code = None
# 
#     # pylint doesn't know about __subclasses__
#     # pylint: disable=no-member
#     @classmethod
#     def get_class(cls, code):
#         '''Return the error subclass for the specified code.'''
#         for c in cls.__subclasses__():
#             if c.code == code:
#                 return c
#             try:
#                 return c.get_class(code)
#             except KeyError:
#                 pass
#         raise KeyError('Error code %d' % code)
#     # pylint: enable=no-member
# 
# class ConnectionFailure(Exception):
#     '''RPC connection died.'''
# 
# Path: opendiamond/scope.py
# def get_cookie_map(cookies):
#     '''Given a list of ScopeCookies, return a dict: server ->[ScopeCookie].'''
#     map = {}
#     for cookie in cookies:
#         for server in cookie.servers:
#             map.setdefault(server, []).append(cookie)
#     return map


# Path: opendiamond/client/search.py
import binascii
import logging
import queue
import struct
import threading
import uuid
from builtins import object
from builtins import str
from collections import deque
from hashlib import sha256
from opendiamond.client.rpc import ControlConnection, BlastConnection
from opendiamond.protocol import (
    XDR_setup, XDR_filter_config, XDR_blob_data, XDR_start, XDR_reexecute,
    DiamondRPCFCacheMiss)
from opendiamond.rpc import RPCError, ConnectionFailure
from opendiamond.scope import get_cookie_map

        Return will an empty dict when search terminates.
        """
        reply = self.blast.get_object()
        dct = dict((attr.name, attr.value) for attr in reply.attrs)
        if not dct:
            # End of search
            self._finished = True
            dct = None
        elif self._should_unpack_attrs:
            dct = self.unpack_attributes(dct)
        return dct

    def evaluate(self, cookies, filters, blob, attrs=None):
        """
        Also known as re-execution.
        :param cookies:
        :param filters:
        :param blob:
        :param attrs:
        :return: A dictionary of the re-executed object's attribute-value pairs.
        """
        self.connect()
        self.setup(cookies, filters)

        # Send reexecute request
        request = XDR_reexecute(object_id=self._blob_uri(blob), attrs=attrs)
        try:
            reply = self.control.reexecute_filters(request)
        except DiamondRPCFCacheMiss:
            # Send object data and retry

            self.control.send_blobs(XDR_blob_data(blobs=[str(blob)]))