Class KeySpaceDirectory

    • 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 directory
        keyType - the data type of the values that may be contained within the directory
        value - a value of ANY_VALUE indicates that any value of the specified type may be stored in the directory, otherwise specifies a constant value that represents the directory
        wrapper - if non-null, specifies a function that may be used to wrap any KeySpacePath objects return from KeySpace.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 directory
        keyType - the data type of the values that may be contained within the directory
        wrapper - if non-null, specifies a function that may be used to wrap any KeySpacePath objects returned from KeySpace.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 directory
        keyType - 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 the KeySpacePath 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 context
        parent - the parent path element
        key - the tuple being parsed
        keySize - the logical key size.
        keyIndex - the position in the index being parsed
        Returns:
        the KeySpacePath representing the leaf-most path for the provided key or Optional.empty() if this directory is not compatible with the element at keyIndex position in the key
      • 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 the key tuple, starting at position keyIndex. 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 context
        parent - the parent path element
        key - the tuple being parsed
        keySize - the logical key size
        keyIndex - 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
      • 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 the DirectoryLayerDirectory: 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, the DirectoryLayerDirectory dynamically converts it's "constValue" into a LONG and, thus, could end up colliding with the constant value of 1 used for "dir2". To prevent this, the DirectoryLayerDirectory must override this method to block any peer that isn't also a DirectorylayerDirectory. If this directory is being added to parent, then dir is the existing peer that has the same storage data type but a different constant value. If this directory already exists in parent, then dir 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 added
        dir - 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
      • wrap

        @Nonnull
        protected KeySpacePath wrap​(@Nonnull
                                    KeySpacePath path)
        If a wrapper was installed for this directory, the provided path will be wrapped by the wrapper and returned, otherwise the original path is returned.
        Parameters:
        path - the path to be wrapped
        Returns:
        the wrapped path or the path provided if no wrapper is installed
      • 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, the DirectoryLayerDirectory would be expecting the value to be a String and would use the directory layer to then convert it into a Long.
        Parameters:
        context - the context in which to perform the resolution
        value - the value to be resolved
        Returns:
        a future containing the resolved value
      • toTupleValueAsyncImpl

        @Nonnull
        protected CompletableFuture<PathValue> toTupleValueAsyncImpl​(@Nonnull
                                                                     FDBRecordContext context,
                                                                     @Nullable
                                                                     Object value)
        This method is called during the process of turning a KeySpacePath into a Tuple. This method should never be directly invoked from anything other than toTupleValueAsync, it is purely intended for new KeySpaceDirectory implementations to override.
        Parameters:
        context - the context in which the tuple is being constructed
        value - 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 from toString() 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 of ANY_VALUE indicates that this directory may contain any value of the type indicated by getKeyType()
        Returns:
        the constant value that this directory stores
      • areEqual

        protected static boolean areEqual​(Object o1,
                                          Object o2)
      • 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