Merge commit '7f6fc3e039c911cd84b8540f7f799fc38a1c1822' into feature-remote-logs
# Conflicts: # fdbserver/workloads/RestartRecovery.actor.cpp
This commit is contained in:
commit
37a6a81634
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -21,36 +21,37 @@
|
|||
import sys
|
||||
import os
|
||||
|
||||
sys.path[:0]=[os.path.join(os.path.dirname(__file__), '..', '..', 'bindings', 'python')]
|
||||
sys.path[:0] = [os.path.join(os.path.dirname(__file__), '..', '..', 'bindings', 'python')]
|
||||
|
||||
import util
|
||||
|
||||
FDB_API_VERSION = 510
|
||||
|
||||
LOGGING = {
|
||||
'version' : 1,
|
||||
'disable_existing_loggers' : False,
|
||||
'formatters' : {
|
||||
'simple' : {
|
||||
'format' : '%(message)s'
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'simple': {
|
||||
'format': '%(message)s'
|
||||
}
|
||||
},
|
||||
'handlers' : {
|
||||
'console' : {
|
||||
'level' : 'NOTSET',
|
||||
'class' : 'logging.StreamHandler',
|
||||
'stream' : sys.stdout,
|
||||
'formatter' : 'simple'
|
||||
'handlers': {
|
||||
'console': {
|
||||
'level': 'NOTSET',
|
||||
'class': 'logging.StreamHandler',
|
||||
'stream': sys.stdout,
|
||||
'formatter': 'simple'
|
||||
}
|
||||
},
|
||||
'loggers' : {
|
||||
'foundationdb.bindingtester' : {
|
||||
'level' : 'INFO',
|
||||
'handlers' : ['console']
|
||||
'loggers': {
|
||||
'foundationdb.bindingtester': {
|
||||
'level': 'INFO',
|
||||
'handlers': ['console']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Result:
|
||||
def __init__(self, subspace, key, values):
|
||||
self.subspace_tuple = util.subspace_to_tuple(subspace)
|
||||
|
@ -63,7 +64,7 @@ class Result:
|
|||
|
||||
left_key = self.key_tuple[specification.key_start_index:]
|
||||
right_key = self.key_tuple[specification.key_start_index:]
|
||||
|
||||
|
||||
if len(left_key) != len(right_key) or left_key != right_key:
|
||||
return False
|
||||
|
||||
|
@ -81,7 +82,7 @@ class Result:
|
|||
def sequence_num(self, specification):
|
||||
if specification.ordering_index is not None:
|
||||
return self.key_tuple[specification.ordering_index]
|
||||
|
||||
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
|
@ -91,4 +92,3 @@ class Result:
|
|||
value_str = repr(self.values)
|
||||
|
||||
return '%s = %s' % (repr(self.subspace_tuple + self.key_tuple), value_str)
|
||||
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -34,8 +34,9 @@ from threading import Timer, Event
|
|||
import logging.config
|
||||
|
||||
from collections import OrderedDict
|
||||
from functools import reduce
|
||||
|
||||
sys.path[:0]=[os.path.join(os.path.dirname(__file__), '..')]
|
||||
sys.path[:0] = [os.path.join(os.path.dirname(__file__), '..')]
|
||||
|
||||
import bindingtester
|
||||
|
||||
|
@ -52,6 +53,7 @@ import fdb.tuple
|
|||
|
||||
fdb.api_version(FDB_API_VERSION)
|
||||
|
||||
|
||||
class ResultSet(object):
|
||||
def __init__(self, specification):
|
||||
self.specification = specification
|
||||
|
@ -80,20 +82,20 @@ class ResultSet(object):
|
|||
has_filtered_error = False
|
||||
|
||||
while True:
|
||||
results = { i : r[indices[i]] for i, r in enumerate(self.tester_results.values()) if len(r) > indices[i] }
|
||||
results = {i: r[indices[i]] for i, r in enumerate(self.tester_results.values()) if len(r) > indices[i]}
|
||||
if len(results) == 0:
|
||||
break
|
||||
|
||||
sequence_nums = [ r.sequence_num(self.specification) for r in results.values() ]
|
||||
sequence_nums = [r.sequence_num(self.specification) for r in results.values()]
|
||||
if any([s is not None for s in sequence_nums]):
|
||||
results = { i : r for i, r in results.items() if r.sequence_num(self.specification) == min(sequence_nums) }
|
||||
results = {i: r for i, r in results.items() if r.sequence_num(self.specification) == min(sequence_nums)}
|
||||
else:
|
||||
results = { i : r for i, r in results.items() if r.matches(min(results.values()), self.specification) }
|
||||
results = {i: r for i, r in results.items() if r.matches(min(results.values()), self.specification)}
|
||||
|
||||
for i in results.keys():
|
||||
indices[i] += 1
|
||||
|
||||
all_results = { i : results[i] if i in results else None for i in range(len(self.tester_results)) }
|
||||
all_results = {i: results[i] if i in results else None for i in range(len(self.tester_results))}
|
||||
result_str = '\n'.join([' %-*s - %s' % (name_length, self.tester_results.keys()[i], r) for i, r in all_results.items()])
|
||||
|
||||
result_list = results.values()
|
||||
|
@ -113,12 +115,15 @@ class ResultSet(object):
|
|||
|
||||
return (num_errors, has_filtered_error)
|
||||
|
||||
|
||||
def choose_api_version(selected_api_version, tester_min_version, tester_max_version, test_min_version, test_max_version):
|
||||
if selected_api_version is not None:
|
||||
if selected_api_version < tester_min_version or selected_api_version > tester_max_version:
|
||||
raise Exception('Not all testers support the API version %d (min=%d, max=%d)' % (selected_api_version, tester_min_version, tester_max_version))
|
||||
raise Exception('Not all testers support the API version %d (min=%d, max=%d)' %
|
||||
(selected_api_version, tester_min_version, tester_max_version))
|
||||
elif selected_api_version < test_min_version or selected_api_version > test_max_version:
|
||||
raise Exception('API version %d is not supported by the specified test (min=%d, max=%d)' % (selected_api_version, test_min_version, test_max_version))
|
||||
raise Exception('API version %d is not supported by the specified test (min=%d, max=%d)' %
|
||||
(selected_api_version, test_min_version, test_max_version))
|
||||
|
||||
api_version = selected_api_version
|
||||
else:
|
||||
|
@ -126,19 +131,23 @@ def choose_api_version(selected_api_version, tester_min_version, tester_max_vers
|
|||
max_version = min(tester_max_version, test_max_version)
|
||||
|
||||
if min_version > max_version:
|
||||
raise Exception('Not all testers support the API versions required by the specified test (tester: min=%d, max=%d; test: min=%d, max=%d)' % (tester_min_version, tester_max_version, test_min_version, test_max_version))
|
||||
raise Exception(
|
||||
'Not all testers support the API versions required by the specified test'
|
||||
'(tester: min=%d, max=%d; test: min=%d, max=%d)' % (tester_min_version, tester_max_version, test_min_version, test_max_version))
|
||||
|
||||
if random.random() < 0.7:
|
||||
api_version = max_version
|
||||
elif random.random() < 0.7:
|
||||
api_version = min_version
|
||||
elif random.random() < 0.9:
|
||||
api_version = random.choice([v for v in [13, 14, 16, 21, 22, 23, 100, 200, 300, 400, 410, 420, 430, 440, 450, 460, 500, 510] if v >= min_version and v <= max_version])
|
||||
api_version = random.choice([v for v in [13, 14, 16, 21, 22, 23, 100, 200, 300, 400, 410, 420, 430,
|
||||
440, 450, 460, 500, 510] if v >= min_version and v <= max_version])
|
||||
else:
|
||||
api_version = random.randint(min_version, max_version)
|
||||
|
||||
return api_version
|
||||
|
||||
|
||||
class TestRunner(object):
|
||||
def __init__(self, args):
|
||||
self.args = copy.copy(args)
|
||||
|
@ -157,7 +166,8 @@ class TestRunner(object):
|
|||
|
||||
min_api_version = max([tester.min_api_version for tester in self.testers])
|
||||
max_api_version = min([tester.max_api_version for tester in self.testers])
|
||||
self.args.api_version = choose_api_version(self.args.api_version, min_api_version, max_api_version, self.test.min_api_version, self.test.max_api_version)
|
||||
self.args.api_version = choose_api_version(self.args.api_version, min_api_version, max_api_version,
|
||||
self.test.min_api_version, self.test.max_api_version)
|
||||
|
||||
util.get_logger().info('\nCreating test at API version %d' % self.args.api_version)
|
||||
|
||||
|
@ -165,7 +175,8 @@ class TestRunner(object):
|
|||
if self.args.max_int_bits is None:
|
||||
self.args.max_int_bits = max_int_bits
|
||||
elif self.args.max_int_bits > max_int_bits:
|
||||
raise Exception('The specified testers support at most %d-bit ints, but --max-int-bits was set to %d' % (max_int_bits, self.args.max_int_bits))
|
||||
raise Exception('The specified testers support at most %d-bit ints, but --max-int-bits was set to %d' %
|
||||
(max_int_bits, self.args.max_int_bits))
|
||||
|
||||
self.args.no_threads = self.args.no_threads or any([not tester.threads_enabled for tester in self.testers])
|
||||
if self.args.no_threads and self.args.concurrency > 1:
|
||||
|
@ -189,15 +200,15 @@ class TestRunner(object):
|
|||
|
||||
for i, instruction in enumerate(instructions):
|
||||
if self.args.print_all or (instruction.operation != 'SWAP' and instruction.operation != 'PUSH'):
|
||||
util.get_logger().error(' %d. %r' % (i+offset, instruction))
|
||||
util.get_logger().error(' %d. %r' % (i + offset, instruction))
|
||||
|
||||
util.get_logger().error('');
|
||||
util.get_logger().error('')
|
||||
|
||||
def run_test(self):
|
||||
test_instructions = self._generate_test()
|
||||
expected_results = self.test.get_expected_results()
|
||||
|
||||
tester_results = { s.subspace : ResultSet(s) for s in self.test.get_result_specifications() }
|
||||
tester_results = {s.subspace: ResultSet(s) for s in self.test.get_result_specifications()}
|
||||
for subspace, results in expected_results.items():
|
||||
tester_results[subspace].add('expected', results)
|
||||
|
||||
|
@ -208,7 +219,8 @@ class TestRunner(object):
|
|||
self.test.pre_run(self.db, self.args)
|
||||
return_code = self._run_tester(tester)
|
||||
if return_code != 0:
|
||||
util.get_logger().error('Test of type %s failed to complete successfully with random seed %d and %d operations\n' % (self.args.test_name, self.args.seed, self.args.num_ops))
|
||||
util.get_logger().error('Test of type %s failed to complete successfully with random seed %d and %d operations\n' %
|
||||
(self.args.test_name, self.args.seed, self.args.num_ops))
|
||||
return 2
|
||||
|
||||
tester_errors[tester] = self.test.validate(self.db, self.args)
|
||||
|
@ -226,18 +238,19 @@ class TestRunner(object):
|
|||
self._insert_instructions(test_instructions)
|
||||
|
||||
def _generate_test(self):
|
||||
util.get_logger().info('Generating %s test at seed %d with %d op(s) and %d concurrent tester(s)...' % (self.args.test_name, self.args.seed, self.args.num_ops, self.args.concurrency))
|
||||
util.get_logger().info('Generating %s test at seed %d with %d op(s) and %d concurrent tester(s)...' %
|
||||
(self.args.test_name, self.args.seed, self.args.num_ops, self.args.concurrency))
|
||||
|
||||
random.seed(self.test_seed)
|
||||
|
||||
if self.args.concurrency == 1:
|
||||
self.test.setup(self.args)
|
||||
test_instructions = { fdb.Subspace((self.args.instruction_prefix,)) : self.test.generate(self.args, 0) }
|
||||
test_instructions = {fdb.Subspace((self.args.instruction_prefix,)): self.test.generate(self.args, 0)}
|
||||
else:
|
||||
test_instructions = {}
|
||||
main_thread = InstructionSet()
|
||||
for i in range(self.args.concurrency):
|
||||
#thread_spec = fdb.Subspace(('thread_spec', i))
|
||||
# thread_spec = fdb.Subspace(('thread_spec', i))
|
||||
thread_spec = 'thread_spec%d' % i
|
||||
main_thread.push_args(thread_spec)
|
||||
main_thread.append('START_THREAD')
|
||||
|
@ -260,7 +273,7 @@ class TestRunner(object):
|
|||
params += [self.args.cluster_file]
|
||||
|
||||
util.get_logger().info('\nRunning tester \'%s\'...' % ' '.join(params))
|
||||
sys.stdout.flush();
|
||||
sys.stdout.flush()
|
||||
proc = subprocess.Popen(params)
|
||||
timed_out = Event()
|
||||
|
||||
|
@ -321,9 +334,10 @@ class TestRunner(object):
|
|||
if len(errors) > 0:
|
||||
util.get_logger().error('The %s tester reported errors:\n' % tester.name)
|
||||
for i, error in enumerate(errors):
|
||||
util.get_logger().error(' %d. %s' % (i+1, error))
|
||||
util.get_logger().error(' %d. %s' % (i + 1, error))
|
||||
|
||||
log_message = '\nTest with seed %d and concurrency %d had %d incorrect result(s) and %d error(s) at API version %d' % (self.args.seed, self.args.concurrency, num_incorrect, num_errors, self.args.api_version)
|
||||
log_message = '\nTest with seed %d and concurrency %d had %d incorrect result(s) and %d error(s) at API version %d' %\
|
||||
(self.args.seed, self.args.concurrency, num_incorrect, num_errors, self.args.api_version)
|
||||
if num_errors == 0 and (num_incorrect == 0 or has_filtered_error):
|
||||
util.get_logger().info(log_message)
|
||||
if has_filtered_error:
|
||||
|
@ -333,6 +347,7 @@ class TestRunner(object):
|
|||
util.get_logger().error(log_message)
|
||||
return 1
|
||||
|
||||
|
||||
def bisect(test_runner, args):
|
||||
util.get_logger().info('')
|
||||
|
||||
|
@ -354,7 +369,8 @@ def bisect(test_runner, args):
|
|||
util.get_logger().error('Error finding minimal failing test for seed %d. The failure may not be deterministic' % args.seed)
|
||||
return 1
|
||||
else:
|
||||
util.get_logger().error('No failing test found for seed %d with %d ops. Try specifying a larger --num-ops parameter.' % (args.seed, args.num_ops))
|
||||
util.get_logger().error('No failing test found for seed %d with %d ops. Try specifying a larger --num-ops parameter.'
|
||||
% (args.seed, args.num_ops))
|
||||
return 0
|
||||
|
||||
elif result == 0:
|
||||
|
@ -365,30 +381,45 @@ def bisect(test_runner, args):
|
|||
util.get_logger().info('Test with %d operations failed with error code %d\n' % (test_runner.args.num_ops, result))
|
||||
upper_bound = test_runner.args.num_ops
|
||||
|
||||
|
||||
def parse_args(argv):
|
||||
parser = argparse.ArgumentParser(description='FoundationDB Binding API Tester')
|
||||
parser.add_argument('--test-name', default='scripted', help='The name of the test to run. Must be the name of a test specified in the tests folder. (default=\'scripted\')')
|
||||
parser.add_argument('--test-name', default='scripted',
|
||||
help='The name of the test to run. Must be the name of a test specified in the tests folder. (default=\'scripted\')')
|
||||
|
||||
parser.add_argument(metavar='tester1', dest='test1', help='Name of the first tester to invoke')
|
||||
parser.add_argument('--compare', metavar='tester2', nargs='?', type=str, default=None, const='python', dest='test2', help='When specified, a second tester will be run and compared against the first. This flag takes an optional argument for the second tester to invoke (default = \'python\').')
|
||||
|
||||
parser.add_argument('--print-test', action='store_true', help='Instead of running a test, prints the set of instructions generated for that test. Unless --all is specified, all setup, finalization, PUSH, and SWAP instructions will be excluded.')
|
||||
parser.add_argument('--compare', metavar='tester2', nargs='?', type=str, default=None, const='python', dest='test2',
|
||||
help='When specified, a second tester will be run and compared against the first. This flag takes an optional argument '
|
||||
'for the second tester to invoke (default = \'python\').')
|
||||
parser.add_argument('--print-test', action='store_true',
|
||||
help='Instead of running a test, prints the set of instructions generated for that test. Unless --all is specified, all '
|
||||
'setup, finalization, PUSH, and SWAP instructions will be excluded.')
|
||||
parser.add_argument('--all', dest='print_all', action='store_true', help='Causes --print-test to print all instructions.')
|
||||
parser.add_argument('--bisect', action='store_true', help='Run the specified test varying the number of operations until a minimal failing test is found. Does not work for concurrent tests.')
|
||||
parser.add_argument('--bisect', action='store_true',
|
||||
help='Run the specified test varying the number of operations until a minimal failing test is found. Does not work for '
|
||||
'concurrent tests.')
|
||||
parser.add_argument('--insert-only', action='store_true', help='Insert the test instructions into the database, but do not run it.')
|
||||
|
||||
parser.add_argument('--concurrency', type=int, default=1, help='Number of concurrent test threads to run. (default = 1).')
|
||||
parser.add_argument('--num-ops', type=int, default=100, help='The number of operations to generate per thread (default = 100)')
|
||||
parser.add_argument('--seed', type=int, help='The random seed to use for generating the test')
|
||||
parser.add_argument('--max-int-bits', type=int, default=None, help='Maximum number of bits to use for int types in testers. By default, the largest value supported by the testers being run will be chosen.')
|
||||
parser.add_argument('--api-version', default=None, type=int, help='The API version that the testers should use. Not supported in scripted mode. (default = random version supported by all testers)')
|
||||
parser.add_argument('--max-int-bits', type=int, default=None,
|
||||
help='Maximum number of bits to use for int types in testers. By default, the largest value supported by the testers being '
|
||||
'run will be chosen.')
|
||||
parser.add_argument('--api-version', default=None, type=int,
|
||||
help='The API version that the testers should use. Not supported in scripted mode. (default = random version supported by '
|
||||
'all testers)')
|
||||
parser.add_argument('--cluster-file', type=str, default=None, help='The cluster file for the cluster being connected to. (default None)')
|
||||
parser.add_argument('--timeout', type=int, default=600, help='The timeout in seconds for running each individual tester. (default 600)')
|
||||
parser.add_argument('--enable-client-trace-logging', nargs='?', type=str, default=None, const='.', help='Enables trace file output. This flag takes an optional argument specifying the output directory (default = \'.\').')
|
||||
parser.add_argument('--instruction-prefix', type=str, default='test_spec', help='The prefix under which the main thread of test instructions are inserted (default=\'test_spec\').')
|
||||
parser.add_argument('--output-subspace', type=str, default='tester_output', help='The string used to create the output subspace for the testers. The subspace will be of the form (<output_subspace>,). (default=\'tester_output\')')
|
||||
parser.add_argument('--enable-client-trace-logging', nargs='?', type=str, default=None, const='.',
|
||||
help='Enables trace file output. This flag takes an optional argument specifying the output directory (default = \'.\').')
|
||||
parser.add_argument('--instruction-prefix', type=str, default='test_spec',
|
||||
help='The prefix under which the main thread of test instructions are inserted (default=\'test_spec\').')
|
||||
parser.add_argument('--output-subspace', type=str, default='tester_output',
|
||||
help='The string used to create the output subspace for the testers. The subspace will be of the form (<output_subspace>,). '
|
||||
'(default=\'tester_output\')')
|
||||
|
||||
parser.add_argument('--logging-level', type=str, default='INFO', choices=['ERROR', 'WARNING', 'INFO', 'DEBUG'], help='Specifies the level of detail in the tester output (default=\'INFO\').')
|
||||
parser.add_argument('--logging-level', type=str, default='INFO',
|
||||
choices=['ERROR', 'WARNING', 'INFO', 'DEBUG'], help='Specifies the level of detail in the tester output (default=\'INFO\').')
|
||||
|
||||
# SOMEDAY: this applies only to the scripted test. Should we invoke test files specifically (as in circus),
|
||||
# or invoke them here and allow tests to add arguments?
|
||||
|
@ -396,6 +427,7 @@ def parse_args(argv):
|
|||
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
def validate_args(args):
|
||||
if args.insert_only and args.bisect:
|
||||
raise Exception('--bisect cannot be used with --insert-only')
|
||||
|
@ -408,6 +440,7 @@ def validate_args(args):
|
|||
if args.concurrency > 1 and args.test2:
|
||||
raise Exception('--compare cannot be used with concurrent tests')
|
||||
|
||||
|
||||
def main(argv):
|
||||
args = parse_args(argv)
|
||||
try:
|
||||
|
@ -444,9 +477,11 @@ def main(argv):
|
|||
util.get_logger().debug(traceback.format_exc())
|
||||
exit(3)
|
||||
|
||||
except:
|
||||
except BaseException:
|
||||
util.get_logger().error('\nERROR: %s' % sys.exc_info()[0])
|
||||
util.get_logger().info(traceback.format_exc())
|
||||
exit(3)
|
||||
|
||||
if __name__ == '__main__': sys.exit(main(sys.argv[1:]))
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -21,8 +21,9 @@
|
|||
import os
|
||||
|
||||
MAX_API_VERSION = 510
|
||||
COMMON_TYPES = [ 'null', 'bytes', 'string', 'int', 'uuid', 'bool', 'float', 'double', 'tuple' ]
|
||||
ALL_TYPES = COMMON_TYPES + [ 'versionstamp' ]
|
||||
COMMON_TYPES = ['null', 'bytes', 'string', 'int', 'uuid', 'bool', 'float', 'double', 'tuple']
|
||||
ALL_TYPES = COMMON_TYPES + ['versionstamp']
|
||||
|
||||
|
||||
class Tester:
|
||||
def __init__(self, name, cmd, max_int_bits=64, min_api_version=0, max_api_version=MAX_API_VERSION, threads_enabled=True, types=COMMON_TYPES):
|
||||
|
@ -44,22 +45,24 @@ class Tester:
|
|||
else:
|
||||
return Tester(test_name_or_args.split(' ')[0], test_name_or_args)
|
||||
|
||||
|
||||
def _absolute_path(path):
|
||||
return os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', path)
|
||||
|
||||
|
||||
_java_cmd = 'java -ea -cp %s:%s com.apple.foundationdb.test.' % (
|
||||
_absolute_path('java/foundationdb-client.jar'),
|
||||
_absolute_path('java/foundationdb-tests.jar'))
|
||||
_absolute_path('java/foundationdb-client.jar'),
|
||||
_absolute_path('java/foundationdb-tests.jar'))
|
||||
|
||||
# We could set min_api_version lower on some of these if the testers were updated to support them
|
||||
testers = {
|
||||
'python' : Tester('python', 'python ' + _absolute_path('python/tests/tester.py'), 2040, 23, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'python3' : Tester('python3', 'python3 ' + _absolute_path('python/tests/tester.py'), 2040, 23, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'node' : Tester('node', _absolute_path('nodejs/tests/tester.js'), 53, 500, MAX_API_VERSION),
|
||||
'streamline' : Tester('streamline', _absolute_path('nodejs/tests/streamline_tester._js'), 53, 500, MAX_API_VERSION),
|
||||
'ruby' : Tester('ruby', _absolute_path('ruby/tests/tester.rb'), 64, 23, MAX_API_VERSION),
|
||||
'java' : Tester('java', _java_cmd + 'StackTester', 2040, 510, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'java_async' : Tester('java', _java_cmd + 'AsyncStackTester', 2040, 510, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'go' : Tester('go', _absolute_path('go/build/bin/_stacktester'), 63, 200, MAX_API_VERSION),
|
||||
'flow' : Tester('flow', _absolute_path('flow/bin/fdb_flow_tester'), 63, 500, MAX_API_VERSION),
|
||||
'python': Tester('python', 'python ' + _absolute_path('python/tests/tester.py'), 2040, 23, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'python3': Tester('python3', 'python3 ' + _absolute_path('python/tests/tester.py'), 2040, 23, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'node': Tester('node', _absolute_path('nodejs/tests/tester.js'), 53, 500, MAX_API_VERSION),
|
||||
'streamline': Tester('streamline', _absolute_path('nodejs/tests/streamline_tester._js'), 53, 500, MAX_API_VERSION),
|
||||
'ruby': Tester('ruby', _absolute_path('ruby/tests/tester.rb'), 64, 23, MAX_API_VERSION),
|
||||
'java': Tester('java', _java_cmd + 'StackTester', 2040, 510, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'java_async': Tester('java', _java_cmd + 'AsyncStackTester', 2040, 510, MAX_API_VERSION, types=ALL_TYPES),
|
||||
'go': Tester('go', _absolute_path('go/build/bin/_stacktester'), 63, 200, MAX_API_VERSION),
|
||||
'flow': Tester('flow', _absolute_path('flow/bin/fdb_flow_tester'), 63, 500, MAX_API_VERSION),
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -28,11 +28,12 @@ from bindingtester import util
|
|||
|
||||
fdb.api_version(FDB_API_VERSION)
|
||||
|
||||
|
||||
class ResultSpecification(object):
|
||||
def __init__(self, subspace, key_start_index=0, ordering_index=None, global_error_filter=None):
|
||||
self.subspace = subspace
|
||||
self.key_start_index = key_start_index
|
||||
self.ordering_index = ordering_index
|
||||
self.ordering_index = ordering_index
|
||||
|
||||
if global_error_filter is not None:
|
||||
error_str = '|'.join(['%d' % e for e in global_error_filter])
|
||||
|
@ -45,7 +46,7 @@ class ResultSpecification(object):
|
|||
return False
|
||||
|
||||
return self.error_regex.search(str) is not None
|
||||
|
||||
|
||||
|
||||
class Test(object):
|
||||
def __init__(self, subspace, min_api_version=0, max_api_version=int(1e9)):
|
||||
|
@ -54,7 +55,7 @@ class Test(object):
|
|||
self.max_api_version = max_api_version
|
||||
|
||||
# Returns nothing
|
||||
def setup(self, args):
|
||||
def setup(self, args):
|
||||
pass
|
||||
|
||||
# Returns an instance of TestInstructions
|
||||
|
@ -75,7 +76,7 @@ class Test(object):
|
|||
def get_expected_results(self):
|
||||
return {}
|
||||
|
||||
# Returns a list of error strings
|
||||
# Returns a list of error strings
|
||||
def validate(self, db, args):
|
||||
return []
|
||||
|
||||
|
@ -88,6 +89,7 @@ class Test(object):
|
|||
|
||||
return test_class[0](subspace)
|
||||
|
||||
|
||||
class Instruction(object):
|
||||
def __init__(self, operation):
|
||||
self.operation = operation
|
||||
|
@ -103,6 +105,7 @@ class Instruction(object):
|
|||
def __repr__(self):
|
||||
return repr(self.operation)
|
||||
|
||||
|
||||
class PushInstruction(Instruction):
|
||||
def __init__(self, argument):
|
||||
self.operation = 'PUSH'
|
||||
|
@ -115,6 +118,7 @@ class PushInstruction(Instruction):
|
|||
def __repr__(self):
|
||||
return '%r %r' % (self.operation, self.argument)
|
||||
|
||||
|
||||
class TestInstructions(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
@ -126,13 +130,14 @@ class TestInstructions(object):
|
|||
def insert_operations(self, db, subspace):
|
||||
pass
|
||||
|
||||
|
||||
class InstructionSet(TestInstructions, list):
|
||||
def __init__(self):
|
||||
TestInstructions.__init__(self)
|
||||
list.__init__(self)
|
||||
|
||||
self.core_test_begin = 0
|
||||
self.core_test_end = None
|
||||
self.core_test_end = None
|
||||
|
||||
def push_args(self, *args):
|
||||
self.extend([PushInstruction(arg) for arg in reversed(args)])
|
||||
|
@ -144,7 +149,7 @@ class InstructionSet(TestInstructions, list):
|
|||
list.append(self, Instruction(instruction))
|
||||
|
||||
def get_threads(self, subspace):
|
||||
return { subspace : self }
|
||||
return {subspace: self}
|
||||
|
||||
def setup_complete(self):
|
||||
self.core_test_begin = len(self)
|
||||
|
@ -153,16 +158,17 @@ class InstructionSet(TestInstructions, list):
|
|||
self.core_test_end = len(self)
|
||||
|
||||
def core_instructions(self):
|
||||
return self[self.core_test_begin : self.core_test_end]
|
||||
|
||||
return self[self.core_test_begin: self.core_test_end]
|
||||
|
||||
@fdb.transactional
|
||||
def _insert_operations_transactional(self, tr, subspace, start, count):
|
||||
for i, instruction in enumerate(self[start : start+count]):
|
||||
for i, instruction in enumerate(self[start: start + count]):
|
||||
tr[subspace.pack((start + i,))] = instruction.to_value()
|
||||
|
||||
def insert_operations(self, db, subspace):
|
||||
for i in range(0, int(math.ceil(len(self) / 1000.0))):
|
||||
self._insert_operations_transactional(db, subspace, i*1000, 1000)
|
||||
self._insert_operations_transactional(db, subspace, i * 1000, 1000)
|
||||
|
||||
|
||||
class ThreadedInstructionSet(TestInstructions):
|
||||
def __init__(self):
|
||||
|
@ -194,4 +200,5 @@ class ThreadedInstructionSet(TestInstructions):
|
|||
self.threads[subspace] = thread_instructions
|
||||
return thread_instructions
|
||||
|
||||
|
||||
util.import_subclasses(__file__, 'bindingtester.tests')
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -32,11 +32,12 @@ from bindingtester.tests import test_util
|
|||
|
||||
fdb.api_version(FDB_API_VERSION)
|
||||
|
||||
|
||||
class ApiTest(Test):
|
||||
def __init__(self, subspace):
|
||||
super(ApiTest, self).__init__(subspace)
|
||||
self.workspace = self.subspace['workspace'] # The keys and values here must match between subsequent runs of the same test
|
||||
self.scratch = self.subspace['scratch'] # The keys and values here can differ between runs
|
||||
self.workspace = self.subspace['workspace'] # The keys and values here must match between subsequent runs of the same test
|
||||
self.scratch = self.subspace['scratch'] # The keys and values here can differ between runs
|
||||
self.stack_subspace = self.subspace['stack']
|
||||
|
||||
self.versionstamped_values = self.scratch['versionstamped_values']
|
||||
|
@ -78,7 +79,7 @@ class ApiTest(Test):
|
|||
self.key_depth = max(0, self.key_depth - num)
|
||||
|
||||
self.outstanding_ops = [i for i in self.outstanding_ops if i[0] <= self.stack_size]
|
||||
|
||||
|
||||
def ensure_string(self, instructions, num):
|
||||
while self.string_depth < num:
|
||||
instructions.push_args(self.random.random_string(random.randint(0, 100)))
|
||||
|
@ -97,7 +98,7 @@ class ApiTest(Test):
|
|||
tup = self.random.random_tuple(5)
|
||||
self.generated_keys.append(tup)
|
||||
|
||||
return self.workspace.pack(tup)
|
||||
return self.workspace.pack(tup)
|
||||
|
||||
def ensure_key(self, instructions, num):
|
||||
while self.key_depth < num:
|
||||
|
@ -131,7 +132,7 @@ class ApiTest(Test):
|
|||
def wait_for_reads(self, instructions):
|
||||
while len(self.outstanding_ops) > 0 and self.outstanding_ops[-1][0] <= self.stack_size:
|
||||
read = self.outstanding_ops.pop()
|
||||
#print '%d. waiting for read at instruction %r' % (len(instructions), read)
|
||||
# print '%d. waiting for read at instruction %r' % (len(instructions), read)
|
||||
test_util.to_front(instructions, self.stack_size - read[0])
|
||||
instructions.append('WAIT_FUTURE')
|
||||
|
||||
|
@ -187,7 +188,7 @@ class ApiTest(Test):
|
|||
index = len(instructions)
|
||||
read_performed = False
|
||||
|
||||
#print 'Adding instruction %s at %d' % (op, index)
|
||||
# print 'Adding instruction %s at %d' % (op, index)
|
||||
|
||||
if args.concurrency == 1 and (op in database_mutations):
|
||||
self.wait_for_reads(instructions)
|
||||
|
@ -211,7 +212,7 @@ class ApiTest(Test):
|
|||
instructions.push_args(random.randint(0, 5000))
|
||||
instructions.append(op)
|
||||
|
||||
self.outstanding_ops.append((self.stack_size, len(instructions)-1))
|
||||
self.outstanding_ops.append((self.stack_size, len(instructions) - 1))
|
||||
if args.concurrency == 1:
|
||||
self.wait_for_reads(instructions)
|
||||
|
||||
|
@ -236,7 +237,7 @@ class ApiTest(Test):
|
|||
test_util.to_front(instructions, 3)
|
||||
instructions.append(op)
|
||||
|
||||
#Don't add key here because we may be outside of our prefix
|
||||
# Don't add key here because we may be outside of our prefix
|
||||
self.add_strings(1)
|
||||
self.can_set_version = False
|
||||
read_performed = True
|
||||
|
@ -249,7 +250,7 @@ class ApiTest(Test):
|
|||
test_util.to_front(instructions, 4)
|
||||
instructions.append(op)
|
||||
|
||||
if range_params[0] >= 1 and range_params[0] <= 1000: # avoid adding a string if the limit is large
|
||||
if range_params[0] >= 1 and range_params[0] <= 1000: # avoid adding a string if the limit is large
|
||||
self.add_strings(1)
|
||||
else:
|
||||
self.add_stack_items(1)
|
||||
|
@ -258,14 +259,14 @@ class ApiTest(Test):
|
|||
read_performed = True
|
||||
|
||||
elif op == 'GET_RANGE_STARTS_WITH' or op == 'GET_RANGE_STARTS_WITH_SNAPSHOT' or op == 'GET_RANGE_STARTS_WITH_DATABASE':
|
||||
#TODO: not tested well
|
||||
# TODO: not tested well
|
||||
self.ensure_key(instructions, 1)
|
||||
range_params = self.random.random_range_params()
|
||||
instructions.push_args(*range_params)
|
||||
test_util.to_front(instructions, 3)
|
||||
instructions.append(op)
|
||||
|
||||
if range_params[0] >= 1 and range_params[0] <= 1000: # avoid adding a string if the limit is large
|
||||
if range_params[0] >= 1 and range_params[0] <= 1000: # avoid adding a string if the limit is large
|
||||
self.add_strings(1)
|
||||
else:
|
||||
self.add_stack_items(1)
|
||||
|
@ -285,7 +286,7 @@ class ApiTest(Test):
|
|||
test_util.to_front(instructions, 9)
|
||||
instructions.append(op)
|
||||
|
||||
if range_params[0] >= 1 and range_params[0] <= 1000: # avoid adding a string if the limit is large
|
||||
if range_params[0] >= 1 and range_params[0] <= 1000: # avoid adding a string if the limit is large
|
||||
self.add_strings(1)
|
||||
else:
|
||||
self.add_stack_items(1)
|
||||
|
@ -302,8 +303,8 @@ class ApiTest(Test):
|
|||
self.ensure_key_value(instructions)
|
||||
instructions.append(op)
|
||||
if op == 'SET_DATABASE':
|
||||
self.add_stack_items(1)
|
||||
|
||||
self.add_stack_items(1)
|
||||
|
||||
elif op == 'SET_READ_VERSION':
|
||||
if self.has_version and self.can_set_version:
|
||||
instructions.append(op)
|
||||
|
@ -316,7 +317,7 @@ class ApiTest(Test):
|
|||
self.add_stack_items(1)
|
||||
|
||||
elif op == 'CLEAR_RANGE' or op == 'CLEAR_RANGE_DATABASE':
|
||||
#Protect against inverted range
|
||||
# Protect against inverted range
|
||||
key1 = self.workspace.pack(self.random.random_tuple(5))
|
||||
key2 = self.workspace.pack(self.random.random_tuple(5))
|
||||
|
||||
|
@ -334,7 +335,7 @@ class ApiTest(Test):
|
|||
instructions.append(op)
|
||||
if op == 'CLEAR_RANGE_STARTS_WITH_DATABASE':
|
||||
self.add_stack_items(1)
|
||||
|
||||
|
||||
elif op == 'ATOMIC_OP' or op == 'ATOMIC_OP_DATABASE':
|
||||
self.ensure_key_value(instructions)
|
||||
if op == 'ATOMIC_OP' or args.concurrency > 1:
|
||||
|
@ -351,10 +352,10 @@ class ApiTest(Test):
|
|||
key1 = self.versionstamped_values.pack((rand_str1,))
|
||||
|
||||
split = random.randint(0, 70)
|
||||
rand_str2 = self.random.random_string(20+split) + fdb.tuple.Versionstamp._UNSET_TR_VERSION + self.random.random_string(70-split)
|
||||
rand_str2 = self.random.random_string(20 + split) + fdb.tuple.Versionstamp._UNSET_TR_VERSION + self.random.random_string(70 - split)
|
||||
key2 = self.versionstamped_keys.pack() + rand_str2
|
||||
index = key2.find(fdb.tuple.Versionstamp._UNSET_TR_VERSION)
|
||||
key2 += chr(index%256)+chr(index/256)
|
||||
key2 += chr(index % 256) + chr(index / 256)
|
||||
|
||||
instructions.push_args(u'SET_VERSIONSTAMPED_VALUE', key1, fdb.tuple.Versionstamp._UNSET_TR_VERSION + rand_str2)
|
||||
instructions.append('ATOMIC_OP')
|
||||
|
@ -436,8 +437,8 @@ class ApiTest(Test):
|
|||
|
||||
version_key = self.versionstamped_keys.pack(tup)
|
||||
first_incomplete = version_key.find(fdb.tuple.Versionstamp._UNSET_TR_VERSION)
|
||||
second_incomplete = -1 if first_incomplete < 0 else version_key.find(fdb.tuple.Versionstamp._UNSET_TR_VERSION,
|
||||
first_incomplete + len(fdb.tuple.Versionstamp._UNSET_TR_VERSION) + 1)
|
||||
second_incomplete = -1 if first_incomplete < 0 else \
|
||||
version_key.find(fdb.tuple.Versionstamp._UNSET_TR_VERSION, first_incomplete + len(fdb.tuple.Versionstamp._UNSET_TR_VERSION) + 1)
|
||||
|
||||
# If there is exactly one incomplete versionstamp, perform the versionstamped key operation.
|
||||
if first_incomplete >= 0 and second_incomplete < 0:
|
||||
|
@ -449,7 +450,8 @@ class ApiTest(Test):
|
|||
instructions.append('ATOMIC_OP')
|
||||
|
||||
version_value_key = self.versionstamped_values.pack((rand_str,))
|
||||
instructions.push_args(u'SET_VERSIONSTAMPED_VALUE', version_value_key, fdb.tuple.Versionstamp._UNSET_TR_VERSION + fdb.tuple.pack(tup))
|
||||
instructions.push_args(u'SET_VERSIONSTAMPED_VALUE', version_value_key,
|
||||
fdb.tuple.Versionstamp._UNSET_TR_VERSION + fdb.tuple.pack(tup))
|
||||
instructions.append('ATOMIC_OP')
|
||||
self.can_use_key_selectors = False
|
||||
|
||||
|
@ -469,7 +471,7 @@ class ApiTest(Test):
|
|||
instructions.append(op)
|
||||
self.add_strings(len(tups))
|
||||
|
||||
#Use SUB to test if integers are correctly unpacked
|
||||
# Use SUB to test if integers are correctly unpacked
|
||||
elif op == 'SUB':
|
||||
a = self.random.random_int() / 2
|
||||
b = self.random.random_int() / 2
|
||||
|
@ -512,7 +514,7 @@ class ApiTest(Test):
|
|||
assert False
|
||||
|
||||
if read_performed and op not in database_reads:
|
||||
self.outstanding_ops.append((self.stack_size, len(instructions)-1))
|
||||
self.outstanding_ops.append((self.stack_size, len(instructions) - 1))
|
||||
|
||||
if args.concurrency == 1 and (op in database_reads or op in database_mutations):
|
||||
instructions.append('WAIT_FUTURE')
|
||||
|
@ -536,7 +538,7 @@ class ApiTest(Test):
|
|||
def check_versionstamps(self, tr, begin_key, limit):
|
||||
next_begin = None
|
||||
incorrect_versionstamps = 0
|
||||
for k,v in tr.get_range(begin_key, self.versionstamped_values.range().stop, limit=limit):
|
||||
for k, v in tr.get_range(begin_key, self.versionstamped_values.range().stop, limit=limit):
|
||||
next_begin = k + '\x00'
|
||||
tup = fdb.tuple.unpack(k)
|
||||
key = self.versionstamped_keys.pack() + v[10:].replace(fdb.tuple.Versionstamp._UNSET_TR_VERSION, v[:10], 1)
|
||||
|
@ -545,7 +547,6 @@ class ApiTest(Test):
|
|||
util.get_logger().error(' %s != %s', repr(tr[key]), repr(tup[-1]))
|
||||
incorrect_versionstamps += 1
|
||||
|
||||
|
||||
return (next_begin, incorrect_versionstamps)
|
||||
|
||||
def validate(self, db, args):
|
||||
|
@ -564,8 +565,7 @@ class ApiTest(Test):
|
|||
return errors
|
||||
|
||||
def get_result_specifications(self):
|
||||
return [
|
||||
ResultSpecification(self.workspace, global_error_filter=[1007, 1021]),
|
||||
ResultSpecification(self.stack_subspace, key_start_index=1, ordering_index=1, global_error_filter=[1007, 1021])
|
||||
return [
|
||||
ResultSpecification(self.workspace, global_error_filter=[1007, 1021]),
|
||||
ResultSpecification(self.stack_subspace, key_start_index=1, ordering_index=1, global_error_filter=[1007, 1021])
|
||||
]
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -32,6 +32,7 @@ from bindingtester.tests.directory_util import DirListEntry
|
|||
|
||||
fdb.api_version(FDB_API_VERSION)
|
||||
|
||||
|
||||
class DirectoryTest(Test):
|
||||
|
||||
def __init__(self, subspace):
|
||||
|
@ -71,12 +72,12 @@ class DirectoryTest(Test):
|
|||
instructions = InstructionSet()
|
||||
|
||||
op_choices = ['NEW_TRANSACTION', 'COMMIT']
|
||||
|
||||
|
||||
general = ['DIRECTORY_CREATE_SUBSPACE', 'DIRECTORY_CREATE_LAYER']
|
||||
|
||||
op_choices += general
|
||||
|
||||
directory_mutations = ['DIRECTORY_CREATE_OR_OPEN', 'DIRECTORY_CREATE', 'DIRECTORY_MOVE', 'DIRECTORY_MOVE_TO',
|
||||
directory_mutations = ['DIRECTORY_CREATE_OR_OPEN', 'DIRECTORY_CREATE', 'DIRECTORY_MOVE', 'DIRECTORY_MOVE_TO',
|
||||
'DIRECTORY_REMOVE', 'DIRECTORY_REMOVE_IF_EXISTS']
|
||||
directory_reads = ['DIRECTORY_EXISTS', 'DIRECTORY_OPEN', 'DIRECTORY_LIST']
|
||||
|
||||
|
@ -105,17 +106,18 @@ class DirectoryTest(Test):
|
|||
|
||||
# Generate some directories that we are going to create in advance. This tests that other bindings
|
||||
# are compatible with the Python implementation
|
||||
self.prepopulated_dirs = [ (generate_path(min_length=1), self.generate_layer()) for i in range(5) ]
|
||||
self.prepopulated_dirs = [(generate_path(min_length=1), self.generate_layer()) for i in range(5)]
|
||||
|
||||
for path, layer in self.prepopulated_dirs:
|
||||
instructions.push_args(layer)
|
||||
instructions.push_args(*test_util.with_length(path))
|
||||
instructions.append('DIRECTORY_OPEN')
|
||||
#print '%d. Selected %s, dir=%s, has_known_prefix=%s, dir_list_len=%d' % (len(instructions), 'DIRECTORY_OPEN', repr(self.dir_index), False, len(self.dir_list))
|
||||
# print '%d. Selected %s, dir=%s, has_known_prefix=%s, dir_list_len=%d' \
|
||||
# % (len(instructions), 'DIRECTORY_OPEN', repr(self.dir_index), False, len(self.dir_list))
|
||||
self.dir_list.append(self.dir_list[0].add_child(path, default_path, self.root, DirListEntry(True, True, has_known_prefix=False)))
|
||||
|
||||
instructions.setup_complete()
|
||||
|
||||
|
||||
for i in range(args.num_ops):
|
||||
if random.random() < 0.5:
|
||||
self.dir_index = random.randrange(0, len(self.dir_list))
|
||||
|
@ -131,7 +133,8 @@ class DirectoryTest(Test):
|
|||
op = random.choice(choices)
|
||||
dir_entry = self.dir_list[self.dir_index]
|
||||
|
||||
#print '%d. Selected %s, dir=%s, has_known_prefix=%s, dir_list_len=%d' % (len(instructions), op, repr(self.dir_index), repr(dir_entry.has_known_prefix), len(self.dir_list))
|
||||
# print '%d. Selected %s, dir=%s, has_known_prefix=%s, dir_list_len=%d' \
|
||||
# % (len(instructions), op, repr(self.dir_index), repr(dir_entry.has_known_prefix), len(self.dir_list))
|
||||
|
||||
if op.endswith('_DATABASE') or op.endswith('_SNAPSHOT'):
|
||||
root_op = op[0:-9]
|
||||
|
@ -160,7 +163,7 @@ class DirectoryTest(Test):
|
|||
indices.append(len(self.dir_list))
|
||||
self.dir_list.append(DirListEntry(False, True))
|
||||
|
||||
instructions.push_args(random.choice([0,1]))
|
||||
instructions.push_args(random.choice([0, 1]))
|
||||
instructions.push_args(*indices)
|
||||
instructions.append(op)
|
||||
self.dir_list.append(DirListEntry(True, False, False))
|
||||
|
@ -172,7 +175,7 @@ class DirectoryTest(Test):
|
|||
test_util.blocking_commit(instructions)
|
||||
|
||||
path = generate_path()
|
||||
op_args = test_util.with_length(path) + (self.generate_layer(),)
|
||||
op_args = test_util.with_length(path) + (self.generate_layer(),)
|
||||
directory_util.push_instruction_and_record_prefix(instructions, op, op_args, path, len(self.dir_list), self.random, self.prefix_log)
|
||||
|
||||
if not op.endswith('_DATABASE') and args.concurrency == 1:
|
||||
|
@ -189,18 +192,19 @@ class DirectoryTest(Test):
|
|||
|
||||
# Because allocated prefixes are non-deterministic, we cannot have overlapping
|
||||
# transactions that allocate/remove these prefixes in a comparison test
|
||||
if op.endswith('_DATABASE') and args.concurrency == 1: # and allow_empty_prefix:
|
||||
if op.endswith('_DATABASE') and args.concurrency == 1: # and allow_empty_prefix:
|
||||
test_util.blocking_commit(instructions)
|
||||
|
||||
path = generate_path()
|
||||
op_args = test_util.with_length(path) + (layer, prefix)
|
||||
op_args = test_util.with_length(path) + (layer, prefix)
|
||||
if prefix is None:
|
||||
directory_util.push_instruction_and_record_prefix(instructions, op, op_args, path, len(self.dir_list), self.random, self.prefix_log)
|
||||
directory_util.push_instruction_and_record_prefix(
|
||||
instructions, op, op_args, path, len(self.dir_list), self.random, self.prefix_log)
|
||||
else:
|
||||
instructions.push_args(*op_args)
|
||||
instructions.append(op)
|
||||
|
||||
if not op.endswith('_DATABASE') and args.concurrency == 1: # and allow_empty_prefix:
|
||||
if not op.endswith('_DATABASE') and args.concurrency == 1: # and allow_empty_prefix:
|
||||
test_util.blocking_commit(instructions)
|
||||
|
||||
self.dir_list.append(dir_entry.add_child(path, default_path, self.root, DirListEntry(True, True, bool(prefix))))
|
||||
|
@ -228,13 +232,14 @@ class DirectoryTest(Test):
|
|||
new_path = generate_path()
|
||||
instructions.push_args(*test_util.with_length(new_path))
|
||||
instructions.append(op)
|
||||
self.dir_list.append(dir_entry.root.add_child(new_path, default_path, self.root, DirListEntry(True, True, dir_entry.has_known_prefix)))
|
||||
self.dir_list.append(dir_entry.root.add_child(new_path, default_path, self.root,
|
||||
DirListEntry(True, True, dir_entry.has_known_prefix)))
|
||||
|
||||
# Make sure that the default directory subspace still exists after moving the current directory
|
||||
self.ensure_default_directory_subspace(instructions, default_path)
|
||||
|
||||
# FIXME: There is currently a problem with removing partitions. In these generated tests, it's possible
|
||||
# for a removed partition to resurrect itself and insert keys into the database using its allocated
|
||||
# for a removed partition to resurrect itself and insert keys into the database using its allocated
|
||||
# prefix. The result is non-deterministic HCA errors.
|
||||
elif root_op == 'DIRECTORY_REMOVE' or root_op == 'DIRECTORY_REMOVE_IF_EXISTS':
|
||||
# Because allocated prefixes are non-deterministic, we cannot have overlapping
|
||||
|
@ -242,7 +247,7 @@ class DirectoryTest(Test):
|
|||
if op.endswith('_DATABASE') and args.concurrency == 1:
|
||||
test_util.blocking_commit(instructions)
|
||||
|
||||
path = ()
|
||||
path = ()
|
||||
count = random.randint(0, 1)
|
||||
if count == 1:
|
||||
path = generate_path()
|
||||
|
@ -256,14 +261,14 @@ class DirectoryTest(Test):
|
|||
self.ensure_default_directory_subspace(instructions, default_path)
|
||||
|
||||
elif root_op == 'DIRECTORY_LIST' or root_op == 'DIRECTORY_EXISTS':
|
||||
path = ()
|
||||
path = ()
|
||||
count = random.randint(0, 1)
|
||||
if count == 1:
|
||||
path = generate_path()
|
||||
instructions.push_args(*test_util.with_length(path))
|
||||
instructions.push_args(count)
|
||||
instructions.append(op)
|
||||
|
||||
|
||||
elif root_op == 'DIRECTORY_PACK_KEY':
|
||||
t = self.random.random_tuple(5)
|
||||
instructions.push_args(*test_util.with_length(t))
|
||||
|
@ -305,10 +310,10 @@ class DirectoryTest(Test):
|
|||
instructions.push_args(self.directory_log.key())
|
||||
instructions.append('DIRECTORY_LOG_DIRECTORY')
|
||||
if dir_entry.has_known_prefix and dir_entry.is_subspace:
|
||||
#print '%d. Logging subspace: %d' % (i, dir_entry.dir_id)
|
||||
# print '%d. Logging subspace: %d' % (i, dir_entry.dir_id)
|
||||
instructions.push_args(self.subspace_log.key())
|
||||
instructions.append('DIRECTORY_LOG_SUBSPACE')
|
||||
if (i+1) % 100 == 0:
|
||||
if (i + 1) % 100 == 0:
|
||||
test_util.blocking_commit(instructions)
|
||||
|
||||
instructions.push_args(self.stack_subspace.key())
|
||||
|
@ -332,18 +337,21 @@ class DirectoryTest(Test):
|
|||
# If a partition is created, allocates a prefix, and then is removed, subsequent prefix
|
||||
# allocations could collide with prior ones. We can get around this by not allowing
|
||||
# a removed directory (or partition) to be used, but that weakens the test in another way.
|
||||
#errors += directory_util.check_for_duplicate_prefixes(db, self.prefix_log)
|
||||
# errors += directory_util.check_for_duplicate_prefixes(db, self.prefix_log)
|
||||
return errors
|
||||
|
||||
def get_result_specfications(self):
|
||||
return [
|
||||
ResultSpecification(self.stack, key_start_index=1, ordering_index=1),
|
||||
ResultSpecification(self.directory_log, ordering_index=0),
|
||||
ResultSpecification(self.subspace_log, ordering_index=0)
|
||||
return [
|
||||
ResultSpecification(self.stack, key_start_index=1, ordering_index=1),
|
||||
ResultSpecification(self.directory_log, ordering_index=0),
|
||||
ResultSpecification(self.subspace_log, ordering_index=0)
|
||||
]
|
||||
|
||||
|
||||
# Utility functions
|
||||
def generate_path(min_length = 0):
|
||||
|
||||
|
||||
def generate_path(min_length=0):
|
||||
length = int(random.random() * random.random() * (4 - min_length)) + min_length
|
||||
path = ()
|
||||
for i in range(length):
|
||||
|
@ -351,9 +359,10 @@ def generate_path(min_length = 0):
|
|||
path = path + (u'',)
|
||||
else:
|
||||
path = path + (random.choice([u'1', u'2', u'3']),)
|
||||
|
||||
|
||||
return path
|
||||
|
||||
|
||||
def generate_prefix(allow_empty=True, is_partition=False):
|
||||
if allow_empty and random.random() < 0.8:
|
||||
return None
|
||||
|
@ -364,7 +373,7 @@ def generate_prefix(allow_empty=True, is_partition=False):
|
|||
|
||||
if not is_partition:
|
||||
first = chr(random.randint(ord('\x1d'), 255) % 255)
|
||||
return first + ''.join(chr(random.randrange(0, 256)) for i in range(0, length-1))
|
||||
return first + ''.join(chr(random.randrange(0, 256)) for i in range(0, length - 1))
|
||||
else:
|
||||
return ''.join(chr(random.randrange(ord('\x02'), ord('\x14'))) for i in range(0, length))
|
||||
else:
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -30,6 +30,7 @@ from bindingtester.tests import test_util, directory_util
|
|||
|
||||
fdb.api_version(FDB_API_VERSION)
|
||||
|
||||
|
||||
class DirectoryHcaTest(Test):
|
||||
def __init__(self, subspace):
|
||||
super(DirectoryHcaTest, self).__init__(subspace)
|
||||
|
@ -39,7 +40,7 @@ class DirectoryHcaTest(Test):
|
|||
|
||||
def setup(self, args):
|
||||
self.random = test_util.RandomGenerator(args.max_int_bits, args.api_version, args.types)
|
||||
self.transactions = ['tr%d' % i for i in range(3)] # SOMEDAY: parameterize this number?
|
||||
self.transactions = ['tr%d' % i for i in range(3)] # SOMEDAY: parameterize this number?
|
||||
self.barrier_num = 0
|
||||
|
||||
self.max_directories_per_transaction = 30
|
||||
|
@ -58,7 +59,7 @@ class DirectoryHcaTest(Test):
|
|||
|
||||
def barrier(self, instructions, thread_number, thread_ending=False):
|
||||
if not thread_ending:
|
||||
instructions.push_args(self.coordination[(self.barrier_num+1)][thread_number].key(), '')
|
||||
instructions.push_args(self.coordination[(self.barrier_num + 1)][thread_number].key(), '')
|
||||
instructions.append('SET_DATABASE')
|
||||
instructions.append('WAIT_FUTURE')
|
||||
|
||||
|
@ -101,8 +102,9 @@ class DirectoryHcaTest(Test):
|
|||
|
||||
for i in range(num_directories):
|
||||
path = (self.random.random_unicode_str(16),)
|
||||
op_args = test_util.with_length(path) + ('', None)
|
||||
directory_util.push_instruction_and_record_prefix(instructions, 'DIRECTORY_CREATE', op_args, path, num_dirs, self.random, self.prefix_log)
|
||||
op_args = test_util.with_length(path) + ('', None)
|
||||
directory_util.push_instruction_and_record_prefix(instructions, 'DIRECTORY_CREATE',
|
||||
op_args, path, num_dirs, self.random, self.prefix_log)
|
||||
num_dirs += 1
|
||||
|
||||
current_op += num_directories
|
||||
|
@ -127,4 +129,3 @@ class DirectoryHcaTest(Test):
|
|||
errors += directory_util.validate_hca_state(db)
|
||||
|
||||
return errors
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -34,8 +34,9 @@ DEFAULT_DIRECTORY_INDEX = 4
|
|||
DEFAULT_DIRECTORY_PREFIX = 'default'
|
||||
DIRECTORY_ERROR_STRING = 'DIRECTORY_ERROR'
|
||||
|
||||
|
||||
class DirListEntry:
|
||||
dir_id = 0 # Used for debugging
|
||||
dir_id = 0 # Used for debugging
|
||||
|
||||
def __init__(self, is_directory, is_subspace, has_known_prefix=True, path=(), root=None):
|
||||
self.root = root or self
|
||||
|
@ -53,45 +54,46 @@ class DirListEntry:
|
|||
|
||||
def add_child(self, subpath, default_path, root, child):
|
||||
if default_path in root.children:
|
||||
#print 'Adding child %r to default directory %r at %r' % (child, root.children[DirectoryTest.DEFAULT_DIRECTORY_PATH].path, subpath)
|
||||
# print 'Adding child %r to default directory %r at %r' % (child, root.children[DirectoryTest.DEFAULT_DIRECTORY_PATH].path, subpath)
|
||||
c = root.children[default_path]._add_child_impl(subpath, child)
|
||||
child.has_known_prefix = c.has_known_prefix and child.has_known_prefix
|
||||
#print 'Added %r' % c
|
||||
# print 'Added %r' % c
|
||||
|
||||
#print 'Adding child %r to directory %r at %r' % (child, self.path, subpath)
|
||||
# print 'Adding child %r to directory %r at %r' % (child, self.path, subpath)
|
||||
c = self._add_child_impl(subpath, child)
|
||||
#print 'Added %r' % c
|
||||
# print 'Added %r' % c
|
||||
return c
|
||||
|
||||
def _add_child_impl(self, subpath, child):
|
||||
#print '%d, %d. Adding child (recursive): %s %s' % (self.dir_id, child.dir_id, repr(self.path), repr(subpath))
|
||||
# print '%d, %d. Adding child (recursive): %s %s' % (self.dir_id, child.dir_id, repr(self.path), repr(subpath))
|
||||
if len(subpath) == 0:
|
||||
self.has_known_prefix = self.has_known_prefix and child.has_known_prefix
|
||||
#print '%d, %d. Setting child: %d' % (self.dir_id, child.dir_id, self.has_known_prefix)
|
||||
# print '%d, %d. Setting child: %d' % (self.dir_id, child.dir_id, self.has_known_prefix)
|
||||
self._merge_children(child)
|
||||
|
||||
return self
|
||||
else:
|
||||
if not subpath[0] in self.children:
|
||||
#print '%d, %d. Path %s was absent (%s)' % (self.dir_id, child.dir_id, repr(self.path + subpath[0:1]), repr(self.children))
|
||||
subdir = DirListEntry(True, True, path = self.path+subpath[0:1], root = self.root)
|
||||
# print '%d, %d. Path %s was absent (%s)' % (self.dir_id, child.dir_id, repr(self.path + subpath[0:1]), repr(self.children))
|
||||
subdir = DirListEntry(True, True, path=self.path + subpath[0:1], root=self.root)
|
||||
subdir.has_known_prefix = len(subpath) == 1
|
||||
self.children[subpath[0]] = subdir
|
||||
else:
|
||||
subdir = self.children[subpath[0]]
|
||||
subdir.has_known_prefix = False
|
||||
#print '%d, %d. Path was present' % (self.dir_id, child.dir_id)
|
||||
# print '%d, %d. Path was present' % (self.dir_id, child.dir_id)
|
||||
|
||||
return subdir._add_child_impl(subpath[1:], child)
|
||||
|
||||
def _merge_children(self, other):
|
||||
for c in other.children:
|
||||
if not c in self.children:
|
||||
if c not in self.children:
|
||||
self.children[c] = other.children[c]
|
||||
else:
|
||||
self.children[c].has_known_prefix = self.children[c].has_known_prefix and other.children[c].has_known_prefix
|
||||
self.children[c]._merge_children(other.children[c])
|
||||
|
||||
|
||||
def setup_directories(instructions, default_path, random):
|
||||
dir_list = [DirListEntry(True, False, True)]
|
||||
instructions.push_args(0, '\xfe')
|
||||
|
@ -114,6 +116,7 @@ def setup_directories(instructions, default_path, random):
|
|||
|
||||
return dir_list
|
||||
|
||||
|
||||
def create_default_directory_subspace(instructions, path, random):
|
||||
test_util.blocking_commit(instructions)
|
||||
instructions.push_args(3)
|
||||
|
@ -125,6 +128,7 @@ def create_default_directory_subspace(instructions, path, random):
|
|||
instructions.push_args(DEFAULT_DIRECTORY_INDEX)
|
||||
instructions.append('DIRECTORY_CHANGE')
|
||||
|
||||
|
||||
def push_instruction_and_record_prefix(instructions, op, op_args, path, dir_index, random, subspace):
|
||||
if not op.endswith('_DATABASE'):
|
||||
instructions.push_args(1, *test_util.with_length(path))
|
||||
|
@ -141,17 +145,18 @@ def push_instruction_and_record_prefix(instructions, op, op_args, path, dir_inde
|
|||
|
||||
instructions.push_args(1, '', random.random_string(16), '')
|
||||
instructions.append('DIRECTORY_PACK_KEY')
|
||||
test_util.to_front(instructions, 3) # move the existence result up to the front of the stack
|
||||
test_util.to_front(instructions, 3) # move the existence result up to the front of the stack
|
||||
|
||||
t = util.subspace_to_tuple(subspace)
|
||||
instructions.push_args(len(t) + 3, *t)
|
||||
|
||||
instructions.append('TUPLE_PACK') # subspace[<exists>][<packed_key>][random.random_string(16)] = ''
|
||||
instructions.append('TUPLE_PACK') # subspace[<exists>][<packed_key>][random.random_string(16)] = ''
|
||||
instructions.append('SET')
|
||||
|
||||
instructions.push_args(DEFAULT_DIRECTORY_INDEX)
|
||||
instructions.append('DIRECTORY_CHANGE')
|
||||
|
||||
|
||||
def check_for_duplicate_prefixes(db, subspace):
|
||||
last_prefix = None
|
||||
start_key = subspace[0].range().start
|
||||
|
@ -164,18 +169,19 @@ def check_for_duplicate_prefixes(db, subspace):
|
|||
break
|
||||
|
||||
start_key = fdb.KeySelector.first_greater_than(prefixes[-1].key)
|
||||
|
||||
|
||||
prefixes = [subspace[0].unpack(kv.key)[0] for kv in prefixes]
|
||||
prefixes = [p for p in prefixes if not (p.startswith(DEFAULT_DIRECTORY_PREFIX) or p == DIRECTORY_ERROR_STRING)]
|
||||
count += len(prefixes)
|
||||
|
||||
prefixes = [last_prefix] + prefixes
|
||||
duplicates.update([p for i,p in enumerate(prefixes[1:]) if p == prefixes[i]])
|
||||
duplicates.update([p for i, p in enumerate(prefixes[1:]) if p == prefixes[i]])
|
||||
last_prefix = prefixes[-1]
|
||||
|
||||
util.get_logger().info('Checked %d directory prefixes for duplicates' % count)
|
||||
return ['The prefix %r was allocated multiple times' % d[:-2] for d in set(duplicates)]
|
||||
|
||||
|
||||
def validate_hca_state(db):
|
||||
hca = fdb.Subspace(('\xfe', 'hca'), '\xfe')
|
||||
counters = hca[0]
|
||||
|
@ -184,7 +190,7 @@ def validate_hca_state(db):
|
|||
last_counter = db.get_range(counters.range().start, counters.range().stop, limit=1, reverse=True)
|
||||
[(start, reported_count)] = [(counters.unpack(kv.key)[0], struct.unpack('<q', kv.value)[0]) for kv in last_counter] or [(0, 0)]
|
||||
|
||||
actual_count = len(db[recent[start] : recent.range().stop])
|
||||
actual_count = len(db[recent[start]: recent.range().stop])
|
||||
if actual_count > reported_count:
|
||||
return ['The HCA reports %d prefixes allocated in current window, but it actually allocated %d' % (reported_count, actual_count)]
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -31,6 +31,8 @@ from bindingtester.tests import test_util
|
|||
fdb.api_version(FDB_API_VERSION)
|
||||
|
||||
# SOMEDAY: This should probably be broken up into smaller tests
|
||||
|
||||
|
||||
class ScriptedTest(Test):
|
||||
TEST_API_VERSION = 510
|
||||
|
||||
|
@ -38,15 +40,15 @@ class ScriptedTest(Test):
|
|||
super(ScriptedTest, self).__init__(subspace, ScriptedTest.TEST_API_VERSION, ScriptedTest.TEST_API_VERSION)
|
||||
self.workspace = self.subspace['workspace']
|
||||
self.results_subspace = self.subspace['results']
|
||||
#self.thread_subspace = self.subspace['threads'] # TODO: update START_THREAD so that we can create threads in subspaces
|
||||
# self.thread_subspace = self.subspace['threads'] # TODO: update START_THREAD so that we can create threads in subspaces
|
||||
|
||||
def setup(self, args):
|
||||
if args.concurrency > 1:
|
||||
raise Exception('Scripted tests cannot be run with a concurrency greater than 1')
|
||||
|
||||
|
||||
# SOMEDAY: this is only a limitation because we don't know how many operations the bisection should start with
|
||||
# it should be fixable.
|
||||
#
|
||||
#
|
||||
# We also need to enable the commented out support for num_ops in this file and make it so the default value runs
|
||||
# the entire test
|
||||
if args.bisect:
|
||||
|
@ -58,7 +60,7 @@ class ScriptedTest(Test):
|
|||
test_instructions = ThreadedInstructionSet()
|
||||
main_thread = test_instructions.create_thread()
|
||||
|
||||
foo = [self.workspace.pack(('foo%d' % i,)) for i in range(0,6)]
|
||||
foo = [self.workspace.pack(('foo%d' % i,)) for i in range(0, 6)]
|
||||
|
||||
main_thread.append('NEW_TRANSACTION')
|
||||
main_thread.push_args(1020)
|
||||
|
@ -270,8 +272,8 @@ class ScriptedTest(Test):
|
|||
|
||||
stampKey = 'stampedXXXXXXXXXXsuffix'
|
||||
stampKeyIndex = stampKey.find('XXXXXXXXXX')
|
||||
stampKeyStr = chr(stampKeyIndex%256) + chr(stampKeyIndex/256)
|
||||
main_thread.push_args(u'SET_VERSIONSTAMPED_KEY', stampKey + stampKeyStr, 'stampedBar')
|
||||
stampKeyStr = chr(stampKeyIndex % 256) + chr(stampKeyIndex / 256)
|
||||
main_thread.push_args(u'SET_VERSIONSTAMPED_KEY', stampKey + stampKeyStr, 'stampedBar')
|
||||
main_thread.append('ATOMIC_OP')
|
||||
main_thread.push_args(u'SET_VERSIONSTAMPED_VALUE', 'stampedValue', 'XXXXXXXXXX')
|
||||
main_thread.append('ATOMIC_OP')
|
||||
|
@ -305,7 +307,7 @@ class ScriptedTest(Test):
|
|||
|
||||
if not args.no_threads:
|
||||
wait_key = 'waitKey'
|
||||
#threads = [self.thread_subspace[i] for i in range(0, 2)]
|
||||
# threads = [self.thread_subspace[i] for i in range(0, 2)]
|
||||
threads = ['thread_spec%d' % i for i in range(0, 2)]
|
||||
for thread_spec in threads:
|
||||
main_thread.push_args(self.workspace.pack((wait_key, thread_spec)), '')
|
||||
|
@ -314,11 +316,12 @@ class ScriptedTest(Test):
|
|||
|
||||
for thread_spec in threads:
|
||||
main_thread.push_args(thread_spec)
|
||||
#if len(main_thread) < args.num_ops:
|
||||
# if len(main_thread) < args.num_ops:
|
||||
main_thread.append('START_THREAD')
|
||||
thread = test_instructions.create_thread(fdb.Subspace((thread_spec,)))
|
||||
thread.append('NEW_TRANSACTION')
|
||||
thread.push_args(foo[1], foo[1], 'bar%s' % thread_spec, self.workspace.pack((wait_key, thread_spec)), self.workspace.pack((wait_key, thread_spec)))
|
||||
thread.push_args(foo[1], foo[1], 'bar%s' % thread_spec, self.workspace.pack(
|
||||
(wait_key, thread_spec)), self.workspace.pack((wait_key, thread_spec)))
|
||||
thread.append('GET')
|
||||
thread.append('POP')
|
||||
thread.append('SET')
|
||||
|
@ -333,20 +336,20 @@ class ScriptedTest(Test):
|
|||
thread.push_args(foo[1])
|
||||
thread.append('GET')
|
||||
self.add_result(thread, args, 'barthread_spec0', 'barthread_spec1')
|
||||
|
||||
|
||||
main_thread.append('EMPTY_STACK')
|
||||
#if len(main_thread) > args.num_ops:
|
||||
#main_thread[args.num_ops:] = []
|
||||
# if len(main_thread) > args.num_ops:
|
||||
# main_thread[args.num_ops:] = []
|
||||
|
||||
return test_instructions
|
||||
|
||||
def get_result_specifications(self):
|
||||
return [
|
||||
ResultSpecification(self.results_subspace, ordering_index=0, global_error_filter=[1007, 1021])
|
||||
return [
|
||||
ResultSpecification(self.results_subspace, ordering_index=0, global_error_filter=[1007, 1021])
|
||||
]
|
||||
|
||||
def get_expected_results(self):
|
||||
return { self.results_subspace : self.results }
|
||||
return {self.results_subspace: self.results}
|
||||
|
||||
def append_range_test(self, instructions, args, num_pairs, kv_length):
|
||||
instructions.append('NEW_TRANSACTION')
|
||||
|
@ -355,7 +358,7 @@ class ScriptedTest(Test):
|
|||
instructions.append('CLEAR_RANGE_STARTS_WITH')
|
||||
|
||||
kvpairs = []
|
||||
for i in range(0, num_pairs*2):
|
||||
for i in range(0, num_pairs * 2):
|
||||
kvpairs.append(self.workspace.pack(('foo', ''.join(chr(random.randint(0, 254)) for i in range(0, kv_length)))))
|
||||
|
||||
kvpairs = list(set(kvpairs))
|
||||
|
@ -364,7 +367,7 @@ class ScriptedTest(Test):
|
|||
kvpairs.sort()
|
||||
|
||||
instructions.push_args(*kvpairs)
|
||||
for i in range(0, len(kvpairs)/2):
|
||||
for i in range(0, len(kvpairs) / 2):
|
||||
instructions.append('SET')
|
||||
if i % 100 == 99:
|
||||
test_util.blocking_commit(instructions)
|
||||
|
@ -388,8 +391,7 @@ class ScriptedTest(Test):
|
|||
instructions.push_args(key)
|
||||
instructions.append('SET_DATABASE')
|
||||
|
||||
#if len(instructions) <= args.num_ops:
|
||||
# if len(instructions) <= args.num_ops:
|
||||
self.results.append(Result(self.results_subspace, key, values))
|
||||
|
||||
instructions.append('POP')
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -31,6 +31,7 @@ from bindingtester import util
|
|||
from bindingtester import FDB_API_VERSION
|
||||
from bindingtester.known_testers import COMMON_TYPES
|
||||
|
||||
|
||||
class RandomGenerator(object):
|
||||
def __init__(self, max_int_bits=64, api_version=FDB_API_VERSION, types=COMMON_TYPES):
|
||||
self.max_int_bits = max_int_bits
|
||||
|
@ -41,13 +42,13 @@ class RandomGenerator(object):
|
|||
return u''.join(self.random_unicode_char() for i in range(0, length))
|
||||
|
||||
def random_int(self):
|
||||
num_bits = random.randint(0, self.max_int_bits) # This way, we test small numbers with higher probability
|
||||
num_bits = random.randint(0, self.max_int_bits) # This way, we test small numbers with higher probability
|
||||
|
||||
max_value = (1 << num_bits) - 1
|
||||
min_value = -max_value - 1
|
||||
num = random.randint(min_value, max_value)
|
||||
|
||||
#util.get_logger().debug('generating int (%d): %d - %s' % (num_bits, num, repr(fdb.tuple.pack((num,)))))
|
||||
# util.get_logger().debug('generating int (%d): %d - %s' % (num_bits, num, repr(fdb.tuple.pack((num,)))))
|
||||
return num
|
||||
|
||||
def random_float(self, exp_bits):
|
||||
|
@ -57,7 +58,7 @@ class RandomGenerator(object):
|
|||
else:
|
||||
# Choose a value from all over the range of acceptable floats for this precision.
|
||||
sign = -1 if random.random() < 0.5 else 1
|
||||
exponent = random.randint(-(1 << (exp_bits-1))-10, (1 << (exp_bits-1) - 1))
|
||||
exponent = random.randint(-(1 << (exp_bits - 1)) - 10, (1 << (exp_bits - 1) - 1))
|
||||
mantissa = random.random()
|
||||
return sign * math.pow(2, exponent) * mantissa
|
||||
|
||||
|
@ -117,12 +118,12 @@ class RandomGenerator(object):
|
|||
smaller_size = random.randint(1, len(to_add))
|
||||
tuples.append(to_add[:smaller_size])
|
||||
else:
|
||||
non_empty = filter(lambda (i,x): (isinstance(x, list) or isinstance(x, tuple)) and len(x) > 0, enumerate(to_add))
|
||||
non_empty = filter(lambda (_, x): (isinstance(x, list) or isinstance(x, tuple)) and len(x) > 0, enumerate(to_add))
|
||||
if len(non_empty) > 0 and random.random() < 0.25:
|
||||
# Add a smaller list to test prefixes of nested structures.
|
||||
idx, choice = random.choice(non_empty)
|
||||
smaller_size = random.randint(0, len(to_add[idx]))
|
||||
tuples.append(to_add[:idx] + (choice[:smaller_size],) + to_add[idx+1:])
|
||||
tuples.append(to_add[:idx] + (choice[:smaller_size],) + to_add[idx + 1:])
|
||||
|
||||
random.shuffle(tuples)
|
||||
return tuples
|
||||
|
@ -133,7 +134,7 @@ class RandomGenerator(object):
|
|||
elif random.random() < 0.75:
|
||||
limit = 0
|
||||
else:
|
||||
limit = random.randint(1e8, (1<<31)-1)
|
||||
limit = random.randint(1e8, (1 << 31) - 1)
|
||||
|
||||
return (limit, random.randint(0, 1), random.randint(-2, 4))
|
||||
|
||||
|
@ -149,13 +150,13 @@ class RandomGenerator(object):
|
|||
if length == 0:
|
||||
return ''
|
||||
|
||||
return chr(random.randint(0, 254)) + ''.join(chr(random.randint(0, 255)) for i in range(0, length-1))
|
||||
return chr(random.randint(0, 254)) + ''.join(chr(random.randint(0, 255)) for i in range(0, length - 1))
|
||||
|
||||
def random_unicode_char(self):
|
||||
while True:
|
||||
if random.random() < 0.05:
|
||||
# Choose one of these special character sequences.
|
||||
specials = [u'\U0001f4a9', u'\U0001f63c', u'\U0001f3f3\ufe0f\u200d\U0001f308', u'\U0001f1f5\U0001f1f2', u'\uf8ff',
|
||||
specials = [u'\U0001f4a9', u'\U0001f63c', u'\U0001f3f3\ufe0f\u200d\U0001f308', u'\U0001f1f5\U0001f1f2', u'\uf8ff',
|
||||
u'\U0002a2b2', u'\u05e9\u05dc\u05d5\u05dd']
|
||||
return random.choice(specials)
|
||||
c = random.randint(0, 0xffff)
|
||||
|
@ -166,11 +167,13 @@ class RandomGenerator(object):
|
|||
def error_string(error_code):
|
||||
return fdb.tuple.pack(('ERROR', str(error_code)))
|
||||
|
||||
|
||||
def blocking_commit(instructions):
|
||||
instructions.append('COMMIT')
|
||||
instructions.append('WAIT_FUTURE')
|
||||
instructions.append('RESET')
|
||||
|
||||
|
||||
def to_front(instructions, index):
|
||||
if index == 0:
|
||||
pass
|
||||
|
@ -178,19 +181,19 @@ def to_front(instructions, index):
|
|||
instructions.push_args(1)
|
||||
instructions.append('SWAP')
|
||||
elif index == 2:
|
||||
instructions.push_args(index-1)
|
||||
instructions.push_args(index - 1)
|
||||
instructions.append('SWAP')
|
||||
instructions.push_args(index)
|
||||
instructions.append('SWAP')
|
||||
else:
|
||||
instructions.push_args(index-1)
|
||||
instructions.push_args(index - 1)
|
||||
instructions.append('SWAP')
|
||||
instructions.push_args(index)
|
||||
instructions.append('SWAP')
|
||||
instructions.push_args(index-1)
|
||||
instructions.push_args(index - 1)
|
||||
instructions.append('SWAP')
|
||||
to_front(instructions, index-1)
|
||||
to_front(instructions, index - 1)
|
||||
|
||||
|
||||
def with_length(tup):
|
||||
return (len(tup),) + tup
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -25,6 +25,7 @@ import glob
|
|||
|
||||
import fdb
|
||||
|
||||
|
||||
def initialize_logger_level(logging_level):
|
||||
logger = get_logger()
|
||||
|
||||
|
@ -39,9 +40,11 @@ def initialize_logger_level(logging_level):
|
|||
elif logging_level == "ERROR":
|
||||
logger.setLevel(logging.ERROR)
|
||||
|
||||
|
||||
def get_logger():
|
||||
return logging.getLogger('foundationdb.bindingtester')
|
||||
|
||||
|
||||
# Attempts to get the name associated with a process termination signal
|
||||
def signal_number_to_name(signal_num):
|
||||
name = []
|
||||
|
@ -53,6 +56,7 @@ def signal_number_to_name(signal_num):
|
|||
else:
|
||||
return str(signal_num)
|
||||
|
||||
|
||||
def import_subclasses(filename, module_path):
|
||||
for f in glob.glob(os.path.join(os.path.dirname(filename), '*.py')):
|
||||
fn = os.path.basename(f)
|
||||
|
@ -60,6 +64,7 @@ def import_subclasses(filename, module_path):
|
|||
continue
|
||||
__import__('%s.%s' % (module_path, os.path.splitext(fn)[0]))
|
||||
|
||||
|
||||
# Attempts to unpack a subspace
|
||||
# This throws an exception if the subspace cannot be unpacked as a tuple
|
||||
# As a result, the binding tester cannot use subspaces that have non-tuple raw prefixes
|
||||
|
@ -69,4 +74,3 @@ def subspace_to_tuple(subspace):
|
|||
except Exception as e:
|
||||
get_logger().debug(e)
|
||||
raise Exception('The binding tester does not support subspaces with non-tuple raw prefixes')
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -27,19 +27,21 @@ import sys
|
|||
|
||||
functions = {}
|
||||
|
||||
func_re = re.compile("^\s*FDB_API_(?:CHANGED|REMOVED)\s*\(\s*([^,]*),\s*([^)]*)\).*")
|
||||
func_re = re.compile(
|
||||
"^\s*FDB_API_(?:CHANGED|REMOVED)\s*\(\s*([^,]*),\s*([^)]*)\).*")
|
||||
|
||||
with open(source, 'r') as srcfile:
|
||||
for l in srcfile:
|
||||
m = func_re.match(l)
|
||||
if m:
|
||||
func, ver = m.groups()
|
||||
if not func in functions:
|
||||
if func not in functions:
|
||||
functions[func] = []
|
||||
ver = int(ver)
|
||||
if not ver in functions[func]:
|
||||
if ver not in functions[func]:
|
||||
functions[func].append(ver)
|
||||
|
||||
|
||||
def write_windows_asm(asmfile, functions):
|
||||
asmfile.write(".data\n")
|
||||
for f in functions:
|
||||
|
@ -55,6 +57,7 @@ def write_windows_asm(asmfile, functions):
|
|||
|
||||
asmfile.write("\nEND\n")
|
||||
|
||||
|
||||
def write_unix_asm(asmfile, functions, prefix):
|
||||
asmfile.write(".intel_syntax noprefix\n")
|
||||
|
||||
|
@ -70,13 +73,17 @@ def write_unix_asm(asmfile, functions, prefix):
|
|||
for f in functions:
|
||||
asmfile.write("\n.globl %s%s\n" % (prefix, f))
|
||||
asmfile.write("%s%s:\n" % (prefix, f))
|
||||
asmfile.write("\tmov r11, qword ptr [%sfdb_api_ptr_%s@GOTPCREL+rip]\n" % (prefix, f))
|
||||
asmfile.write(
|
||||
"\tmov r11, qword ptr [%sfdb_api_ptr_%s@GOTPCREL+rip]\n" % (prefix, f))
|
||||
asmfile.write("\tmov r11, qword ptr [r11]\n")
|
||||
asmfile.write("\tjmp r11\n")
|
||||
|
||||
|
||||
with open(asm, 'w') as asmfile, open(h, 'w') as hfile:
|
||||
hfile.write("void fdb_api_ptr_unimpl() { fprintf(stderr, \"UNIMPLEMENTED FDB API FUNCTION\\n\"); abort(); }\n\n")
|
||||
hfile.write("void fdb_api_ptr_removed() { fprintf(stderr, \"REMOVED FDB API FUNCTION\\n\"); abort(); }\n\n")
|
||||
hfile.write(
|
||||
"void fdb_api_ptr_unimpl() { fprintf(stderr, \"UNIMPLEMENTED FDB API FUNCTION\\n\"); abort(); }\n\n")
|
||||
hfile.write(
|
||||
"void fdb_api_ptr_removed() { fprintf(stderr, \"REMOVED FDB API FUNCTION\\n\"); abort(); }\n\n")
|
||||
|
||||
if platform == "linux":
|
||||
write_unix_asm(asmfile, functions, '')
|
||||
|
@ -90,4 +97,4 @@ with open(asm, 'w') as asmfile, open(h, 'w') as hfile:
|
|||
hfile.write("extern \"C\" ")
|
||||
hfile.write("void* fdb_api_ptr_%s = (void*)&fdb_api_ptr_unimpl;\n" % f)
|
||||
for v in functions[f]:
|
||||
hfile.write("#define %s_v%d_PREV %s_v%d\n" % (f, v, f, v-1))
|
||||
hfile.write("#define %s_v%d_PREV %s_v%d\n" % (f, v, f, v - 1))
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -51,6 +51,14 @@ GO_SRC := $(shell find $(CURDIR)/bindings/go/src -name '*.go')
|
|||
|
||||
fdb_go: $(GO_PACKAGE_OBJECTS) $(GO_SRC)
|
||||
|
||||
fdb_go_fmt: $(GO_SRC)
|
||||
@echo "Formatting fdb_go"
|
||||
@gofmt -w $(GO_SRC)
|
||||
|
||||
fdb_go_fmt_check: $(GO_SRC)
|
||||
@echo "Checking fdb_go"
|
||||
@bash -c 'fmtoutstr=$$(gofmt -l $(GO_SRC)) ; if [[ -n "$${fmtoutstr}" ]] ; then echo "Detected go formatting violations for the following files:" ; echo "$${fmtoutstr}" ; echo "Try running: make fdb_go_fmt"; exit 1 ; fi'
|
||||
|
||||
fdb_go_path: $(GO_SRC)
|
||||
@echo "Creating fdb_go_path"
|
||||
@mkdir -p $(GO_DEST)
|
||||
|
@ -66,27 +74,27 @@ fdb_go_tester_clean:
|
|||
@echo "Cleaning fdb_go_tester"
|
||||
@rm -rf $(GOPATH)/bin
|
||||
|
||||
$(GOPATH)/bin/_stacktester: fdb_go_path $(GO_SRC) $(GO_PACKAGE_OBJECTS) $(GO_DEST)/fdb/generated.go
|
||||
$(GOPATH)/bin/_stacktester: fdb_go_path fdb_go_fmt_check $(GO_SRC) $(GO_PACKAGE_OBJECTS) $(GO_DEST)/fdb/generated.go
|
||||
@echo "Compiling $(basename $(notdir $@))"
|
||||
@go install $(GO_IMPORT_PATH)/_stacktester
|
||||
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/tuple.a: fdb_go_path $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_DEST)/fdb/generated.go
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/tuple.a: fdb_go_path fdb_go_fmt_check $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_DEST)/fdb/generated.go
|
||||
@echo "Compiling fdb/tuple"
|
||||
@go install $(GO_IMPORT_PATH)/fdb/tuple
|
||||
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/subspace.a: fdb_go_path $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a $(GO_DEST)/fdb/generated.go
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/subspace.a: fdb_go_path fdb_go_fmt_check $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a $(GO_DEST)/fdb/generated.go
|
||||
@echo "Compiling fdb/subspace"
|
||||
@go install $(GO_IMPORT_PATH)/fdb/subspace
|
||||
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/directory.a: fdb_go_path $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a $(GO_PACKAGE_OUTDIR)/fdb/subspace.a $(GO_DEST)/fdb/generated.go
|
||||
$(GO_PACKAGE_OUTDIR)/fdb/directory.a: fdb_go_path fdb_go_fmt_check $(GO_SRC) $(GO_PACKAGE_OUTDIR)/fdb.a $(GO_PACKAGE_OUTDIR)/fdb/tuple.a $(GO_PACKAGE_OUTDIR)/fdb/subspace.a $(GO_DEST)/fdb/generated.go
|
||||
@echo "Compiling fdb/directory"
|
||||
@go install $(GO_IMPORT_PATH)/fdb/directory
|
||||
|
||||
$(GO_PACKAGE_OUTDIR)/fdb.a: fdb_go_path $(GO_SRC) $(GO_DEST)/fdb/generated.go
|
||||
$(GO_PACKAGE_OUTDIR)/fdb.a: fdb_go_path fdb_go_fmt_check $(GO_SRC) $(GO_DEST)/fdb/generated.go
|
||||
@echo "Compiling fdb"
|
||||
@go install $(GO_IMPORT_PATH)/fdb
|
||||
|
||||
$(GO_DEST)/fdb/generated.go: fdb_go_path lib/libfdb_c.$(DLEXT) bindings/go/src/_util/translate_fdb_options.go fdbclient/vexillographer/fdb.options
|
||||
$(GO_DEST)/fdb/generated.go: fdb_go_path fdb_go_fmt_check lib/libfdb_c.$(DLEXT) bindings/go/src/_util/translate_fdb_options.go fdbclient/vexillographer/fdb.options
|
||||
@echo "Building $@"
|
||||
@go run bindings/go/src/_util/translate_fdb_options.go < fdbclient/vexillographer/fdb.options > $@
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -21,12 +21,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/tuple"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/subspace"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/directory"
|
||||
"strings"
|
||||
"bytes"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/directory"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/subspace"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/tuple"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (sm *StackMachine) popTuples(count int) []tuple.Tuple {
|
||||
|
@ -60,8 +60,8 @@ func tuplePackStrings(s []string) []byte {
|
|||
}
|
||||
|
||||
type DirectoryExtension struct {
|
||||
list []interface{}
|
||||
index int64
|
||||
list []interface{}
|
||||
index int64
|
||||
errorIndex int64
|
||||
}
|
||||
|
||||
|
@ -93,15 +93,15 @@ func (sm *StackMachine) maybePath() []string {
|
|||
return path
|
||||
}
|
||||
|
||||
var createOps = map[string]bool {
|
||||
var createOps = map[string]bool{
|
||||
"CREATE_SUBSPACE": true,
|
||||
"CREATE_LAYER": true,
|
||||
"CREATE_OR_OPEN": true,
|
||||
"CREATE": true,
|
||||
"OPEN": true,
|
||||
"MOVE": true,
|
||||
"MOVE_TO": true,
|
||||
"OPEN_SUBSPACE": true,
|
||||
"CREATE_LAYER": true,
|
||||
"CREATE_OR_OPEN": true,
|
||||
"CREATE": true,
|
||||
"OPEN": true,
|
||||
"MOVE": true,
|
||||
"MOVE_TO": true,
|
||||
"OPEN_SUBSPACE": true,
|
||||
}
|
||||
|
||||
func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool, idx int, t fdb.Transactor, rt fdb.ReadTransactor) {
|
||||
|
@ -142,7 +142,9 @@ func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool,
|
|||
layer = l.([]byte)
|
||||
}
|
||||
d, e := de.cwd().CreateOrOpen(t, tupleToPath(tuples[0]), layer)
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
de.store(d)
|
||||
case op == "CREATE":
|
||||
tuples := sm.popTuples(1)
|
||||
|
@ -159,7 +161,9 @@ func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool,
|
|||
// p.([]byte) itself may be nil, but CreatePrefix handles that appropriately
|
||||
d, e = de.cwd().CreatePrefix(t, tupleToPath(tuples[0]), layer, p.([]byte))
|
||||
}
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
de.store(d)
|
||||
case op == "OPEN":
|
||||
tuples := sm.popTuples(1)
|
||||
|
@ -169,7 +173,9 @@ func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool,
|
|||
layer = l.([]byte)
|
||||
}
|
||||
d, e := de.cwd().Open(rt, tupleToPath(tuples[0]), layer)
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
de.store(d)
|
||||
case op == "CHANGE":
|
||||
i := sm.waitAndPop().item.(int64)
|
||||
|
@ -182,12 +188,16 @@ func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool,
|
|||
case op == "MOVE":
|
||||
tuples := sm.popTuples(2)
|
||||
d, e := de.cwd().Move(t, tupleToPath(tuples[0]), tupleToPath(tuples[1]))
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
de.store(d)
|
||||
case op == "MOVE_TO":
|
||||
tuples := sm.popTuples(1)
|
||||
d, e := de.cwd().MoveTo(t, tupleToPath(tuples[0]))
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
de.store(d)
|
||||
case strings.HasPrefix(op, "REMOVE"):
|
||||
path := sm.maybePath()
|
||||
|
@ -197,9 +207,11 @@ func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool,
|
|||
// doesn't end up committing the version key. (Other languages have
|
||||
// separate remove() and remove_if_exists() so don't have this tricky
|
||||
// issue).
|
||||
_, e := t.Transact(func (tr fdb.Transaction) (interface{}, error) {
|
||||
_, e := t.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
ok, e := de.cwd().Remove(tr, path)
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
switch op[6:] {
|
||||
case "":
|
||||
if !ok {
|
||||
|
@ -209,16 +221,24 @@ func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool,
|
|||
}
|
||||
return nil, nil
|
||||
})
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
case op == "LIST":
|
||||
subs, e := de.cwd().List(rt, sm.maybePath())
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
t := make(tuple.Tuple, len(subs))
|
||||
for i, s := range subs { t[i] = s }
|
||||
for i, s := range subs {
|
||||
t[i] = s
|
||||
}
|
||||
sm.store(idx, t.Pack())
|
||||
case op == "EXISTS":
|
||||
b, e := de.cwd().Exists(rt, sm.maybePath())
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
if b {
|
||||
sm.store(idx, int64(1))
|
||||
} else {
|
||||
|
@ -229,8 +249,10 @@ func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool,
|
|||
sm.store(idx, de.css().Pack(tuples[0]))
|
||||
case op == "UNPACK_KEY":
|
||||
t, e := de.css().Unpack(fdb.Key(sm.waitAndPop().item.([]byte)))
|
||||
if e != nil { panic(e) }
|
||||
for _, el := range(t) {
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
for _, el := range t {
|
||||
sm.store(idx, el)
|
||||
}
|
||||
case op == "RANGE":
|
||||
|
@ -252,7 +274,7 @@ func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool,
|
|||
k := sm.waitAndPop().item.([]byte)
|
||||
k = append(k, tuple.Tuple{de.index}.Pack()...)
|
||||
v := de.css().Bytes()
|
||||
t.Transact(func (tr fdb.Transaction) (interface{}, error) {
|
||||
t.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
tr.Set(fdb.Key(k), v)
|
||||
return nil, nil
|
||||
})
|
||||
|
@ -266,7 +288,9 @@ func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool,
|
|||
k3 := ss.Pack(tuple.Tuple{"exists"})
|
||||
var v3 []byte
|
||||
exists, e := de.cwd().Exists(rt, nil)
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
if exists {
|
||||
v3 = tuple.Tuple{1}.Pack()
|
||||
} else {
|
||||
|
@ -276,10 +300,12 @@ func (de *DirectoryExtension) processOp(sm *StackMachine, op string, isDB bool,
|
|||
var subs []string
|
||||
if exists {
|
||||
subs, e = de.cwd().List(rt, nil)
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
}
|
||||
v4 := tuplePackStrings(subs)
|
||||
t.Transact(func (tr fdb.Transaction) (interface{}, error) {
|
||||
t.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
tr.Set(k1, v1)
|
||||
tr.Set(k2, v2)
|
||||
tr.Set(k3, v3)
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -24,23 +24,23 @@ import (
|
|||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/tuple"
|
||||
"log"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"runtime"
|
||||
"reflect"
|
||||
"time"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const verbose bool = false
|
||||
|
||||
var trMap = map[string]fdb.Transaction {}
|
||||
var trMap = map[string]fdb.Transaction{}
|
||||
var trMapLock = sync.RWMutex{}
|
||||
|
||||
// Make tuples sortable by byte-order
|
||||
|
@ -69,17 +69,17 @@ func int64ToBool(i int64) bool {
|
|||
|
||||
type stackEntry struct {
|
||||
item interface{}
|
||||
idx int
|
||||
idx int
|
||||
}
|
||||
|
||||
type StackMachine struct {
|
||||
prefix []byte
|
||||
trName string
|
||||
stack []stackEntry
|
||||
prefix []byte
|
||||
trName string
|
||||
stack []stackEntry
|
||||
lastVersion int64
|
||||
threads sync.WaitGroup
|
||||
verbose bool
|
||||
de *DirectoryExtension
|
||||
threads sync.WaitGroup
|
||||
verbose bool
|
||||
de *DirectoryExtension
|
||||
}
|
||||
|
||||
func newStackMachine(prefix []byte, verbose bool) *StackMachine {
|
||||
|
@ -99,7 +99,7 @@ func (sm *StackMachine) waitAndPop() (ret stackEntry) {
|
|||
}
|
||||
}()
|
||||
|
||||
ret, sm.stack = sm.stack[len(sm.stack) - 1], sm.stack[:len(sm.stack) - 1]
|
||||
ret, sm.stack = sm.stack[len(sm.stack)-1], sm.stack[:len(sm.stack)-1]
|
||||
switch el := ret.item.(type) {
|
||||
case []byte:
|
||||
ret.item = el
|
||||
|
@ -150,9 +150,9 @@ func (sm *StackMachine) popPrefixRange() fdb.ExactRange {
|
|||
}
|
||||
|
||||
func (sm *StackMachine) pushRange(idx int, sl []fdb.KeyValue, prefixFilter []byte) {
|
||||
var t tuple.Tuple = make(tuple.Tuple, 0, len(sl) * 2)
|
||||
var t tuple.Tuple = make(tuple.Tuple, 0, len(sl)*2)
|
||||
|
||||
for _, kv := range(sl) {
|
||||
for _, kv := range sl {
|
||||
if prefixFilter == nil || bytes.HasPrefix(kv.Key, prefixFilter) {
|
||||
t = append(t, kv.Key)
|
||||
t = append(t, kv.Value)
|
||||
|
@ -240,7 +240,7 @@ func (sm *StackMachine) dumpStack() {
|
|||
}
|
||||
}
|
||||
|
||||
func (sm *StackMachine) executeMutation(t fdb.Transactor, f func (fdb.Transaction) (interface{}, error), isDB bool, idx int) {
|
||||
func (sm *StackMachine) executeMutation(t fdb.Transactor, f func(fdb.Transaction) (interface{}, error), isDB bool, idx int) {
|
||||
_, e := t.Transact(f)
|
||||
if e != nil {
|
||||
panic(e)
|
||||
|
@ -250,8 +250,8 @@ func (sm *StackMachine) executeMutation(t fdb.Transactor, f func (fdb.Transactio
|
|||
}
|
||||
}
|
||||
|
||||
func (sm *StackMachine) checkWatches(watches [4]fdb.FutureNil, expected bool) (bool) {
|
||||
for _, watch := range(watches) {
|
||||
func (sm *StackMachine) checkWatches(watches [4]fdb.FutureNil, expected bool) bool {
|
||||
for _, watch := range watches {
|
||||
if watch.IsReady() || expected {
|
||||
e := watch.Get()
|
||||
if e != nil {
|
||||
|
@ -283,7 +283,9 @@ func (sm *StackMachine) testWatches() {
|
|||
tr.Set(fdb.Key("w3"), []byte("3"))
|
||||
return nil, nil
|
||||
})
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
var watches [4]fdb.FutureNil
|
||||
|
||||
|
@ -297,7 +299,9 @@ func (sm *StackMachine) testWatches() {
|
|||
tr.Clear(fdb.Key("w1"))
|
||||
return nil, nil
|
||||
})
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
|
@ -312,7 +316,9 @@ func (sm *StackMachine) testWatches() {
|
|||
tr.BitXor(fdb.Key("w3"), []byte("\xff\xff"))
|
||||
return nil, nil
|
||||
})
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
if sm.checkWatches(watches, true) {
|
||||
return
|
||||
|
@ -322,21 +328,23 @@ func (sm *StackMachine) testWatches() {
|
|||
|
||||
func (sm *StackMachine) testLocality() {
|
||||
_, e := db.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
tr.Options().SetTimeout(60*1000)
|
||||
tr.Options().SetTimeout(60 * 1000)
|
||||
tr.Options().SetReadSystemKeys()
|
||||
boundaryKeys, e := db.LocalityGetBoundaryKeys(fdb.KeyRange{fdb.Key(""), fdb.Key("\xff\xff")}, 0, 0)
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
for i:=0; i<len(boundaryKeys)-1 ; i++ {
|
||||
for i := 0; i < len(boundaryKeys)-1; i++ {
|
||||
start := boundaryKeys[i]
|
||||
end := tr.GetKey(fdb.LastLessThan(boundaryKeys[i+1])).MustGet()
|
||||
|
||||
startAddresses := tr.LocalityGetAddressesForKey(start).MustGet()
|
||||
endAddresses := tr.LocalityGetAddressesForKey(end).MustGet()
|
||||
|
||||
for _, address1 := range(startAddresses) {
|
||||
for _, address1 := range startAddresses {
|
||||
found := false
|
||||
for _, address2 := range(endAddresses) {
|
||||
for _, address2 := range endAddresses {
|
||||
if address1 == address2 {
|
||||
found = true
|
||||
break
|
||||
|
@ -351,7 +359,9 @@ func (sm *StackMachine) testLocality() {
|
|||
return nil, nil
|
||||
})
|
||||
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (sm *StackMachine) logStack(entries map[int]stackEntry, prefix []byte) {
|
||||
|
@ -377,7 +387,9 @@ func (sm *StackMachine) logStack(entries map[int]stackEntry, prefix []byte) {
|
|||
return nil, nil
|
||||
})
|
||||
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -467,28 +479,28 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
case op == "PUSH":
|
||||
sm.store(idx, inst[1])
|
||||
case op == "DUP":
|
||||
entry := sm.stack[len(sm.stack) - 1]
|
||||
entry := sm.stack[len(sm.stack)-1]
|
||||
sm.store(entry.idx, entry.item)
|
||||
case op == "EMPTY_STACK":
|
||||
sm.stack = []stackEntry{}
|
||||
sm.stack = make([]stackEntry, 0)
|
||||
case op == "SWAP":
|
||||
idx := sm.waitAndPop().item.(int64)
|
||||
sm.stack[len(sm.stack) - 1], sm.stack[len(sm.stack) - 1 - int(idx)] = sm.stack[len(sm.stack) - 1 - int(idx)], sm.stack[len(sm.stack) - 1]
|
||||
sm.stack[len(sm.stack)-1], sm.stack[len(sm.stack)-1-int(idx)] = sm.stack[len(sm.stack)-1-int(idx)], sm.stack[len(sm.stack)-1]
|
||||
case op == "POP":
|
||||
sm.stack = sm.stack[:len(sm.stack) - 1]
|
||||
sm.stack = sm.stack[:len(sm.stack)-1]
|
||||
case op == "SUB":
|
||||
sm.store(idx, sm.waitAndPop().item.(int64) - sm.waitAndPop().item.(int64))
|
||||
sm.store(idx, sm.waitAndPop().item.(int64)-sm.waitAndPop().item.(int64))
|
||||
case op == "CONCAT":
|
||||
str1 := sm.waitAndPop().item
|
||||
str2 := sm.waitAndPop().item
|
||||
switch str1.(type) {
|
||||
case string:
|
||||
sm.store(idx, str1.(string) + str2.(string))
|
||||
case []byte:
|
||||
sm.store(idx, append(str1.([]byte), str2.([]byte)...))
|
||||
default:
|
||||
panic("Invalid CONCAT parameter")
|
||||
case string:
|
||||
sm.store(idx, str1.(string)+str2.(string))
|
||||
case []byte:
|
||||
sm.store(idx, append(str1.([]byte), str2.([]byte)...))
|
||||
default:
|
||||
panic("Invalid CONCAT parameter")
|
||||
}
|
||||
case op == "NEW_TRANSACTION":
|
||||
sm.newTransaction()
|
||||
|
@ -497,16 +509,18 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
case op == "ON_ERROR":
|
||||
sm.store(idx, sm.currentTransaction().OnError(fdb.Error{int(sm.waitAndPop().item.(int64))}))
|
||||
case op == "GET_READ_VERSION":
|
||||
_, e = rt.ReadTransact(func (rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
_, e = rt.ReadTransact(func(rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
sm.lastVersion = rtr.GetReadVersion().MustGet()
|
||||
sm.store(idx, []byte("GOT_READ_VERSION"))
|
||||
return nil, nil
|
||||
})
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
case op == "SET":
|
||||
key := fdb.Key(sm.waitAndPop().item.([]byte))
|
||||
value := sm.waitAndPop().item.([]byte)
|
||||
sm.executeMutation(t, func (tr fdb.Transaction) (interface{}, error) {
|
||||
sm.executeMutation(t, func(tr fdb.Transaction) (interface{}, error) {
|
||||
tr.Set(key, value)
|
||||
return nil, nil
|
||||
}, isDB, idx)
|
||||
|
@ -525,10 +539,12 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
sm.logStack(entries, prefix)
|
||||
case op == "GET":
|
||||
key := fdb.Key(sm.waitAndPop().item.([]byte))
|
||||
res, e := rt.ReadTransact(func (rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
res, e := rt.ReadTransact(func(rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
return rtr.Get(key), nil
|
||||
})
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
sm.store(idx, res.(fdb.FutureByteSlice))
|
||||
case op == "COMMIT":
|
||||
|
@ -537,7 +553,7 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
sm.currentTransaction().Reset()
|
||||
case op == "CLEAR":
|
||||
key := fdb.Key(sm.waitAndPop().item.([]byte))
|
||||
sm.executeMutation(t, func (tr fdb.Transaction) (interface{}, error) {
|
||||
sm.executeMutation(t, func(tr fdb.Transaction) (interface{}, error) {
|
||||
tr.Clear(key)
|
||||
return nil, nil
|
||||
}, isDB, idx)
|
||||
|
@ -557,10 +573,12 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
case op == "GET_KEY":
|
||||
sel := sm.popSelector()
|
||||
prefix := sm.waitAndPop().item.([]byte)
|
||||
res, e := rt.ReadTransact(func (rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
res, e := rt.ReadTransact(func(rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
return rtr.GetKey(sel).MustGet(), nil
|
||||
})
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
key := res.(fdb.Key)
|
||||
|
||||
|
@ -570,7 +588,9 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
sm.store(idx, prefix)
|
||||
} else {
|
||||
s, e := fdb.Strinc(prefix)
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
sm.store(idx, s)
|
||||
}
|
||||
case strings.HasPrefix(op, "GET_RANGE"):
|
||||
|
@ -591,10 +611,12 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
prefix = sm.waitAndPop().item.([]byte)
|
||||
}
|
||||
|
||||
res, e := rt.ReadTransact(func (rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
res, e := rt.ReadTransact(func(rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
return rtr.GetRange(r, ro).GetSliceOrPanic(), nil
|
||||
})
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
sm.pushRange(idx, res.([]fdb.KeyValue), prefix)
|
||||
case strings.HasPrefix(op, "CLEAR_RANGE"):
|
||||
|
@ -607,7 +629,7 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
er = sm.popKeyRange()
|
||||
}
|
||||
|
||||
sm.executeMutation(t, func (tr fdb.Transaction) (interface{}, error) {
|
||||
sm.executeMutation(t, func(tr fdb.Transaction) (interface{}, error) {
|
||||
tr.ClearRange(er)
|
||||
return nil, nil
|
||||
}, isDB, idx)
|
||||
|
@ -623,7 +645,7 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
for _, el := range(t) {
|
||||
for _, el := range t {
|
||||
sm.store(idx, []byte(tuple.Tuple{el}.Pack()))
|
||||
}
|
||||
case op == "TUPLE_SORT":
|
||||
|
@ -681,7 +703,7 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
db.Transact(func (tr fdb.Transaction) (interface{}, error) {
|
||||
db.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
v := tr.GetRange(er, fdb.RangeOptions{}).GetSliceOrPanic()
|
||||
if len(v) != 0 {
|
||||
panic(fdb.Error{1020})
|
||||
|
@ -718,7 +740,7 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
key := fdb.Key(sm.waitAndPop().item.([]byte))
|
||||
ival := sm.waitAndPop().item
|
||||
value := ival.([]byte)
|
||||
sm.executeMutation(t, func (tr fdb.Transaction) (interface{}, error) {
|
||||
sm.executeMutation(t, func(tr fdb.Transaction) (interface{}, error) {
|
||||
reflect.ValueOf(tr).MethodByName(opname).Call([]reflect.Value{reflect.ValueOf(key), reflect.ValueOf(value)})
|
||||
return nil, nil
|
||||
}, isDB, idx)
|
||||
|
@ -740,7 +762,7 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
tr.Options().SetReadSystemKeys()
|
||||
tr.Options().SetAccessSystemKeys()
|
||||
tr.Options().SetDurabilityDevNullIsWebScale()
|
||||
tr.Options().SetTimeout(60*1000)
|
||||
tr.Options().SetTimeout(60 * 1000)
|
||||
tr.Options().SetRetryLimit(50)
|
||||
tr.Options().SetMaxRetryDelay(100)
|
||||
tr.Options().SetUsedDuringCommitProtectionDisable()
|
||||
|
@ -751,7 +773,9 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
return tr.Get(fdb.Key("\xff")).MustGet(), nil
|
||||
})
|
||||
|
||||
if e != nil { panic(e) }
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
|
||||
sm.testWatches()
|
||||
sm.testLocality()
|
||||
|
@ -772,7 +796,7 @@ func (sm *StackMachine) processInst(idx int, inst tuple.Tuple) {
|
|||
}
|
||||
|
||||
func (sm *StackMachine) Run() {
|
||||
r, e := db.Transact(func (tr fdb.Transaction) (interface{}, error) {
|
||||
r, e := db.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
return tr.GetRange(tuple.Tuple{sm.prefix}, fdb.RangeOptions{}).GetSliceOrPanic(), nil
|
||||
})
|
||||
if e != nil {
|
||||
|
@ -781,7 +805,7 @@ func (sm *StackMachine) Run() {
|
|||
|
||||
instructions := r.([]fdb.KeyValue)
|
||||
|
||||
for i, kv := range(instructions) {
|
||||
for i, kv := range instructions {
|
||||
inst, _ := tuple.Unpack(fdb.Key(kv.Value))
|
||||
|
||||
if sm.verbose {
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -24,26 +24,26 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"go/doc"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"strings"
|
||||
"os"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
"go/doc"
|
||||
)
|
||||
|
||||
type Option struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Code int `xml:"code,attr"`
|
||||
ParamType string `xml:"paramType,attr"`
|
||||
ParamDesc string `xml:"paramDescription,attr"`
|
||||
Name string `xml:"name,attr"`
|
||||
Code int `xml:"code,attr"`
|
||||
ParamType string `xml:"paramType,attr"`
|
||||
ParamDesc string `xml:"paramDescription,attr"`
|
||||
Description string `xml:"description,attr"`
|
||||
Hidden bool `xml:"hidden,attr"`
|
||||
Hidden bool `xml:"hidden,attr"`
|
||||
}
|
||||
type Scope struct {
|
||||
Name string `xml:"name,attr"`
|
||||
Name string `xml:"name,attr"`
|
||||
Option []Option
|
||||
}
|
||||
type Options struct {
|
||||
|
@ -114,12 +114,12 @@ func translateName(old string) string {
|
|||
return strings.Replace(strings.Title(strings.Replace(old, "_", " ", -1)), " ", "", -1)
|
||||
}
|
||||
|
||||
func lowerFirst (s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
r, n := utf8.DecodeRuneInString(s)
|
||||
return string(unicode.ToLower(r)) + s[n:]
|
||||
func lowerFirst(s string) string {
|
||||
if s == "" {
|
||||
return ""
|
||||
}
|
||||
r, n := utf8.DecodeRuneInString(s)
|
||||
return string(unicode.ToLower(r)) + s[n:]
|
||||
}
|
||||
|
||||
func writeMutation(opt Option) {
|
||||
|
@ -139,7 +139,7 @@ func writeEnum(scope Scope, opt Option, delta int) {
|
|||
doc.ToText(os.Stdout, opt.Description, " // ", "", 73)
|
||||
// fmt.Printf(" // %s\n", opt.Description)
|
||||
}
|
||||
fmt.Printf(" %s %s = %d\n", scope.Name + translateName(opt.Name), scope.Name, opt.Code + delta)
|
||||
fmt.Printf(" %s %s = %d\n", scope.Name+translateName(opt.Name), scope.Name, opt.Code+delta)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -182,11 +182,11 @@ func int64ToBytes(i int64) ([]byte, error) {
|
|||
}
|
||||
`)
|
||||
|
||||
for _, scope := range(v.Scope) {
|
||||
for _, scope := range v.Scope {
|
||||
if strings.HasSuffix(scope.Name, "Option") {
|
||||
receiver := scope.Name + "s"
|
||||
|
||||
for _, opt := range(scope.Option) {
|
||||
for _, opt := range scope.Option {
|
||||
if opt.Description != "Deprecated" && !opt.Hidden { // Eww
|
||||
writeOpt(receiver, opt)
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ func int64ToBytes(i int64) ([]byte, error) {
|
|||
}
|
||||
|
||||
if scope.Name == "MutationType" {
|
||||
for _, opt := range(scope.Option) {
|
||||
for _, opt := range scope.Option {
|
||||
if opt.Description != "Deprecated" && !opt.Hidden { // Eww
|
||||
writeMutation(opt)
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ func int64ToBytes(i int64) ([]byte, error) {
|
|||
type %s int
|
||||
const (
|
||||
`, scope.Name)
|
||||
for _, opt := range(scope.Option) {
|
||||
for _, opt := range scope.Option {
|
||||
if !opt.Hidden {
|
||||
writeEnum(scope, opt, d)
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -23,10 +23,10 @@
|
|||
package directory
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/subspace"
|
||||
"encoding/binary"
|
||||
"bytes"
|
||||
"math/rand"
|
||||
"sync"
|
||||
)
|
||||
|
@ -53,14 +53,18 @@ func windowSize(start int64) int64 {
|
|||
// can't be too small. So start small and scale up. We don't want this to
|
||||
// ever get *too* big because we have to store about window_size/2 recent
|
||||
// items.
|
||||
if start < 255 { return 64 }
|
||||
if start < 65535 { return 1024 }
|
||||
if start < 255 {
|
||||
return 64
|
||||
}
|
||||
if start < 65535 {
|
||||
return 1024
|
||||
}
|
||||
return 8192
|
||||
}
|
||||
|
||||
func (hca highContentionAllocator) allocate(tr fdb.Transaction, s subspace.Subspace) (subspace.Subspace, error) {
|
||||
for {
|
||||
rr := tr.Snapshot().GetRange(hca.counters, fdb.RangeOptions{Limit:1, Reverse:true})
|
||||
rr := tr.Snapshot().GetRange(hca.counters, fdb.RangeOptions{Limit: 1, Reverse: true})
|
||||
kvs := rr.GetSliceOrPanic()
|
||||
|
||||
var start int64
|
||||
|
@ -106,7 +110,7 @@ func (hca highContentionAllocator) allocate(tr fdb.Transaction, s subspace.Subsp
|
|||
}
|
||||
|
||||
window = windowSize(start)
|
||||
if count * 2 < window {
|
||||
if count*2 < window {
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -124,7 +128,7 @@ func (hca highContentionAllocator) allocate(tr fdb.Transaction, s subspace.Subsp
|
|||
|
||||
allocatorMutex.Lock()
|
||||
|
||||
latestCounter := tr.Snapshot().GetRange(hca.counters, fdb.RangeOptions{Limit:1, Reverse:true})
|
||||
latestCounter := tr.Snapshot().GetRange(hca.counters, fdb.RangeOptions{Limit: 1, Reverse: true})
|
||||
candidateValue := tr.Get(key)
|
||||
tr.Options().SetNextWriteNoWriteConflictRange()
|
||||
tr.Set(key, []byte(""))
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -40,9 +40,9 @@
|
|||
package directory
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/subspace"
|
||||
"errors"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -23,23 +23,23 @@
|
|||
package directory
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/subspace"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/tuple"
|
||||
"encoding/binary"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type directoryLayer struct {
|
||||
nodeSS subspace.Subspace
|
||||
nodeSS subspace.Subspace
|
||||
contentSS subspace.Subspace
|
||||
|
||||
allowManualPrefixes bool
|
||||
|
||||
allocator highContentionAllocator
|
||||
rootNode subspace.Subspace
|
||||
rootNode subspace.Subspace
|
||||
|
||||
path []string
|
||||
}
|
||||
|
@ -130,13 +130,17 @@ func (dl directoryLayer) createOrOpen(rtr fdb.ReadTransaction, tr *fdb.Transacti
|
|||
prefix = newss.Bytes()
|
||||
|
||||
pf, e := dl.isPrefixFree(rtr.Snapshot(), prefix)
|
||||
if e != nil { return nil, e }
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
if !pf {
|
||||
return nil, errors.New("the directory layer has manually allocated prefixes that conflict with the automatic prefix allocator")
|
||||
}
|
||||
} else {
|
||||
pf, e := dl.isPrefixFree(rtr, prefix)
|
||||
if e != nil { return nil, e }
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
if !pf {
|
||||
return nil, errors.New("the given prefix is already in use")
|
||||
}
|
||||
|
@ -171,7 +175,7 @@ func (dl directoryLayer) createOrOpen(rtr fdb.ReadTransaction, tr *fdb.Transacti
|
|||
}
|
||||
|
||||
func (dl directoryLayer) CreateOrOpen(t fdb.Transactor, path []string, layer []byte) (DirectorySubspace, error) {
|
||||
r, e := t.Transact(func (tr fdb.Transaction) (interface{}, error) {
|
||||
r, e := t.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
return dl.createOrOpen(tr, &tr, path, layer, nil, true, true)
|
||||
})
|
||||
if e != nil {
|
||||
|
@ -181,7 +185,7 @@ func (dl directoryLayer) CreateOrOpen(t fdb.Transactor, path []string, layer []b
|
|||
}
|
||||
|
||||
func (dl directoryLayer) Create(t fdb.Transactor, path []string, layer []byte) (DirectorySubspace, error) {
|
||||
r, e := t.Transact(func (tr fdb.Transaction) (interface{}, error) {
|
||||
r, e := t.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
return dl.createOrOpen(tr, &tr, path, layer, nil, true, false)
|
||||
})
|
||||
if e != nil {
|
||||
|
@ -194,7 +198,7 @@ func (dl directoryLayer) CreatePrefix(t fdb.Transactor, path []string, layer []b
|
|||
if prefix == nil {
|
||||
prefix = []byte{}
|
||||
}
|
||||
r, e := t.Transact(func (tr fdb.Transaction) (interface{}, error) {
|
||||
r, e := t.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
return dl.createOrOpen(tr, &tr, path, layer, prefix, true, false)
|
||||
})
|
||||
if e != nil {
|
||||
|
@ -204,7 +208,7 @@ func (dl directoryLayer) CreatePrefix(t fdb.Transactor, path []string, layer []b
|
|||
}
|
||||
|
||||
func (dl directoryLayer) Open(rt fdb.ReadTransactor, path []string, layer []byte) (DirectorySubspace, error) {
|
||||
r, e := rt.ReadTransact(func (rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
r, e := rt.ReadTransact(func(rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
return dl.createOrOpen(rtr, nil, path, layer, nil, false, true)
|
||||
})
|
||||
if e != nil {
|
||||
|
@ -214,7 +218,7 @@ func (dl directoryLayer) Open(rt fdb.ReadTransactor, path []string, layer []byte
|
|||
}
|
||||
|
||||
func (dl directoryLayer) Exists(rt fdb.ReadTransactor, path []string) (bool, error) {
|
||||
r, e := rt.ReadTransact(func (rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
r, e := rt.ReadTransact(func(rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
if e := dl.checkVersion(rtr, nil); e != nil {
|
||||
return false, e
|
||||
}
|
||||
|
@ -241,7 +245,7 @@ func (dl directoryLayer) Exists(rt fdb.ReadTransactor, path []string) (bool, err
|
|||
}
|
||||
|
||||
func (dl directoryLayer) List(rt fdb.ReadTransactor, path []string) ([]string, error) {
|
||||
r, e := rt.ReadTransact(func (rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
r, e := rt.ReadTransact(func(rtr fdb.ReadTransaction) (interface{}, error) {
|
||||
if e := dl.checkVersion(rtr, nil); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
@ -272,7 +276,7 @@ func (dl directoryLayer) MoveTo(t fdb.Transactor, newAbsolutePath []string) (Dir
|
|||
}
|
||||
|
||||
func (dl directoryLayer) Move(t fdb.Transactor, oldPath []string, newPath []string) (DirectorySubspace, error) {
|
||||
r, e := t.Transact(func (tr fdb.Transaction) (interface{}, error) {
|
||||
r, e := t.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
if e := dl.checkVersion(tr, &tr); e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
@ -330,7 +334,7 @@ func (dl directoryLayer) Move(t fdb.Transactor, oldPath []string, newPath []stri
|
|||
}
|
||||
|
||||
func (dl directoryLayer) Remove(t fdb.Transactor, path []string) (bool, error) {
|
||||
r, e := t.Transact(func (tr fdb.Transaction) (interface{}, error) {
|
||||
r, e := t.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
if e := dl.checkVersion(tr, &tr); e != nil {
|
||||
return false, e
|
||||
}
|
||||
|
@ -375,9 +379,13 @@ func (dl directoryLayer) removeRecursive(tr fdb.Transaction, node subspace.Subsp
|
|||
}
|
||||
|
||||
p, e := dl.nodeSS.Unpack(node)
|
||||
if e != nil { return e }
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
kr, e := fdb.PrefixRange(p[0].([]byte))
|
||||
if e != nil { return e }
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
tr.ClearRange(kr)
|
||||
tr.ClearRange(node)
|
||||
|
@ -445,7 +453,7 @@ func (dl directoryLayer) nodeContainingKey(rtr fdb.ReadTransaction, key []byte)
|
|||
bk, _ := dl.nodeSS.FDBRangeKeys()
|
||||
kr := fdb.KeyRange{bk, fdb.Key(append(dl.nodeSS.Pack(tuple.Tuple{key}), 0x00))}
|
||||
|
||||
kvs := rtr.GetRange(kr, fdb.RangeOptions{Reverse:true, Limit:1}).GetSliceOrPanic()
|
||||
kvs := rtr.GetRange(kr, fdb.RangeOptions{Reverse: true, Limit: 1}).GetSliceOrPanic()
|
||||
if len(kvs) == 1 {
|
||||
pp, e := dl.nodeSS.Unpack(kvs[0].Key)
|
||||
if e != nil {
|
||||
|
@ -540,7 +548,7 @@ func (dl directoryLayer) contentsOfNode(node subspace.Subspace, path []string, l
|
|||
}
|
||||
prefix := p[0]
|
||||
|
||||
newPath := make([]string, len(dl.path) + len(path))
|
||||
newPath := make([]string, len(dl.path)+len(path))
|
||||
copy(newPath, dl.path)
|
||||
copy(newPath[len(dl.path):], path)
|
||||
|
||||
|
@ -548,7 +556,7 @@ func (dl directoryLayer) contentsOfNode(node subspace.Subspace, path []string, l
|
|||
ss := subspace.FromBytes(pb)
|
||||
|
||||
if bytes.Compare(layer, []byte("partition")) == 0 {
|
||||
nssb := make([]byte, len(pb) + 1)
|
||||
nssb := make([]byte, len(pb)+1)
|
||||
copy(nssb, pb)
|
||||
nssb[len(pb)] = 0xFE
|
||||
ndl := NewDirectoryLayer(subspace.FromBytes(nssb), ss, false).(directoryLayer)
|
||||
|
@ -560,7 +568,9 @@ func (dl directoryLayer) contentsOfNode(node subspace.Subspace, path []string, l
|
|||
}
|
||||
|
||||
func (dl directoryLayer) nodeWithPrefix(prefix []byte) subspace.Subspace {
|
||||
if prefix == nil { return nil }
|
||||
if prefix == nil {
|
||||
return nil
|
||||
}
|
||||
return dl.nodeSS.Sub(prefix)
|
||||
}
|
||||
|
||||
|
@ -576,9 +586,9 @@ func (dl directoryLayer) find(rtr fdb.ReadTransaction, path []string) *node {
|
|||
}
|
||||
|
||||
func (dl directoryLayer) partitionSubpath(lpath, rpath []string) []string {
|
||||
r := make([]string, len(lpath) - len(dl.path) + len(rpath))
|
||||
r := make([]string, len(lpath)-len(dl.path)+len(rpath))
|
||||
copy(r, lpath[len(dl.path):])
|
||||
copy(r[len(lpath) - len(dl.path):], rpath)
|
||||
copy(r[len(lpath)-len(dl.path):], rpath)
|
||||
return r
|
||||
}
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -38,8 +38,8 @@ type DirectorySubspace interface {
|
|||
|
||||
type directorySubspace struct {
|
||||
subspace.Subspace
|
||||
dl directoryLayer
|
||||
path []string
|
||||
dl directoryLayer
|
||||
path []string
|
||||
layer []byte
|
||||
}
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -23,16 +23,16 @@
|
|||
package directory
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/subspace"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type node struct {
|
||||
subspace subspace.Subspace
|
||||
path []string
|
||||
subspace subspace.Subspace
|
||||
path []string
|
||||
targetPath []string
|
||||
_layer fdb.FutureByteSlice
|
||||
_layer fdb.FutureByteSlice
|
||||
}
|
||||
|
||||
func (n *node) exists() bool {
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -53,7 +53,7 @@ func (e Error) Error() string {
|
|||
var (
|
||||
errNetworkNotSetup = Error{2008}
|
||||
|
||||
errAPIVersionUnset = Error{2200}
|
||||
errAPIVersionAlreadySet = Error{2201}
|
||||
errAPIVersionUnset = Error{2200}
|
||||
errAPIVersionAlreadySet = Error{2201}
|
||||
errAPIVersionNotSupported = Error{2203}
|
||||
)
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -30,11 +30,11 @@ package fdb
|
|||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
/* Would put this in futures.go but for the documented issue with
|
||||
|
@ -53,7 +53,7 @@ type Transactor interface {
|
|||
// Transact executes the caller-provided function, providing it with a
|
||||
// Transaction (itself a Transactor, allowing composition of transactional
|
||||
// functions).
|
||||
Transact(func (Transaction) (interface{}, error)) (interface{}, error)
|
||||
Transact(func(Transaction) (interface{}, error)) (interface{}, error)
|
||||
|
||||
// All Transactors are also ReadTransactors, allowing them to be used with
|
||||
// read-only transactional functions.
|
||||
|
@ -68,7 +68,7 @@ type ReadTransactor interface {
|
|||
// ReadTransact executes the caller-provided function, providing it with a
|
||||
// ReadTransaction (itself a ReadTransactor, allowing composition of
|
||||
// read-only transactional functions).
|
||||
ReadTransact(func (ReadTransaction) (interface{}, error)) (interface{}, error)
|
||||
ReadTransact(func(ReadTransaction) (interface{}, error)) (interface{}, error)
|
||||
}
|
||||
|
||||
func setOpt(setter func(*C.uint8_t, C.int) C.fdb_error_t, param []byte) error {
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -23,8 +23,8 @@
|
|||
package fdb_test
|
||||
|
||||
import (
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"fmt"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -52,7 +52,7 @@ func ExampleVersionstamp(t *testing.T) {
|
|||
fdb.MustAPIVersion(400)
|
||||
db := fdb.MustOpenDefault()
|
||||
|
||||
setVs := func(t fdb.Transactor, key fdb.Key ) (fdb.FutureKey, error) {
|
||||
setVs := func(t fdb.Transactor, key fdb.Key) (fdb.FutureKey, error) {
|
||||
fmt.Printf("setOne called with: %T\n", t)
|
||||
ret, e := t.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
tr.SetVersionstampedValue(key, []byte("blahblahbl"))
|
||||
|
@ -100,7 +100,7 @@ func ExampleTransactor() {
|
|||
setMany := func(t fdb.Transactor, value []byte, keys ...fdb.Key) error {
|
||||
fmt.Printf("setMany called with: %T\n", t)
|
||||
_, e := t.Transact(func(tr fdb.Transaction) (interface{}, error) {
|
||||
for _, key := range(keys) {
|
||||
for _, key := range keys {
|
||||
setOne(tr, key, value)
|
||||
}
|
||||
return nil, nil
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -41,9 +41,9 @@ package fdb
|
|||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
"sync"
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// A Future represents a value (or error) to be available at some later
|
||||
|
@ -253,7 +253,7 @@ type futureKeyValueArray struct {
|
|||
}
|
||||
|
||||
func stringRefToSlice(ptr unsafe.Pointer) []byte {
|
||||
size := *((*C.int)(unsafe.Pointer(uintptr(ptr)+8)))
|
||||
size := *((*C.int)(unsafe.Pointer(uintptr(ptr) + 8)))
|
||||
|
||||
if size == 0 {
|
||||
return []byte{}
|
||||
|
@ -278,13 +278,13 @@ func (f futureKeyValueArray) Get() ([]KeyValue, bool, error) {
|
|||
ret := make([]KeyValue, int(count))
|
||||
|
||||
for i := 0; i < int(count); i++ {
|
||||
kvptr := unsafe.Pointer(uintptr(unsafe.Pointer(kvs)) + uintptr(i * 24))
|
||||
kvptr := unsafe.Pointer(uintptr(unsafe.Pointer(kvs)) + uintptr(i*24))
|
||||
|
||||
ret[i].Key = stringRefToSlice(kvptr)
|
||||
ret[i].Value = stringRefToSlice(unsafe.Pointer(uintptr(kvptr) + 12))
|
||||
}
|
||||
|
||||
return ret, (more != 0), nil
|
||||
return ret, (more != 0), nil
|
||||
}
|
||||
|
||||
// FutureInt64 represents the asynchronous result of a function that returns a
|
||||
|
@ -361,7 +361,7 @@ func (f futureStringSlice) Get() ([]string, error) {
|
|||
ret := make([]string, int(count))
|
||||
|
||||
for i := 0; i < int(count); i++ {
|
||||
ret[i] = C.GoString((*C.char)(*(**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(strings))+uintptr(i*8)))))
|
||||
ret[i] = C.GoString((*C.char)(*(**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(strings)) + uintptr(i*8)))))
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -36,9 +36,9 @@ type Selectable interface {
|
|||
// below. For details of how KeySelectors are specified and resolved, see
|
||||
// https://foundationdb.org/documentation/developer-guide.html#key-selectors.
|
||||
type KeySelector struct {
|
||||
Key KeyConvertible
|
||||
Key KeyConvertible
|
||||
OrEqual bool
|
||||
Offset int
|
||||
Offset int
|
||||
}
|
||||
|
||||
func (ks KeySelector) FDBKeySelector() KeySelector {
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -34,7 +34,7 @@ import (
|
|||
|
||||
// KeyValue represents a single key-value pair in the database.
|
||||
type KeyValue struct {
|
||||
Key Key
|
||||
Key Key
|
||||
Value []byte
|
||||
}
|
||||
|
||||
|
@ -121,11 +121,11 @@ func (sr SelectorRange) FDBRangeKeySelectors() (Selectable, Selectable) {
|
|||
// A RangeResult should not be returned from a transactional function passed to
|
||||
// the Transact method of a Transactor.
|
||||
type RangeResult struct {
|
||||
t *transaction
|
||||
sr SelectorRange
|
||||
options RangeOptions
|
||||
t *transaction
|
||||
sr SelectorRange
|
||||
options RangeOptions
|
||||
snapshot bool
|
||||
f *futureKeyValueArray
|
||||
f *futureKeyValueArray
|
||||
}
|
||||
|
||||
// GetSliceWithError returns a slice of KeyValue objects satisfying the range
|
||||
|
@ -173,12 +173,12 @@ func (rr RangeResult) GetSliceOrPanic() []KeyValue {
|
|||
// range specified in the read that returned this RangeResult.
|
||||
func (rr RangeResult) Iterator() *RangeIterator {
|
||||
return &RangeIterator{
|
||||
t: rr.t,
|
||||
f: rr.f,
|
||||
sr: rr.sr,
|
||||
options: rr.options,
|
||||
t: rr.t,
|
||||
f: rr.f,
|
||||
sr: rr.sr,
|
||||
options: rr.options,
|
||||
iteration: 1,
|
||||
snapshot: rr.snapshot,
|
||||
snapshot: rr.snapshot,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,17 +193,17 @@ func (rr RangeResult) Iterator() *RangeIterator {
|
|||
// RangeResult and used concurrently. RangeIterator should not be returned from
|
||||
// a transactional function passed to the Transact method of a Transactor.
|
||||
type RangeIterator struct {
|
||||
t *transaction
|
||||
f *futureKeyValueArray
|
||||
sr SelectorRange
|
||||
options RangeOptions
|
||||
t *transaction
|
||||
f *futureKeyValueArray
|
||||
sr SelectorRange
|
||||
options RangeOptions
|
||||
iteration int
|
||||
done bool
|
||||
more bool
|
||||
kvs []KeyValue
|
||||
index int
|
||||
err error
|
||||
snapshot bool
|
||||
done bool
|
||||
more bool
|
||||
kvs []KeyValue
|
||||
index int
|
||||
err error
|
||||
snapshot bool
|
||||
}
|
||||
|
||||
// Advance attempts to advance the iterator to the next key-value pair. Advance
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -46,7 +46,7 @@ type Snapshot struct {
|
|||
//
|
||||
// See the ReadTransactor interface for an example of using ReadTransact with
|
||||
// Transaction, Snapshot and Database objects.
|
||||
func (s Snapshot) ReadTransact(f func (ReadTransaction) (interface{}, error)) (r interface{}, e error) {
|
||||
func (s Snapshot) ReadTransact(f func(ReadTransaction) (interface{}, error)) (r interface{}, e error) {
|
||||
defer panicToError(&e)
|
||||
|
||||
r, e = f(s)
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -33,10 +33,10 @@
|
|||
package subspace
|
||||
|
||||
import (
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/tuple"
|
||||
"bytes"
|
||||
"errors"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb/tuple"
|
||||
)
|
||||
|
||||
// Subspace represents a well-defined region of keyspace in a FoundationDB
|
||||
|
@ -134,7 +134,7 @@ func (s subspace) FDBRangeKeySelectors() (fdb.Selectable, fdb.Selectable) {
|
|||
}
|
||||
|
||||
func concat(a []byte, b ...byte) []byte {
|
||||
r := make([]byte, len(a) + len(b))
|
||||
r := make([]byte, len(a)+len(b))
|
||||
copy(r, a)
|
||||
copy(r[len(a):], b)
|
||||
return r
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -70,7 +70,7 @@ type Transaction struct {
|
|||
|
||||
type transaction struct {
|
||||
ptr *C.FDBTransaction
|
||||
db Database
|
||||
db Database
|
||||
}
|
||||
|
||||
// TransactionOptions is a handle with which to set options that affect a
|
||||
|
@ -110,7 +110,7 @@ func (t Transaction) GetDatabase() Database {
|
|||
//
|
||||
// See the Transactor interface for an example of using Transact with
|
||||
// Transaction and Database objects.
|
||||
func (t Transaction) Transact(f func (Transaction) (interface{}, error)) (r interface{}, e error) {
|
||||
func (t Transaction) Transact(f func(Transaction) (interface{}, error)) (r interface{}, e error) {
|
||||
defer panicToError(&e)
|
||||
|
||||
r, e = f(t)
|
||||
|
@ -260,11 +260,11 @@ func (t *transaction) getRange(r Range, options RangeOptions, snapshot bool) Ran
|
|||
f := t.doGetRange(r, options, snapshot, 1)
|
||||
begin, end := r.FDBRangeKeySelectors()
|
||||
return RangeResult{
|
||||
t: t,
|
||||
sr: SelectorRange{begin, end},
|
||||
options: options,
|
||||
t: t,
|
||||
sr: SelectorRange{begin, end},
|
||||
options: options,
|
||||
snapshot: snapshot,
|
||||
f: &f,
|
||||
f: &f,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,7 +402,7 @@ func (t Transaction) AddReadConflictRange(er ExactRange) error {
|
|||
}
|
||||
|
||||
func copyAndAppend(orig []byte, b byte) []byte {
|
||||
ret := make([]byte, len(orig) + 1)
|
||||
ret := make([]byte, len(orig)+1)
|
||||
copy(ret, orig)
|
||||
ret[len(orig)] = b
|
||||
return ret
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -35,9 +35,9 @@
|
|||
package tuple
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/binary"
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/apple/foundationdb/bindings/go/src/fdb"
|
||||
)
|
||||
|
||||
|
@ -68,33 +68,33 @@ type UUID [16]byte
|
|||
|
||||
// Type codes: These prefix the different elements in a packed Tuple
|
||||
// to indicate what type they are.
|
||||
const nilCode = 0x00
|
||||
const bytesCode = 0x01
|
||||
const stringCode = 0x02
|
||||
const nestedCode = 0x05
|
||||
const nilCode = 0x00
|
||||
const bytesCode = 0x01
|
||||
const stringCode = 0x02
|
||||
const nestedCode = 0x05
|
||||
const intZeroCode = 0x14
|
||||
const posIntEnd = 0x1c
|
||||
const posIntEnd = 0x1c
|
||||
const negIntStart = 0x0c
|
||||
const floatCode = 0x20
|
||||
const doubleCode = 0x21
|
||||
const falseCode = 0x26
|
||||
const trueCode = 0x27
|
||||
const uuidCode = 0x30
|
||||
const floatCode = 0x20
|
||||
const doubleCode = 0x21
|
||||
const falseCode = 0x26
|
||||
const trueCode = 0x27
|
||||
const uuidCode = 0x30
|
||||
|
||||
var sizeLimits = []uint64{
|
||||
1 << (0 * 8) - 1,
|
||||
1 << (1 * 8) - 1,
|
||||
1 << (2 * 8) - 1,
|
||||
1 << (3 * 8) - 1,
|
||||
1 << (4 * 8) - 1,
|
||||
1 << (5 * 8) - 1,
|
||||
1 << (6 * 8) - 1,
|
||||
1 << (7 * 8) - 1,
|
||||
1 << (8 * 8) - 1,
|
||||
1<<(0*8) - 1,
|
||||
1<<(1*8) - 1,
|
||||
1<<(2*8) - 1,
|
||||
1<<(3*8) - 1,
|
||||
1<<(4*8) - 1,
|
||||
1<<(5*8) - 1,
|
||||
1<<(6*8) - 1,
|
||||
1<<(7*8) - 1,
|
||||
1<<(8*8) - 1,
|
||||
}
|
||||
|
||||
func adjustFloatBytes(b []byte, encode bool) {
|
||||
if (encode && b[0] & 0x80 != 0x00) || (!encode && b[0] & 0x80 == 0x00) {
|
||||
if (encode && b[0]&0x80 != 0x00) || (!encode && b[0]&0x80 == 0x00) {
|
||||
// Negative numbers: flip all of the bytes.
|
||||
for i := 0; i < len(b); i++ {
|
||||
b[i] = b[i] ^ 0xff
|
||||
|
@ -131,11 +131,11 @@ func encodeInt(buf *bytes.Buffer, i int64) {
|
|||
switch {
|
||||
case i > 0:
|
||||
n = bisectLeft(uint64(i))
|
||||
buf.WriteByte(byte(intZeroCode+n))
|
||||
buf.WriteByte(byte(intZeroCode + n))
|
||||
binary.Write(&ibuf, binary.BigEndian, i)
|
||||
case i < 0:
|
||||
n = bisectLeft(uint64(-i))
|
||||
buf.WriteByte(byte(0x14-n))
|
||||
buf.WriteByte(byte(0x14 - n))
|
||||
binary.Write(&ibuf, binary.BigEndian, int64(sizeLimits[n])+i)
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ func encodeTuple(buf *bytes.Buffer, t Tuple, nested bool) {
|
|||
buf.WriteByte(nestedCode)
|
||||
}
|
||||
|
||||
for i, e := range(t) {
|
||||
for i, e := range t {
|
||||
switch e := e.(type) {
|
||||
case Tuple:
|
||||
encodeTuple(buf, e, true)
|
||||
|
@ -232,7 +232,7 @@ func findTerminator(b []byte) int {
|
|||
for {
|
||||
idx := bytes.IndexByte(bp, 0x00)
|
||||
length += idx
|
||||
if idx + 1 == len(bp) || bp[idx+1] != 0xFF {
|
||||
if idx+1 == len(bp) || bp[idx+1] != 0xFF {
|
||||
break
|
||||
}
|
||||
length += 2
|
||||
|
@ -276,7 +276,7 @@ func decodeInt(b []byte) (int64, int) {
|
|||
ret -= int64(sizeLimits[n])
|
||||
}
|
||||
|
||||
return ret, n+1
|
||||
return ret, n + 1
|
||||
}
|
||||
|
||||
func decodeFloat(b []byte) (float32, int) {
|
||||
|
@ -317,11 +317,11 @@ func decodeTuple(b []byte, nested bool) (Tuple, int, error) {
|
|||
if !nested {
|
||||
el = nil
|
||||
off = 1
|
||||
} else if i + 1 < len(b) && b[i+1] == 0xff {
|
||||
} else if i+1 < len(b) && b[i+1] == 0xff {
|
||||
el = nil
|
||||
off = 2
|
||||
} else {
|
||||
return t, i+1, nil
|
||||
return t, i + 1, nil
|
||||
}
|
||||
case b[i] == bytesCode:
|
||||
el, off = decodeBytes(b[i:])
|
||||
|
@ -330,12 +330,12 @@ func decodeTuple(b []byte, nested bool) (Tuple, int, error) {
|
|||
case negIntStart <= b[i] && b[i] <= posIntEnd:
|
||||
el, off = decodeInt(b[i:])
|
||||
case b[i] == floatCode:
|
||||
if i + 5 > len(b) {
|
||||
if i+5 > len(b) {
|
||||
return nil, i, fmt.Errorf("insufficient bytes to decode float starting at position %d of byte array for tuple", i)
|
||||
}
|
||||
el, off = decodeFloat(b[i:])
|
||||
case b[i] == doubleCode:
|
||||
if i + 9 > len(b) {
|
||||
if i+9 > len(b) {
|
||||
return nil, i, fmt.Errorf("insufficient bytes to decode double starting at position %d of byte array for tuple", i)
|
||||
}
|
||||
el, off = decodeDouble(b[i:])
|
||||
|
@ -346,7 +346,7 @@ func decodeTuple(b []byte, nested bool) (Tuple, int, error) {
|
|||
el = false
|
||||
off = 1
|
||||
case b[i] == uuidCode:
|
||||
if i + 17 > len(b) {
|
||||
if i+17 > len(b) {
|
||||
return nil, i, fmt.Errorf("insufficient bytes to decode UUID starting at position %d of byte array for tuple", i)
|
||||
}
|
||||
el, off = decodeUUID(b[i:])
|
||||
|
@ -401,7 +401,7 @@ func (t Tuple) FDBRangeKeySelectors() (fdb.Selectable, fdb.Selectable) {
|
|||
}
|
||||
|
||||
func concat(a []byte, b ...byte) []byte {
|
||||
r := make([]byte, len(a) + len(b))
|
||||
r := make([]byte, len(a)+len(b))
|
||||
copy(r, a)
|
||||
copy(r[len(a):], b)
|
||||
return r
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
# This source file is part of the FoundationDB open source project
|
||||
#
|
||||
# Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue