示例#1
0
 def FROM(self, tr, *pattern, seed=Map()):  # seed is immutable
     """Yields bindings that match PATTERN"""
     assert len(pattern) == len(self._items), "invalid item count"
     variable = tuple(isinstance(x, Variable) for x in pattern)
     # find the first index suitable for the query
     combination = tuple(x for x in range(len(self._items))
                         if not variable[x])
     for subspace, index in enumerate(self._indices):
         if is_permutation_prefix(combination, index):
             break
     else:
         raise NStoreException("Oops!")
     # `index` variable holds the permutation suitable for the
     # query. `subspace` is the "prefix" of that index.
     prefix = tuple(pattern[i] for i in index
                    if not isinstance(pattern[i], Variable))
     prefix = (self._prefix, subspace, prefix)
     for key, _ in tr.get_range_startswith(fdb.tuple.pack(prefix)[:-1]):
         key = fdb.tuple.unpack(key)
         items = key[2]
         # re-order the items
         items = tuple(items[index.index(i)]
                       for i in range(len(self._items)))
         # seed is immutable
         bindings = seed
         for i, item in enumerate(pattern):
             if isinstance(item, Variable):
                 bindings = bindings.set(item.name, items[i])
         yield bindings
示例#2
0
 def __init__(self, docPath, keyPath):
     docPath = ["d"] + docPath.split(".")
     if keyPath:
         keyPath = keyPath.split(".")
     else:
         keyPath = []
     self.docPath = tuple(docPath)
     self.keyPath = tuple(keyPath)
     self.dkPath = tuple(docPath + keyPath)
     self.index_keys = tuple(i for i, k in enumerate(docPath) if k == '?')
     self.key_keys = tuple(i+len(docPath) for i, k in enumerate(keyPath) if k == '?')
     self.register(self.dkPath)
     self.index_doc = root.index[str(self.plugin_id)]
示例#3
0
 def __init__(self, docPath, keyPath):
     docPath = ["d"] + docPath.split(".")
     if keyPath:
         keyPath = keyPath.split(".")
     else:
         keyPath = []
     self.docPath = tuple(docPath)
     self.keyPath = tuple(keyPath)
     self.dkPath = tuple(docPath + keyPath)
     self.index_keys = tuple(i for i, k in enumerate(docPath) if k == '?')
     self.key_keys = tuple(i + len(docPath) for i, k in enumerate(keyPath)
                           if k == '?')
     self.register(self.dkPath)
     self.index_doc = root.index[str(self.plugin_id)]
示例#4
0
    def push_range(self, inst, iter, prefix_filter=None):
        kvs = []
        for k, v in iter:
            if prefix_filter is None or k.startswith(prefix_filter):
                kvs += [k, v]

        inst.push(fdb.tuple.pack(tuple(kvs)))
示例#5
0
 def func(*args):
     assert len(args) == arity, "arity mismatch"
     leftmost_consts = [arg.id for arg in
                        itertools.takewhile(lambda x: x.is_const(), args[:-1])]
     prefix_tuple = tuple(leftmost_consts)
     partial_key = len(leftmost_consts) < arity - 1
     for k, v in self._get_generic_predicate(db, prefix_tuple, partial_key):
         yield self.subspace.unpack(k)+(v,)
示例#6
0
 def func(*args):
     assert len(args) == arity, "arity mismatch"
     leftmost_consts = [arg.id for arg in
                        itertools.takewhile(lambda x: x.is_const(), args)]
     prefix_tuple = (prefix,) + tuple(leftmost_consts)
     partial_key = len(leftmost_consts) < arity
     for t in self._get_custom_predicate(db, prefix_tuple, partial_key):
         yield self.subspace.unpack(t)[1:]
示例#7
0
def z_to_xy(z):
    m = [0,0]
    l = 0
    while z:
        for i in [0, 1]:
            m[i] += (z & 1) << l
            z >>= 1
        l += 1
    return tuple(m)
示例#8
0
 def reader(self):
     for fully_pathed in glob.iglob(os.path.join(self._dir, self._filename)):
         if not os.path.isfile(fully_pathed): continue
         with open(fully_pathed, 'rb') as csv_file:
             csv_reader = csv.reader(csv_file, delimiter=self._delimiter)
             first_line = True
             for line in csv_reader:
                 if self._header and first_line:
                     first_line = False
                     continue
                 if self._skip_empty:
                     line = [v for v in line if v != '']
                 yield tuple(line)
示例#9
0
 def reader(self):
     for fully_pathed in glob.iglob(os.path.join(self._dir, self._filename)):
         if not os.path.isfile(fully_pathed): continue
         with open(fully_pathed, 'rb') as csv_file:
             csv_reader = csv.reader(csv_file, delimiter=self._delimiter)
             first_line = True
             for line in csv_reader:
                 if self._header and first_line:
                     first_line = False
                     continue
                 if self._skip_empty:
                     line = [v for v in line if v != '']
                 yield tuple(line)
示例#10
0
    def _to_unicode_path(self, path):
        if isinstance(path, str):
            path = unicode(path)

        if isinstance(path, unicode):
            return (path,)

        if isinstance(path, tuple):
            path = list(path)
            for i, name in enumerate(path):
                if isinstance(name, str):
                    path[i] = unicode(path[i])
                elif not isinstance(name, unicode):
                    raise ValueError('Invalid path: must be a unicode string or a tuple of unicode strings')

            return tuple(path)

        raise ValueError('Invalid path: must be a unicode string or a tuple of unicode strings')
示例#11
0
    def random_tuple(self, max_size, incomplete_versionstamps=False):
        size = random.randint(1, max_size)
        tup = []

        for i in range(size):
            choice = random.choice(self.types)
            if choice == 'int':
                tup.append(self.random_int())
            elif choice == 'null':
                tup.append(None)
            elif choice == 'bytes':
                tup.append(self.random_string(random.randint(0, 100)))
            elif choice == 'string':
                tup.append(self.random_unicode_str(random.randint(0, 100)))
            elif choice == 'uuid':
                tup.append(uuid.uuid4())
            elif choice == 'bool':
                b = random.random() < 0.5
                if self.api_version < 500:
                    tup.append(int(b))
                else:
                    tup.append(b)
            elif choice == 'float':
                tup.append(fdb.tuple.SingleFloat(self.random_float(8)))
            elif choice == 'double':
                tup.append(self.random_float(11))
            elif choice == 'tuple':
                length = random.randint(0, max_size - size)
                if length == 0:
                    tup.append(())
                else:
                    tup.append(self.random_tuple(length))
            elif choice == 'versionstamp':
                if incomplete_versionstamps and random.random() < 0.5:
                    tr_version = fdb.tuple.Versionstamp._UNSET_TR_VERSION
                else:
                    tr_version = self.random_string(10)
                user_version = random.randint(0, 0xffff)
                tup.append(fdb.tuple.Versionstamp(tr_version, user_version))
            else:
                assert false

        return tuple(tup)
def _to_unicode_path(path):
    if isinstance(path, bytes):
        path = six.text_type(path)

    if isinstance(path, six.text_type):
        return (path, )

    if isinstance(path, tuple):
        path = list(path)
        for i, name in enumerate(path):
            if isinstance(name, bytes):
                path[i] = six.text_type(path[i])
            elif not isinstance(name, six.text_type):
                raise ValueError(
                    'Invalid path: must be a unicode string or a tuple of unicode strings'
                )

        return tuple(path)

    raise ValueError(
        'Invalid path: must be a unicode string or a tuple of unicode strings')
示例#13
0
    def run(self):
        for idx, i in enumerate(self.instructions):
            op_tuple = fdb.tuple.unpack(i.value)
            op = op_tuple[0]

            # print("Stack is %r" % self.stack)
            # if op != "PUSH" and op != "SWAP":
            #     print("%d. Instruction is %s" % (idx, op))

            isDatabase = op.endswith(six.u('_DATABASE'))
            isSnapshot = op.endswith(six.u('_SNAPSHOT'))

            if isDatabase:
                op = op[:-9]
                obj = self.db
            elif isSnapshot:
                op = op[:-9]
                obj = self.current_transaction().snapshot
            else:
                obj = self.current_transaction()

            inst = Instruction(obj, self.stack, op, idx, isDatabase, isSnapshot)

            try:
                if inst.op == six.u("PUSH"):
                    inst.push(op_tuple[1])
                elif inst.op == six.u("DUP"):
                    inst.stack.push(*self.stack[0])
                elif inst.op == six.u("EMPTY_STACK"):
                    self.stack = Stack()
                elif inst.op == six.u("SWAP"):
                    idx = inst.pop()
                    self.stack[0], self.stack[idx] = self.stack[idx], self.stack[0]
                elif inst.op == six.u("POP"):
                    inst.pop()
                elif inst.op == six.u("SUB"):
                    a, b = inst.pop(2)
                    inst.push(a - b)
                elif inst.op == six.u("CONCAT"):
                    a, b = inst.pop(2)
                    inst.push(a + b)
                elif inst.op == six.u("WAIT_FUTURE"):
                    old_idx, item = inst.pop(with_idx=True)
                    inst.stack.push(old_idx, item)
                elif inst.op == six.u("NEW_TRANSACTION"):
                    self.new_transaction()
                elif inst.op == six.u("USE_TRANSACTION"):
                    self.switch_transaction(inst.pop())
                elif inst.op == six.u("ON_ERROR"):
                    inst.push(inst.tr.on_error(inst.pop()))
                elif inst.op == six.u("GET"):
                    key = inst.pop()
                    num = random.randint(0, 2)
                    if num == 0:
                        f = obj[key]
                    elif num == 1:
                        f = obj.get(key)
                    else:
                        f = obj.__getitem__(key)

                    if f == None:
                        inst.push(b'RESULT_NOT_PRESENT')
                    else:
                        inst.push(f)
                elif inst.op == six.u("GET_ESTIMATED_RANGE_SIZE"):
                    begin, end = inst.pop(2)
                    estimatedSize = obj.get_estimated_range_size_bytes(begin, end).wait()
                    inst.push(b"GOT_ESTIMATED_RANGE_SIZE")
                elif inst.op == six.u("GET_KEY"):
                    key, or_equal, offset, prefix = inst.pop(4)
                    result = obj.get_key(fdb.KeySelector(key, or_equal, offset))
                    if result.startswith(prefix):
                        inst.push(result)
                    elif result < prefix:
                        inst.push(prefix)
                    else:
                        inst.push(strinc(prefix))

                elif inst.op == six.u("GET_RANGE"):
                    begin, end, limit, reverse, mode = inst.pop(5)
                    if limit == 0 and mode == -1 and random.random() < 0.5:
                        if reverse:
                            r = obj[begin:end:-1]
                        else:
                            r = obj[begin:end]
                    else:
                        r = obj.get_range(begin, end, limit, reverse, mode)

                    self.push_range(inst, r)
                elif inst.op == six.u("GET_RANGE_STARTS_WITH"):
                    prefix, limit, reverse, mode = inst.pop(4)
                    self.push_range(inst, obj.get_range_startswith(prefix, limit, reverse, mode))
                elif inst.op == six.u("GET_RANGE_SELECTOR"):
                    begin_key, begin_or_equal, begin_offset, end_key, end_or_equal, end_offset, limit, reverse, mode, prefix = inst.pop(10)
                    beginSel = fdb.KeySelector(begin_key, begin_or_equal, begin_offset)
                    endSel = fdb.KeySelector(end_key, end_or_equal, end_offset)
                    if limit == 0 and mode == -1 and random.random() < 0.5:
                        if reverse:
                            r = obj[beginSel:endSel:-1]
                        else:
                            r = obj[beginSel:endSel]
                    else:
                        r = obj.get_range(beginSel, endSel, limit, reverse, mode)

                    self.push_range(inst, r, prefix_filter=prefix)
                elif inst.op == six.u("GET_READ_VERSION"):
                    self.last_version = obj.get_read_version().wait()
                    inst.push(b"GOT_READ_VERSION")
                elif inst.op == six.u("SET"):
                    key, value = inst.pop(2)
                    if random.random() < 0.5:
                        obj[key] = value
                    else:
                        obj.set(key, value)

                    if obj == self.db:
                        inst.push(b"RESULT_NOT_PRESENT")
                elif inst.op == six.u("LOG_STACK"):
                    prefix = inst.pop()
                    entries = {}
                    while len(self.stack) > 0:
                        stack_index = len(self.stack) - 1
                        entries[stack_index] = inst.pop(with_idx=True)
                        if len(entries) == 100:
                            self.log_stack(self.db, prefix, entries)
                            entries = {}

                    self.log_stack(self.db, prefix, entries)
                elif inst.op == six.u("ATOMIC_OP"):
                    opType, key, value = inst.pop(3)
                    getattr(obj, opType.lower())(key, value)

                    if obj == self.db:
                        inst.push(b"RESULT_NOT_PRESENT")
                elif inst.op == six.u("SET_READ_VERSION"):
                    inst.tr.set_read_version(self.last_version)
                elif inst.op == six.u("CLEAR"):
                    if random.random() < 0.5:
                        del obj[inst.pop()]
                    else:
                        obj.clear(inst.pop())

                    if obj == self.db:
                        inst.push(b"RESULT_NOT_PRESENT")
                elif inst.op == six.u("CLEAR_RANGE"):
                    begin, end = inst.pop(2)
                    num = random.randint(0, 2)
                    if num == 0:
                        del obj[begin:end]
                    elif num == 1:
                        obj.clear_range(begin, end)
                    else:
                        obj.__delitem__(slice(begin, end))

                    if obj == self.db:
                        inst.push(b"RESULT_NOT_PRESENT")
                elif inst.op == six.u("CLEAR_RANGE_STARTS_WITH"):
                    obj.clear_range_startswith(inst.pop())
                    if obj == self.db:
                        inst.push(b"RESULT_NOT_PRESENT")
                elif inst.op == six.u("READ_CONFLICT_RANGE"):
                    inst.tr.add_read_conflict_range(inst.pop(), inst.pop())
                    inst.push(b"SET_CONFLICT_RANGE")
                elif inst.op == six.u("WRITE_CONFLICT_RANGE"):
                    inst.tr.add_write_conflict_range(inst.pop(), inst.pop())
                    inst.push(b"SET_CONFLICT_RANGE")
                elif inst.op == six.u("READ_CONFLICT_KEY"):
                    inst.tr.add_read_conflict_key(inst.pop())
                    inst.push(b"SET_CONFLICT_KEY")
                elif inst.op == six.u("WRITE_CONFLICT_KEY"):
                    inst.tr.add_write_conflict_key(inst.pop())
                    inst.push(b"SET_CONFLICT_KEY")
                elif inst.op == six.u("DISABLE_WRITE_CONFLICT"):
                    inst.tr.options.set_next_write_no_write_conflict_range()
                elif inst.op == six.u("COMMIT"):
                    inst.push(inst.tr.commit())
                elif inst.op == six.u("RESET"):
                    inst.tr.reset()
                elif inst.op == six.u("CANCEL"):
                    inst.tr.cancel()
                elif inst.op == six.u("GET_COMMITTED_VERSION"):
                    self.last_version = inst.tr.get_committed_version()
                    inst.push(b"GOT_COMMITTED_VERSION")
                elif inst.op == six.u("GET_APPROXIMATE_SIZE"):
                    approximate_size = inst.tr.get_approximate_size().wait()
                    inst.push(b"GOT_APPROXIMATE_SIZE")
                elif inst.op == six.u("GET_VERSIONSTAMP"):
                    inst.push(inst.tr.get_versionstamp())
                elif inst.op == six.u("TUPLE_PACK"):
                    count = inst.pop()
                    items = inst.pop(count)
                    inst.push(fdb.tuple.pack(tuple(items)))
                elif inst.op == six.u("TUPLE_PACK_WITH_VERSIONSTAMP"):
                    prefix = inst.pop()
                    count = inst.pop()
                    items = inst.pop(count)
                    if not fdb.tuple.has_incomplete_versionstamp(items) and random.random() < 0.5:
                        inst.push(b"ERROR: NONE")
                    else:
                        try:
                            packed = fdb.tuple.pack_with_versionstamp(tuple(items), prefix=prefix)
                            inst.push(b"OK")
                            inst.push(packed)
                        except ValueError as e:
                            if str(e).startswith("No incomplete"):
                                inst.push(b"ERROR: NONE")
                            else:
                                inst.push(b"ERROR: MULTIPLE")
                elif inst.op == six.u("TUPLE_UNPACK"):
                    for i in fdb.tuple.unpack(inst.pop()):
                        inst.push(fdb.tuple.pack((i,)))
                elif inst.op == six.u("TUPLE_SORT"):
                    count = inst.pop()
                    items = inst.pop(count)
                    unpacked = map(fdb.tuple.unpack, items)
                    if six.PY3:
                        sorted_items = sorted(unpacked, key=fdb.tuple.pack)
                    else:
                        sorted_items = sorted(unpacked, cmp=fdb.tuple.compare)
                    for item in sorted_items:
                        inst.push(fdb.tuple.pack(item))
                elif inst.op == six.u("TUPLE_RANGE"):
                    count = inst.pop()
                    items = inst.pop(count)
                    r = fdb.tuple.range(tuple(items))
                    inst.push(r.start)
                    inst.push(r.stop)
                elif inst.op == six.u("ENCODE_FLOAT"):
                    f_bytes = inst.pop()
                    f = struct.unpack(">f", f_bytes)[0]
                    if not math.isnan(f) and not math.isinf(f) and not f == -0.0 and f == int(f):
                        f = int(f)
                    inst.push(fdb.tuple.SingleFloat(f))
                elif inst.op == six.u("ENCODE_DOUBLE"):
                    d_bytes = inst.pop()
                    d = struct.unpack(">d", d_bytes)[0]
                    inst.push(d)
                elif inst.op == six.u("DECODE_FLOAT"):
                    f = inst.pop()
                    f_bytes = struct.pack(">f", f.value)
                    inst.push(f_bytes)
                elif inst.op == six.u("DECODE_DOUBLE"):
                    d = inst.pop()
                    d_bytes = struct.pack(">d", d)
                    inst.push(d_bytes)
                elif inst.op == six.u("START_THREAD"):
                    t = Tester(self.db, inst.pop())
                    thr = threading.Thread(target=t.run)
                    thr.start()
                    self.threads.append(thr)
                elif inst.op == six.u("WAIT_EMPTY"):
                    prefix = inst.pop()
                    Tester.wait_empty(self.db, prefix)
                    inst.push(b"WAITED_FOR_EMPTY")
                elif inst.op == six.u("UNIT_TESTS"):
                    try:
                        test_db_options(db)
                        test_options(db)
                        test_watches(db)
                        test_cancellation(db)
                        test_retry_limits(db)
                        test_db_retry_limits(db)
                        test_timeouts(db)
                        test_db_timeouts(db)
                        test_combinations(db)
                        test_locality(db)
                        test_predicates()

                        test_size_limit_option(db)
                        test_get_approximate_size(db)

                    except fdb.FDBError as e:
                        print("Unit tests failed: %s" % e.description)
                        traceback.print_exc()

                        raise Exception("Unit tests failed: %s" % e.description)
                elif inst.op.startswith(six.u('DIRECTORY_')):
                    self.directory_extension.process_instruction(inst)
                else:
                    raise Exception("Unknown op %s" % inst.op)
            except fdb.FDBError as e:
                # print('ERROR: %r' % e)
                inst.stack.push(idx, fdb.tuple.pack((b"ERROR", str(e.code).encode('ascii'))))

            # print("        to %s" % self.stack)
            # print()

        [thr.join() for thr in self.threads]
示例#14
0
 def pack(self, t=tuple()):
     return self.rawPrefix + fdb.tuple.pack(t)
示例#15
0
 def range(self, t=tuple()):
     p = fdb.tuple.range(t)
     return slice(self.rawPrefix + p.start, self.rawPrefix + p.stop)
示例#16
0
 def pack_with_versionstamp(self, t=tuple()):
     return fdb.tuple.pack_with_versionstamp(t, prefix=self.rawPrefix)
示例#17
0
 def pack(self, t=tuple()):
     return self.rawPrefix + fdb.tuple.pack(t)
示例#18
0
 def __init__(self, prefixTuple=tuple(), rawPrefix=b''):
     self.rawPrefix = fdb.tuple.pack(prefixTuple, prefix=rawPrefix)
示例#19
0
 def __init__(self, prefixTuple=tuple(), rawPrefix=""):
     self.rawPrefix = rawPrefix + fdb.tuple.pack(prefixTuple)
示例#20
0
 def __init__(self, prefixTuple=tuple(), rawPrefix=""):
     self.rawPrefix = rawPrefix + fdb.tuple.pack(prefixTuple)
 def range(self, t=tuple()):
     raise Exception(
         'Cannot get range for the root of a directory partition.')
 def pack(self, t=tuple()):
     raise Exception(
         'Cannot pack keys using the root of a directory partition.')
示例#23
0
 def pack(self, t=tuple()):
     return fdb.tuple.pack(t, prefix=self.rawPrefix)
示例#24
0
 def range(self, t=tuple()):
     p = fdb.tuple.range(t)
     return slice(self.rawPrefix + p.start, self.rawPrefix + p.stop)