Class KeySpaceDirectory
- java.lang.Object
-
- com.apple.foundationdb.record.provider.foundationdb.keyspace.KeySpaceDirectory
-
- Direct Known Subclasses:
DirectoryLayerDirectory
@API(MAINTAINED) public class KeySpaceDirectory extends Object
Defines a directory within aKeySpace
.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
KeySpaceDirectory.KeyType
The available data types for directories.
-
Field Summary
Fields Modifier and Type Field Description static Object
ANY_VALUE
The value of a directory that may contain any value of the type specified for the directory (as opposed to a directory that is restricted to a specific constant value).protected static CompletableFuture<Optional<ResolvedKeySpacePath>>
DIRECTORY_NOT_FOR_KEY
Return value frompathFromKey
to indicate that a given tuple value is not appropriate for a given directory.protected KeySpaceDirectory.KeyType
keyType
protected String
name
protected KeySpaceDirectory
parent
protected List<KeySpaceDirectory>
subdirs
protected Map<String,KeySpaceDirectory>
subdirsByName
protected Object
value
protected Function<KeySpacePath,KeySpacePath>
wrapper
-
Constructor Summary
Constructors Constructor Description KeySpaceDirectory(String name, KeySpaceDirectory.KeyType keyType)
Creates a directory that can hold any value of a given type.KeySpaceDirectory(String name, KeySpaceDirectory.KeyType keyType, Object value)
KeySpaceDirectory(String name, KeySpaceDirectory.KeyType keyType, Object value, Function<KeySpacePath,KeySpacePath> wrapper)
Creates a directory.KeySpaceDirectory(String name, KeySpaceDirectory.KeyType keyType, Function<KeySpacePath,KeySpacePath> wrapper)
Creates a directory that can hold any value of a given type.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description KeySpaceDirectory
addSubdirectory(KeySpaceDirectory subdirectory)
Adds a subdirectory within the directory.protected static boolean
areEqual(Object o1, Object o2)
int
depth()
Get the depth in the directory tree of this directory.protected CompletableFuture<ResolvedKeySpacePath>
findChildForKey(FDBRecordContext context, ResolvedKeySpacePath parent, Tuple key, int keySize, int keyIndex)
Iterates over the subdirectories of this directory looking for one that is compatible with thekey
tuple, starting at positionkeyIndex
.CompletableFuture<ResolvedKeySpacePath>
findChildForValue(FDBRecordContext context, ResolvedKeySpacePath parent, Object value)
Iterates over the subdirectories of this directory looking for one that is compatible with the given value.KeySpaceDirectory.KeyType
getKeyType()
Returns the type of values this directory stores.String
getName()
Returns the name of this directory.String
getNameInTree()
When displaying the name of this directory in the tree output fromtoString()
allows the directory implementation to ornament the name in any fashion it sees fit.KeySpaceDirectory
getParent()
Returns this directory's parent.List<KeySpaceDirectory>
getSubdirectories()
Returns the set of subdirectories contained within this directory.KeySpaceDirectory
getSubdirectory(String name)
Retrieves a subdirectory.Object
getValue()
Returns the constant value that this directory stores.protected boolean
isCompatible(KeySpaceDirectory parent, KeySpaceDirectory dir)
When a subdirectory is being added to a directory and an existing subdirectory is found that stores the same data type but with a different constant value, this method will be called both on the directory being added as well as the existing subdirectory to allow them to determine if they are compatible with each other.boolean
isLeaf()
Returns whether or not the directory is a leaf directory (has no subdirectories).protected RecordCursor<ResolvedKeySpacePath>
listSubdirectoryAsync(KeySpacePath listFrom, FDBRecordContext context, String subdirName, byte[] continuation, ScanProperties scanProperties)
protected RecordCursor<ResolvedKeySpacePath>
listSubdirectoryAsync(KeySpacePath listFrom, FDBRecordContext context, String subdirName, ValueRange<?> valueRange, byte[] continuation, ScanProperties scanProperties)
protected CompletableFuture<ResolvedKeySpacePath>
nextChildForKey(int childIndex, FDBRecordContext context, ResolvedKeySpacePath parent, Tuple key, int keySize, int keyIndex)
protected CompletableFuture<Optional<ResolvedKeySpacePath>>
pathFromKey(FDBRecordContext context, ResolvedKeySpacePath parent, Tuple key, int keySize, int keyIndex)
Given a position in a tuple, checks to see if this directory is compatible with the value at the position, returning either a path indicating that it was compatible or nothing if it was not compatible.String
toPathString()
Returns the path that leads up to this directory (including this directory), and returns it as a string that looks something like a filesystem path.String
toString()
void
toTree(Writer out)
Sends the keyspace as an ascii-art tree to an output stream.protected PathValue
toTupleValue(FDBRecordContext context, Object value)
protected CompletableFuture<PathValue>
toTupleValueAsync(FDBRecordContext context, Object value)
Asks the directory implementation to "resolve" a tuple value.protected CompletableFuture<PathValue>
toTupleValueAsyncImpl(FDBRecordContext context, Object value)
This method is called during the process of turning aKeySpacePath
into aTuple
.protected void
validateConstant(Object value)
Called during creation to validate that the constant value provided is of a valid type for this directory.protected Object
validateResolvedValue(Object value)
Ensures that a value is suitable to be stored within this directory.protected KeySpacePath
wrap(KeySpacePath path)
If awrapper
was installed for this directory, the providedpath
will be wrapped by thewrapper
and returned, otherwise the originalpath
is returned.
-
-
-
Field Detail
-
DIRECTORY_NOT_FOR_KEY
protected static final CompletableFuture<Optional<ResolvedKeySpacePath>> DIRECTORY_NOT_FOR_KEY
Return value frompathFromKey
to indicate that a given tuple value is not appropriate for a given directory.
-
ANY_VALUE
public static final Object ANY_VALUE
The value of a directory that may contain any value of the type specified for the directory (as opposed to a directory that is restricted to a specific constant value).
-
parent
@Nullable protected KeySpaceDirectory parent
-
keyType
@Nonnull protected final KeySpaceDirectory.KeyType keyType
-
subdirsByName
@Nonnull protected final Map<String,KeySpaceDirectory> subdirsByName
-
subdirs
@Nonnull protected final List<KeySpaceDirectory> subdirs
-
wrapper
@Nullable protected Function<KeySpacePath,KeySpacePath> wrapper
-
-
Constructor Detail
-
KeySpaceDirectory
public KeySpaceDirectory(@Nonnull String name, @Nonnull KeySpaceDirectory.KeyType keyType, @Nullable Object value, @Nullable Function<KeySpacePath,KeySpacePath> wrapper)
Creates a directory. The wrapper is useful if you want to decorate the path with additional functionality, such as the ability to retrieve a child path element via an explicit function name rather than a string constant (e.g.getEmployeePath(int id)
).- Parameters:
name
- the name of the directorykeyType
- the data type of the values that may be contained within the directoryvalue
- avalue
ofANY_VALUE
indicates that any value of the specified type may be stored in the directory, otherwise specifies a constant value that represents the directorywrapper
- if non-null, specifies a function that may be used to wrap anyKeySpacePath
objects return fromKeySpace.pathFromKey(FDBRecordContext, Tuple)
- Throws:
RecordCoreArgumentException
- if the provided value constant value is not valid for the type of directory being created
-
KeySpaceDirectory
public KeySpaceDirectory(@Nonnull String name, @Nonnull KeySpaceDirectory.KeyType keyType, @Nullable Function<KeySpacePath,KeySpacePath> wrapper)
Creates a directory that can hold any value of a given type. The wrapper is useful if you want to decorate the path with additional functionality, such as the ability to retrieve a child path element via an explicit function name rather than a string constant (e.g.getEmployeePath(int id)
).- Parameters:
name
- the name of the directorykeyType
- the data type of the values that may be contained within the directorywrapper
- if non-null, specifies a function that may be used to wrap anyKeySpacePath
objects returned fromKeySpace.pathFromKey(FDBRecordContext, Tuple)
-
KeySpaceDirectory
public KeySpaceDirectory(@Nonnull String name, @Nonnull KeySpaceDirectory.KeyType keyType)
Creates a directory that can hold any value of a given type.- Parameters:
name
- the name of the directorykeyType
- the data type of the values that may be contained within the directory
-
-
Method Detail
-
depth
public int depth()
Get the depth in the directory tree of this directory.- Returns:
- the depth in the directory tree of this directory
-
validateConstant
protected void validateConstant(@Nullable Object value)
Called during creation to validate that the constant value provided is of a valid type for this directory.- Parameters:
value
- constant value to validate
-
pathFromKey
@Nonnull protected CompletableFuture<Optional<ResolvedKeySpacePath>> pathFromKey(@Nonnull FDBRecordContext context, @Nullable ResolvedKeySpacePath parent, @Nonnull Tuple key, int keySize, int keyIndex)
Given a position in a tuple, checks to see if this directory is compatible with the value at the position, returning either a path indicating that it was compatible or nothing if it was not compatible. This method allows overriding implementations to consume as much or as little of the tuple as necessary (for example, you could have a directory that needed two tuple elements to represent itself) or to have finer grained control over how theKeySpacePath
for itself is constructed. If key size if less than the actual key length, the path remainder will reflect the left over key elements.- Parameters:
context
- the database contextparent
- the parent path elementkey
- the tuple being parsedkeySize
- the logical key size.keyIndex
- the position in the index being parsed- Returns:
- the
KeySpacePath
representing the leaf-most path for the providedkey
orOptional.empty()
if this directory is not compatible with the element atkeyIndex
position in thekey
-
findChildForValue
@Nonnull public CompletableFuture<ResolvedKeySpacePath> findChildForValue(@Nonnull FDBRecordContext context, @Nullable ResolvedKeySpacePath parent, @Nullable Object value)
Iterates over the subdirectories of this directory looking for one that is compatible with the given value.- Parameters:
context
- the database contextparent
- the parent path elementvalue
- the child value to be resolved- Returns:
- a future that completes with the matching keyspace path
- Throws:
RecordCoreArgumentException
- if no compatible child can be found
-
findChildForKey
@Nonnull protected CompletableFuture<ResolvedKeySpacePath> findChildForKey(@Nonnull FDBRecordContext context, @Nullable ResolvedKeySpacePath parent, @Nonnull Tuple key, int keySize, int keyIndex)
Iterates over the subdirectories of this directory looking for one that is compatible with thekey
tuple, starting at positionkeyIndex
. If the key size is less than the actual key length, the path remainder will reflect the left over key elements.- Parameters:
context
- the database contextparent
- the parent path elementkey
- the tuple being parsedkeySize
- the logical key sizekeyIndex
- the position in the index being parsed- Returns:
- a future that completes with the matching keyspace path
- Throws:
RecordCoreArgumentException
- if no compatible child can be found
-
nextChildForKey
protected CompletableFuture<ResolvedKeySpacePath> nextChildForKey(int childIndex, @Nonnull FDBRecordContext context, @Nullable ResolvedKeySpacePath parent, @Nonnull Tuple key, int keySize, int keyIndex)
-
addSubdirectory
@Nonnull public KeySpaceDirectory addSubdirectory(@Nonnull KeySpaceDirectory subdirectory)
Adds a subdirectory within the directory.- Parameters:
subdirectory
- the subdirectory to add- Returns:
- this directory
- Throws:
RecordCoreArgumentException
- if a subdirectory of the same name already exists, or a subdirectory of the same type already exists with the same constant value
-
isCompatible
protected boolean isCompatible(@Nonnull KeySpaceDirectory parent, @Nonnull KeySpaceDirectory dir)
When a subdirectory is being added to a directory and an existing subdirectory is found that stores the same data type but with a different constant value, this method will be called both on the directory being added as well as the existing subdirectory to allow them to determine if they are compatible with each other. A concrete example use case for this is theDirectoryLayerDirectory
: let's say we had something like:dir.addSubdirectory(new DirectoryLayerDirectory("dir1", "constValue")) .addSubdirectory(new KeySpaceDirectory("dir2", KeyType.LONG, 1)
In this case, we are adding two directories which are of the same type, LONG (DirectorylayerDirectory
is implicitly of type long) and, although, the two appear to have different constant values and, thus, should be compatible with each other, theDirectoryLayerDirectory
dynamically converts it's"constValue"
into a LONG and, thus, could end up colliding with the constant value of1
used for"dir2"
. To prevent this, theDirectoryLayerDirectory
must override this method to block any peer that isn't also aDirectorylayerDirectory
. If this directory is being added toparent
, thendir
is the existing peer that has the same storage data type but a different constant value. If this directory already exists inparent
, thendir
is a new peer that is being added that has the same data type but a different constant value.- Parameters:
parent
- the parent directory in which a subdirectory is being addeddir
- the existing peer directory- Returns:
- true if the directories can co-exist, false otherwise
-
isLeaf
public boolean isLeaf()
Returns whether or not the directory is a leaf directory (has no subdirectories).- Returns:
- true if the directory is a leaf directory, false otherwise
-
getSubdirectory
@Nonnull public KeySpaceDirectory getSubdirectory(@Nonnull String name)
Retrieves a subdirectory.- Parameters:
name
- the name of the subdirectory to return- Returns:
- the subdirectory with the specified
name
- Throws:
NoSuchDirectoryException
- if the directory does not exist
-
wrap
@Nonnull protected KeySpacePath wrap(@Nonnull KeySpacePath path)
If awrapper
was installed for this directory, the providedpath
will be wrapped by thewrapper
and returned, otherwise the originalpath
is returned.- Parameters:
path
- the path to be wrapped- Returns:
- the wrapped path or the path provided if no wrapper is installed
-
listSubdirectoryAsync
@Nonnull protected RecordCursor<ResolvedKeySpacePath> listSubdirectoryAsync(@Nullable KeySpacePath listFrom, @Nonnull FDBRecordContext context, @Nonnull String subdirName, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties)
-
listSubdirectoryAsync
@Nonnull protected RecordCursor<ResolvedKeySpacePath> listSubdirectoryAsync(@Nullable KeySpacePath listFrom, @Nonnull FDBRecordContext context, @Nonnull String subdirName, @Nullable ValueRange<?> valueRange, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties)
-
getSubdirectories
@Nonnull public List<KeySpaceDirectory> getSubdirectories()
Returns the set of subdirectories contained within this directory.- Returns:
- the set of subdirectories contained within this directory
-
toTupleValueAsync
@Nonnull protected final CompletableFuture<PathValue> toTupleValueAsync(@Nonnull FDBRecordContext context, @Nullable Object value)
Asks the directory implementation to "resolve" a tuple value. The meaning of resolve can vary amongst different types of directorys but, for example, theDirectoryLayerDirectory
would be expecting the value to be aString
and would use the directory layer to then convert it into aLong
.- Parameters:
context
- the context in which to perform the resolutionvalue
- the value to be resolved- Returns:
- a future containing the resolved value
-
toTupleValue
@Nullable protected PathValue toTupleValue(@Nonnull FDBRecordContext context, @Nullable Object value)
-
toTupleValueAsyncImpl
@Nonnull protected CompletableFuture<PathValue> toTupleValueAsyncImpl(@Nonnull FDBRecordContext context, @Nullable Object value)
This method is called during the process of turning aKeySpacePath
into aTuple
. This method should never be directly invoked from anything other thantoTupleValueAsync
, it is purely intended for newKeySpaceDirectory
implementations to override.- Parameters:
context
- the context in which the tuple is being constructedvalue
- the value that was provided to be stored in this directory- Returns:
- a future that will result in the value to be physically stored for the provided input
value
- Throws:
RecordCoreArgumentException
- if the value provided for this directory is incompatible with the definition of this directory
-
validateResolvedValue
@Nullable protected Object validateResolvedValue(@Nullable Object value)
Ensures that a value is suitable to be stored within this directory.- Parameters:
value
- the value to be stored in this directory- Returns:
- the
value
- Throws:
RecordCoreArgumentException
- if the value is not suitable for storing in this directory
-
getParent
@Nullable public KeySpaceDirectory getParent()
Returns this directory's parent.- Returns:
- this directory's parent, or
null
if there is no parent
-
getName
@Nonnull public String getName()
Returns the name of this directory.- Returns:
- the name of this directory
-
getNameInTree
@Nonnull public String getNameInTree()
When displaying the name of this directory in the tree output fromtoString()
allows the directory implementation to ornament the name in any fashion it sees fit.- Returns:
- the display name of the directory in the tree output
-
getKeyType
@Nonnull public KeySpaceDirectory.KeyType getKeyType()
Returns the type of values this directory stores.- Returns:
- the type of values this directory stores
-
getValue
@Nullable public Object getValue()
Returns the constant value that this directory stores. A return value ofANY_VALUE
indicates that this directory may contain any value of the type indicated bygetKeyType()
- Returns:
- the constant value that this directory stores
-
toPathString
public String toPathString()
Returns the path that leads up to this directory (including this directory), and returns it as a string that looks something like a filesystem path.- Returns:
- the path to this directory as a string
-
toTree
public void toTree(Writer out) throws IOException
Sends the keyspace as an ascii-art tree to an output stream.- Parameters:
out
- the print destination- Throws:
IOException
- if there is a problem with the destination
-
-