text:
//   Copyright 2004-2014 Jim Voris
//
//   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.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
package com.qumasoft.server;

import com.qumasoft.qvcslib.ArchiveDirManagerFactory;
import com.qumasoft.qvcslib.ArchiveDirManagerInterface;
import com.qumasoft.qvcslib.LogFile;
import com.qumasoft.qvcslib.QVCSException;
import com.qumasoft.qvcslib.QVCSServedProjectNamesFilter;
import com.qumasoft.qvcslib.ServedProjectProperties;
import com.qumasoft.qvcslib.ServerResponseFactoryInterface;
import com.qumasoft.qvcslib.Utility;
import java.io.File;
import java.io.IOException;

import java.net.ServerSocket;
import java.nio.charset.Charset;
import java.util.Set;
import javax.net.ssl.SSLServerSocket;

import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocketFactory;

import java.net.Socket;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.logging.LogManager;

import com.qumasoft.qvcslib.ArchiveDigestManager;
import com.qumasoft.qvcslib.ArchiveDirManager;
import com.qumasoft.qvcslib.QVCSConstants;
import com.qumasoft.qvcslib.ServerResponseFactory;
import com.qumasoft.qvcslib.ServerResponseFactoryBaseClass;
import com.qumasoft.qvcslib.SerializableObjectInterface;
import com.qumasoft.qvcslib.ServerResponseLogin;
import com.qumasoft.qvcslib.ServerResponseMessage;
import com.qumasoft.qvcslib.VanillaServerResponseFactory;

import com.qumasoft.webserver.WebServer;

/**
 *
 * @author  $Author$
 */
public class QVCSEnterpriseServer
{
    // Capture the version of the server.
    private static final String m_Version = "$Label$";

    static final int DEFAULT_VANILLA_LISTEN_PORT    = 9887;
    static final int DEFAULT_NON_SECURE_LISTEN_PORT = 9888;
    static final int DEFAULT_SECURE_LISTEN_PORT     = 9889;
    static final int DEFAULT_ADMIN_LISTEN_PORT      = 9890;
    static final String WEB_SERVER_PORT             = "9080";

    static final int m_workerThreads = 50;

    private int m_VanillaPort   = DEFAULT_VANILLA_LISTEN_PORT;
    private int m_NonSecurePort = DEFAULT_NON_SECURE_LISTEN_PORT;
    private int m_SecurePort    = DEFAULT_SECURE_LISTEN_PORT;
    private int m_AdminPort     = DEFAULT_ADMIN_LISTEN_PORT;

    private String m_QVCSHomeDirectory = null;
    private String m_args[];

    /* Where worker threads stand idle */
    final Vector<Runnable> m_Threads = new Vector<Runnable>();
    final Vector<Runnable> m_VanillaThreads = new Vector<Runnable>();
    int m_ThreadCount = 1;

    VanillaServer m_VanillaServer = null;
    NonSecureServer m_nonSecureServer = null;
    SecureServer m_secureServer = null;
    SecureServer m_adminServer = null;
    QVCSWebServer m_webServer = null;

    // Server socket listener threads.
    Thread m_VanillaThread   = null;
    Thread m_NonSecureThread = null;
    Thread m_SecureThread    = null;
    Thread m_AdminThread     = null;

    // Web server thread.
    Thread m_WebServerThread = null;

    static private QVCSEnterpriseServer m_Server;

    // Create our logger object
    private static Logger m_logger = Logger.getLogger("com.qumasoft.server");

    static final List<ServerResponseFactoryInterface>  connectedUsersCollection = Collections.synchronizedList(new ArrayList<ServerResponseFactoryInterface>());

    public static void main (String args[])
    {
        QVCSEnterpriseServer server = new QVCSEnterpriseServer(args);
        server.startServer();
    }

    public static Collection getConnectedUsers()
    {
        Vector<ServerResponseFactoryInterface> collection = null;
        synchronized (connectedUsersCollection)
        {
            collection = new Vector<ServerResponseFactoryInterface>();
            Iterator<ServerResponseFactoryInterface> it = connectedUsersCollection.iterator();
            while (it.hasNext())
            {
                collection.add(it.next());
            }
        }
        return collection;
    }

    private Collection<ServerResponseFactoryInterface> getConnectedUsersCollection()
    {
        return connectedUsersCollection;
    }

    public static void setShutdownInProgress(boolean flag)
    {
        if (flag)
        {
            m_logger.log(Level.INFO, "QVCS Enterprise Server is exiting.");

            if (m_Server.m_VanillaThread != null)
            {
                m_Server.m_VanillaServer.closeServerSocket();
            }
            if (m_Server.m_NonSecureThread != null)
            {
                m_Server.m_nonSecureServer.closeServerSocket();
            }
            if (m_Server.m_SecureThread != null)
            {
                m_Server.m_secureServer.closeServerSocket();
            }
            if (m_Server.m_AdminThread != null)
            {
                m_Server.m_adminServer.closeServerSocket();
            }
        }
    }

    /** Creates a new instance of QVCSEnterpriseServer
     * @param args command line arguments.
     */
    public QVCSEnterpriseServer(String[] args)
    {
        m_args = args;
        m_Server = this;
        if (m_args.length > 0)
        {
            System.setProperty("user.dir", m_args[0]);
            m_QVCSHomeDirectory = m_args[0];
        }
    }

    public void startServer()
    {

        try
        {
            if (m_args.length > 1)
            {
                m_VanillaPort = Integer.parseInt(m_args[1]);
            }
        }
        catch (NumberFormatException e)
        {
            m_VanillaPort = DEFAULT_VANILLA_LISTEN_PORT;
        }

        try
        {
            if (m_args.length > 2)
            {
                m_NonSecurePort = Integer.parseInt(m_args[2]);
            }
        }
        catch (NumberFormatException e)
        {
            m_NonSecurePort = DEFAULT_NON_SECURE_LISTEN_PORT;
        }

        try
        {
            if (m_args.length > 3)
            {
                m_SecurePort = Integer.parseInt(m_args[3]);
            }
        }
        catch (NumberFormatException e)
        {
            m_SecurePort = DEFAULT_SECURE_LISTEN_PORT;
        }

        try
        {
            if (m_args.length > 4)
            {
                m_AdminPort = Integer.parseInt(m_args[4]);
            }
        }
        catch (NumberFormatException e)
        {
            m_AdminPort = DEFAULT_ADMIN_LISTEN_PORT;
        }

        // Init the logging properties.
        initLoggingProperties();

        // Report the System info.
        reportSystemInfo();

        m_logger.log(Level.INFO, "QVCS Enterprise Server Version: '" + m_Version + "'.");
        m_logger.log(Level.INFO, "QVCS Enterprise Server running with " + Runtime.getRuntime().availableProcessors() + " available processors.");

        // Initialize the role privileges manager
        RolePrivilegesManager.getInstance().initialize();

        // Initialize the role manager.
        RoleManager.getRoleManager().initialize();

        // Initialize the authentication manager.
        AuthenticationManager.getAuthenticationManager().initialize();

        // Initialize the archive digest manager.
        ArchiveDigestManager.getInstance().initialize(QVCSConstants.QVCS_SERVED_PROJECT_TYPE);

        // Initialize the file ID manager.
        FileIDManager.getInstance().initialize();

        // See if we need to scan for fileID, etc.
        if (FileIDManager.getInstance().getFileIDResetRequiredFlag())
        {
            // Remove the label manager store.
            DirectoryContentsLabelManager.getInstance().resetStore();
            DirectoryContentsLabelManager.getInstance().initialize();

            // Reset the directory id dictionary store.
            DirectoryIDDictionary.getInstance().resetStore();
            DirectoryIDDictionary.getInstance().initialize();

            // Reset the directoryID store.
            DirectoryIDManager.getInstance().resetStore();
            DirectoryIDManager.getInstance().initialize();

            // Reset the file id dictionary store.
            FileIDDictionary.getInstance().resetStore();
            FileIDDictionary.getInstance().initialize();

            // Remove the view manager store.
            ViewManager.getInstance().resetStore();
            ViewManager.getInstance().initialize();

            // We need to reset all file IDs.
            resetFileIDs();
            FileIDManager.getInstance().setFileIDResetRequiredFlag(false);

            // Reset the directory IDs. Note that directory ID's are
            // per project, so there are separate maximum values for each separate
            // project.
            resetDirectoryIDs();

            // Initialize our DirectoryContents objects.
            initializeDirectoryContentsObjects();
        }
        else
        {
            // Initialize the DirectoryIDDictionary.
            DirectoryIDDictionary.getInstance().initialize();

            // Initialize the FileIDDictionary.
            FileIDDictionary.getInstance().initialize();

            // Initialize the directoryID manager.
            DirectoryIDManager.getInstance().initialize();

            // Initialize the LabelHistory manager.
            DirectoryContentsLabelManager.getInstance().initialize();

            // Initialize the ViewManager.
            ViewManager.getInstance().initialize();
        }

        // Register our shutdown thread.
        Runtime.getRuntime().addShutdownHook(new QVCSEnterpriseServer.ShutdownThread());

        // Initialize the Activity Journal Manager.
        ActivityJournalManager.getInstance().initialize();
        ActivityJournalManager.getInstance().addJournalEntry("QVCS-Enterprise Server is starting.  Server Version: " + m_Version + ".");

        // Launch four separate listener threads; one for vanilla connections,
        // one for non-secure requests,
        // one for secure requests, and a fourth for admin messages.
        m_VanillaServer   = new VanillaServer(m_VanillaPort);
        m_nonSecureServer = new NonSecureServer(m_NonSecurePort);
        m_secureServer    = new SecureServer(m_SecurePort);
        m_adminServer     = new SecureServer(m_AdminPort);
        m_webServer       = new QVCSWebServer(m_args);

        m_VanillaThread   = new Thread(m_VanillaServer, "vanilla server");
        m_NonSecureThread = new Thread(m_nonSecureServer, "non secure server");
        m_SecureThread    = new Thread(m_secureServer, "secure server");
        m_AdminThread     = new Thread(m_adminServer, "admin server");
        m_WebServerThread = new Thread(m_webServer, "web server");

        m_VanillaThread.start();
        m_NonSecureThread.start();
        m_SecureThread.start();
        m_AdminThread.start();
        m_WebServerThread.start();

        try
        {
            // Wait for all the worker threads to exit.  When a worker thread
            // exits, it calls notify on the m_Threads object.
            synchronized (m_Threads)
            {
                while (m_Threads.size() > 0)
                {
                    m_Threads.wait();
                }
            }

            synchronized (m_VanillaThreads)
            {
                while (m_VanillaThreads.size() > 0)
                {
                    m_VanillaThreads.wait();
                }
            }

            m_VanillaThread.join();
            m_NonSecureThread.join();
            m_SecureThread.join();
            m_AdminThread.join();

            // Kill the web server.
            m_WebServerThread.interrupt();
        }
        catch (Exception e)
        {
            m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
        }
        finally
        {
            ActivityJournalManager.getInstance().addJournalEntry("QVCS-Enterprise Server is shutting down.");
            ArchiveDigestManager.getInstance().writeStore();
            DirectoryIDManager.getInstance().writeStore();
            FileIDManager.getInstance().writeStore();
            DirectoryContentsLabelManager.getInstance().writeStore();
            DirectoryIDDictionary.getInstance().writeStore();
            FileIDDictionary.getInstance().writeStore();
            ActivityJournalManager.getInstance().closeJournal();
            m_logger.log(Level.INFO, "QVCS Enterprise Server exit complete.");
            System.out.println("QVCS Enterprise Server exit complete.");
            System.exit(0);
        }
    }

    public static void stopServer(String args[])
    {
        m_logger.log(Level.INFO, "QVCS Enterprise Server Windows Service beginning shutdown.");
        ServerResponseFactoryBaseClass.setShutdownInProgress(true);
    }

    private void initLoggingProperties()
    {
        try
        {
            String logConfigFile = m_QVCSHomeDirectory + File.separator + "serverLogging.properties";
            System.setProperty("java.util.logging.config.file", logConfigFile);
            LogManager.getLogManager().readConfiguration();
        }
        catch (Exception e)
        {
            m_logger.log(Level.SEVERE, "Caught exception: " + e.getClass().toString() + " : " + e.getLocalizedMessage());
            System.out.println("Caught exception: " + e.getClass().toString() + " : " + e.getLocalizedMessage());
        }
    }

    private void reportSystemInfo()
    {
        java.util.Properties systemProperties = System.getProperties();
        java.util.Set keys = systemProperties.keySet();
        java.util.Iterator it = keys.iterator();
        m_logger.log(Level.FINE, "System properties:");
        while(it.hasNext())
        {
            String key = (String)it.next();
            String message = key + " = " + System.getProperty(key);
            m_logger.log(Level.FINE, message);
        }

        // Log what charset is the platform default
        m_logger.log(Level.FINE, "Default charset: " + Charset.defaultCharset().displayName());
    }

    /** This method is called before the server opens any ports to listen
     * for client connections... The goal is to reset the file ids for all files in all
     * existing projects. We do not use the ArchiveDirManager class here
     * as that is heavier-weight than what we want/need to do here.
     */
    private void resetFileIDs()
    {
        m_logger.log(Level.INFO, "QVCSEnterpriseServer: reseting all file id's for all projects.");

        try
        {
            // Get a list of all the projects that this server serves...
            ServedProjectProperties[] projectPropertiesList = getServedProjectPropertiesList();

            // Iterate over the list of projects...
            for (int i = 0; i < projectPropertiesList.length; i++)
            {
                String archiveLocation = projectPropertiesList[i].getArchiveLocation();
                File projectBaseDirectory = new File(archiveLocation);
                resetFileIDsForProjectDirectoryTree(projectBaseDirectory);
            }
        }
        catch (Exception e)
        {
            m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
        }
    }

    /** For use before the server accepts clients connections only!!
     */
    private ServedProjectProperties[] getServedProjectPropertiesList()
    {
        ServedProjectProperties[] servedProjectsProperties = new ServedProjectProperties[0];

        // Where all the property files can be found...
        File propertiesDirectory = new File(System.getProperty("user.dir") +
                                            System.getProperty("file.separator") +
                                            QVCSConstants.QVCS_PROPERTIES_DIRECTORY);

        QVCSServedProjectNamesFilter servedProjectNamesFilter = new QVCSServedProjectNamesFilter();
        File[] servedProjectFiles = propertiesDirectory.listFiles(servedProjectNamesFilter);
        if (servedProjectFiles != null)
        {
            servedProjectsProperties = new ServedProjectProperties[servedProjectFiles.length];

            for (int i = 0; i < servedProjectFiles.length; i++)
            {
                String projectName = servedProjectNamesFilter.getProjectName(servedProjectFiles[i].getName());
                try
                {
                    ServedProjectProperties projectProperties = new ServedProjectProperties(projectName);
                    servedProjectsProperties[i] = new ServedProjectProperties(projectName);
                }
                catch (Exception e)
                {
                    m_logger.log(Level.WARNING, "Error finding served project names for project: '" + projectName + "'.");
                }
            }
        }
        return servedProjectsProperties;
    }

    /**
     * For use by the resetFileIDs() method only!!  Reset fileIDs for the given directory tree.
     */
    private void resetFileIDsForProjectDirectoryTree(File directory)
    {
        m_logger.log(Level.INFO, "Reseting file id's for directory: " + directory.getAbsolutePath());

        File[] fileList = directory.listFiles();

        if (fileList != null)
        {
            for (int i = 0; i < fileList.length; i++)
            {
                if (fileList[i].getName().compareToIgnoreCase(QVCSConstants.QVCS_CACHE_NAME) == 0)
                {
                    // Get rid of the cache file, since we may be changing things here that
                    // would make the cache out of date.
                    if (fileList[i].delete())
                    {
                        m_logger.log(Level.INFO, "Deleting " + QVCSConstants.QVCS_CACHE_NAME + " file from directory: " + directory.getAbsolutePath());
                    }
                    continue;
                }
                if (fileList[i].getName().compareToIgnoreCase(QVCSConstants.QVCS_JOURNAL_NAME) == 0)
                {
                    continue;
                }
                if (fileList[i].isDirectory())
                {
                    // Recurse through the directory tree...
                    resetFileIDsForProjectDirectoryTree(fileList[i]);
                    continue;
                }
                if (fileList[i].getName().compareToIgnoreCase(QVCSConstants.QVCS_DIRECTORYID_FILENAME) == 0)
                {
                    continue;
                }
                if (fileList[i].getName().endsWith(QVCSConstants.QVCS_ARCHIVE_TEMPFILE_SUFFIX))
                {
                    continue;
                }
                if (fileList[i].getName().endsWith(QVCSConstants.QVCS_ARCHIVE_OLDFILE_SUFFIX))
                {
                    continue;
                }
                LogFile logfile = new LogFile(fileList[i].getPath());
                if (logfile.readInformation())
                {
                    // Update the file's file ID. This will cause a re-write of the archive file with an updated
                    // header (supplemental info) that contains the assigned file id.
                    logfile.setFileID(FileIDManager.getInstance().getNewFileID());
                }
                else
                {
                    m_logger.log(Level.WARNING, "Failed to read logfile information for: " + fileList[i].getPath());
                }
            }
        }
    }

    /**
     * This method is called before the server opens any ports to listen
     * for client connections... The goal is to reset the directory ids for all existing projects.
     */
    private void resetDirectoryIDs()
    {
        m_logger.log(Level.INFO, "QVCSEnterpriseServer: resetting all directory ids.");

        try
        {
            // Get a list of all the projects that this server serves...
            ServedProjectProperties[] projectPropertiesList = getServedProjectPropertiesList();

            // Iterate over the list of projects...
            for (int i = 0; i < projectPropertiesList.length; i++)
            {
                String archiveLocation = projectPropertiesList[i].getArchiveLocation();
                File projectBaseDirectory = new File(archiveLocation);
                resetDirectoryIDsForDirectoryTree(projectBaseDirectory);
                DirectoryIDManager.getInstance().setMaximumDirectoryID(projectPropertiesList[i].getProjectName(), 0);
            }
        }
        catch (Exception e)
        {
            m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
        }
    }

    /**
     * For use by the resetDirectoryIDs() method only!!  Reset the given directory ids
     * for the given directory tree.
     */
    private void resetDirectoryIDsForDirectoryTree(File directory)
    {
        m_logger.log(Level.INFO, "Scanning directory: " + directory.getAbsolutePath());

        File[] fileList = directory.listFiles();

        if (fileList != null)
        {
            for (int i = 0; i < fileList.length; i++)
            {
                if (fileList[i].isDirectory())
                {
                    // Recurse through the directory tree...
                    resetDirectoryIDsForDirectoryTree(fileList[i]);
                    continue;
                }
                if (fileList[i].getName().compareToIgnoreCase(QVCSConstants.QVCS_DIRECTORYID_FILENAME) == 0)
                {
                    try
                    {
                        // Delete the directory ID file... It will get re-created when we create the directory
                        // contents object for this directory...
                        fileList[i].delete();
                    }
                    catch (Exception e)
                    {
                        m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
                    }
                    continue;
                }
            }
        }
    }

    /**
     * Used once only when upgrading, or running the server for the very first
     * time. This method should only be run before the  server accepts requests
     * from client.
     */
    private void initializeDirectoryContentsObjects()
    {
        m_logger.log(Level.INFO, "QVCSEnterpriseServer: Initializing DirectoryContents objects...");

        // Delete any/all existing directory contents objects... we're starting
        // from scratch here.
        deleteExistingDirectoryContentsObjects();

        try
        {
            // Get a list of all the projects that this server serves...
            ServedProjectProperties[] projectPropertiesList = getServedProjectPropertiesList();

            // Iterate over the list of projects...
            for (int i = 0; i < projectPropertiesList.length; i++)
            {
                // Wrap this work in a server transaction so the DirectoryContents
                // stuff will behave in a useful way...
                ServerResponseFactoryInterface bogusResponseObject = new BogusResponseObject();

                // Keep track that we're in a transaction.
                ServerTransactionManager.getInstance().clientBeginTransaction(bogusResponseObject);

                String archiveLocation = projectPropertiesList[i].getArchiveLocation();
                File projectBaseDirectory = new File(archiveLocation);

                // And initialize the directory contents objects for this project tree.
                initializeDirectoryContentsObjectForDirectory(projectBaseDirectory, projectPropertiesList[i], bogusResponseObject);

                // Keep track that we ended this transaction.
                ServerTransactionManager.getInstance().clientEndTransaction(bogusResponseObject);
            }

            // Throw away any archive dir managers we built since we now need
            // to built them again so they will discard (i.e. move) any obsolete
            // files.
            ArchiveDirManagerFactory.getInstance().resetDirectoryMap();
        }
        catch (Exception e)
        {
            m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
        }
    }

    /**
     * Used only during an upgrade or when product is run for the 1st time.
     */
    private void deleteExistingDirectoryContentsObjects()
    {
        try
        {
            // Get a list of all the projects that this server serves...
            ServedProjectProperties[] projectPropertiesList = getServedProjectPropertiesList();

            // Iterate over the list of projects...
            for (int i = 0; i < projectPropertiesList.length; i++)
            {
                String projectName = projectPropertiesList[i].getProjectName();

                String fullArchiveDirectory = System.getProperties().getProperty("user.dir") +
                        File.separator +
                        QVCSConstants.QVCS_PROJECTS_DIRECTORY +
                        File.separator +
                        projectName +
                        File.separator +
                        QVCSConstants.QVCS_DIRECTORY_METADATA_DIRECTORY;
                File directoryFile = new File(fullArchiveDirectory);
                if (!directoryFile.exists())
                {
                    if (!directoryFile.mkdirs())
                    {
                        continue;
                    }
                }

                // Delete all the files in the QVCS_DIRECTORY_METADATA_DIRECTORY
                File[] fileList = directoryFile.listFiles();

                if (fileList != null)
                {
                    for (int j = 0; j < fileList.length; j++)
                    {
                        if (fileList[j].isDirectory())
                        {
                            continue;
                        }
                        fileList[j].delete();
                    }
                }
            }
        }
        catch (Exception e)
        {
            m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
        }
    }

    /**
     * Used only during an upgrade or when product is run for the 1st time.
     */
    private void initializeDirectoryContentsObjectForDirectory(File directory, ServedProjectProperties servedProjectProperties, ServerResponseFactoryInterface bogusResponseObject)
    {
        m_logger.log(Level.INFO, "Creating directory contents for: " + directory.getAbsolutePath());
        String projectName = servedProjectProperties.getProjectName();
        String viewName = QVCSConstants.QVCS_TRUNK_VIEW;
        String appendedPath = deduceAppendedPath(directory, servedProjectProperties);

        File[] fileList = directory.listFiles();

        if (fileList != null)
        {
            try
            {
                // Create the archiveDirManager for this directory...
                ArchiveDirManager archiveDirManager = (ArchiveDirManager)ArchiveDirManagerFactory.getInstance().getDirectoryManager(QVCSConstants.QVCS_SERVER_SERVER_NAME, projectName, viewName, appendedPath, QVCSConstants.QVCS_SERVED_PROJECT_TYPE, QVCSConstants.QVCS_SERVER_USER, bogusResponseObject, false);
                DirectoryContentsManager directoryContentsManager = DirectoryContentsManagerFactory.getInstance().getDirectoryContentsManager(projectName);
                directoryContentsManager.createDirectoryContentsFromArchiveDirManager(archiveDirManager, bogusResponseObject);
            }
            catch (QVCSException e)
            {
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }
            catch (IOException e)
            {
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }

            // Build all child directories only after creating the DirectoryContents
            // for this directory.
            for (int i = 0; i < fileList.length; i++)
            {
                if (fileList[i].isDirectory())
                {
                    // Recurse through the directory tree...
                    initializeDirectoryContentsObjectForDirectory(fileList[i], servedProjectProperties, bogusResponseObject);
                }
            }
        }
    }

    private String deduceAppendedPath(File directory, ServedProjectProperties servedProjectProperties)
    {
        String appendedPath = null;
        String projectBaseDirectory = servedProjectProperties.getArchiveLocation();

        String directoryPath = null;
        String standardDirectoryPath = null;
        try
        {
            directoryPath = directory.getCanonicalPath();
            standardDirectoryPath = Utility.getInstance().convertToStandardPath(directoryPath);
            if (projectBaseDirectory.length() == standardDirectoryPath.length())
            {
                appendedPath = "";
            }
            else
            {
                appendedPath = standardDirectoryPath.substring(1 + projectBaseDirectory.length());
            }
        }
        catch (IOException e)
        {
            m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
        }
        return appendedPath;
    }

    /** This is the class that runs at server exit time. */
    static class ShutdownThread extends Thread
    {
        @Override
        public void run()
        {
            try
            {
                ActivityJournalManager.getInstance().addJournalEntry("QVCS-Enterprise Server: shutdown thread called to shutdown.");
                ArchiveDigestManager.getInstance().writeStore();
                DirectoryIDManager.getInstance().writeStore();
                FileIDManager.getInstance().writeStore();
                DirectoryContentsLabelManager.getInstance().writeStore();
                DirectoryIDDictionary.getInstance().writeStore();
                FileIDDictionary.getInstance().writeStore();
                ActivityJournalManager.getInstance().closeJournal();
                m_logger.log(Level.INFO, "QVCS Enterprise Server exit complete.");
                System.out.println("QVCS Enterprise Server exit complete.");
            }
            catch (Exception e)
            {
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }
        }
    }

    class NonSecureServer implements Runnable
    {
        int localPort = 0;
        ServerSocket m_ServerSocket = null;

        NonSecureServer(int port)
        {
            localPort = port;
        }

        void closeServerSocket()
        {
            if (m_ServerSocket != null)
            {
                try
                {
                    m_ServerSocket.close();
                }
                catch (Exception e)
                {
                }
            }
        }

        public void run()
        {
            try
            {
                m_ServerSocket = new ServerSocket(localPort);
                m_logger.log(Level.INFO, "Non secure server is listening on port: " + localPort);
                while (true &&!ServerResponseFactoryBaseClass.getShutdownInProgress())
                {
                    Socket socket = m_ServerSocket.accept();
                    socket.setTcpNoDelay(true);
                    socket.setKeepAlive(true);

                    m_logger.log(Level.INFO, "QVCSEnterpriseServer: got non-secure connect");
                    m_logger.log(Level.INFO, "local  socket port: " + socket.getLocalPort());
                    m_logger.log(Level.INFO, "remote socket port: " + socket.getPort());

                    Worker w = null;
                    synchronized (m_Threads)
                    {
                        if (m_Threads.isEmpty())
                        {
                            m_logger.log(Level.INFO, "creating new worker thread for non-secure connection");
                            Worker ws = new Worker();
                            ws.setSocket(socket);
                            (new Thread(ws, "worker thread " + m_ThreadCount++)).start();
                        }
                        else
                        {
                            m_logger.log(Level.INFO, "re-using worker thread for non-secure connection");
                            w = (Worker) m_Threads.elementAt(0);
                            m_Threads.removeElementAt(0);
                            w.setSocket(socket);
                        }
                    }
                }
            }
            catch (java.net.SocketException e)
            {
                m_logger.log(Level.INFO, "Server non-secure accept thread is exiting.");
            }
            catch (java.io.IOException e)
            {
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }
            catch (Exception e)
            {
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }
            finally
            {
                if (m_ServerSocket != null)
                {
                    try
                    {
                        m_ServerSocket.close();
                    }
                    catch (java.io.IOException e)
                    {
                    }
                }
                m_logger.log(Level.INFO, "QVCSEnterpriseServer: closing listener thread for port: " + localPort);
            }
        }
    }

    // This server is for connections from clients where the data is in raw
    // data format, instead of being handled as Java serialized objects.
    // The original motivation for this class was to add support for connections
    // from Microsoft SCC compliant clients.
    class VanillaServer implements Runnable
    {
        int localPort = 0;
        ServerSocket m_ServerSocket = null;

        VanillaServer(int port)
        {
            localPort = port;
        }

        void closeServerSocket()
        {
            if (m_ServerSocket != null)
            {
                try
                {
                    m_ServerSocket.close();
                }
                catch (Exception e)
                {
                }
            }
        }

        public void run()
        {
            try
            {
                m_ServerSocket = new ServerSocket(localPort);
                m_logger.log(Level.INFO, "Server is listening on port: " + localPort);
                while (true &&!ServerResponseFactoryBaseClass.getShutdownInProgress())
                {
                    Socket socket = m_ServerSocket.accept();
                    socket.setTcpNoDelay(true);
                    socket.setKeepAlive(true);

                    m_logger.log(Level.INFO, "QVCSEnterpriseServer: got connect");
                    m_logger.log(Level.INFO, "local  socket port: " + socket.getLocalPort());
                    m_logger.log(Level.INFO, "remote socket port: " + socket.getPort());
                    m_logger.log(Level.INFO, "socket timeout: " + socket.getSoTimeout());
                    m_logger.log(Level.INFO, "receive buffer size: " + socket.getReceiveBufferSize());
                    m_logger.log(Level.INFO, "send buffer size: " + socket.getSendBufferSize());

                    VanillaWorker w = null;
                    synchronized (m_VanillaThreads)
                    {
                        if (m_VanillaThreads.isEmpty())
                        {
                            m_logger.log(Level.INFO, "creating new worker thread for connection");
                            VanillaWorker ws = new VanillaWorker();
                            ws.setSocket(socket);
                            (new Thread(ws, "vanilla worker thread " + m_ThreadCount++)).start();
                        }
                        else
                        {
                            m_logger.log(Level.INFO, "re-using worker thread for connection");
                            w = (VanillaWorker) m_VanillaThreads.elementAt(0);
                            m_VanillaThreads.removeElementAt(0);
                            w.setSocket(socket);
                        }
                    }
                }
            }
            catch (java.net.SocketException e)
            {
                m_logger.log(Level.INFO, "Server accept thread is exiting.");
            }
            catch (java.io.IOException e)
            {
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }
            catch (Exception e)
            {
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }
            finally
            {
                if (m_ServerSocket != null)
                {
                    try
                    {
                        m_ServerSocket.close();
                    }
                    catch (java.io.IOException e)
                    {
                    }
                }
                m_logger.log(Level.INFO, "QVCSEnterpriseServer: closing listener thread for port: " + localPort);
            }
        }
    }

    class SecureServer implements Runnable
    {
        int localPort = 0;
        SSLServerSocket m_ServerSocket = null;

        SecureServer(int port)
        {
            localPort = port;
        }

        void closeServerSocket()
        {
            if (m_ServerSocket != null)
            {
                try
                {
                    m_ServerSocket.close();
                }
                catch (Exception e)
                {
                }
            }
        }

        public void run()
        {
            try
            {
                ServerSocketFactory socketFactory = SSLServerSocketFactory.getDefault();
                m_ServerSocket = (SSLServerSocket)socketFactory.createServerSocket(localPort);

                // Select an appropriate cipher suite.
                String [] useSuites = new String[1];
                useSuites[0] = "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
                m_ServerSocket.setEnabledCipherSuites(useSuites);

                m_logger.log(Level.INFO, "Secure server is listening on port: " + localPort);
                while (true &&!ServerResponseFactoryBaseClass.getShutdownInProgress())
                {
                    Socket socket = m_ServerSocket.accept();
                    socket.setTcpNoDelay(true);
                    socket.setKeepAlive(true);

                    m_logger.log(Level.INFO, "QVCSEnterpriseServer: got secure connection");
                    m_logger.log(Level.INFO, "local  socket port: " + socket.getLocalPort());
                    m_logger.log(Level.INFO, "remote socket port: " + socket.getPort());

                    Worker w = null;
                    synchronized (m_Threads)
                    {
                        if (m_Threads.isEmpty())
                        {
                            m_logger.log(Level.INFO, "creating new worker thread for secure connection");
                            Worker ws = new Worker();
                            ws.setSocket(socket);
                            (new Thread(ws, "worker thread " + m_ThreadCount++)).start();
                        }
                        else
                        {
                            m_logger.log(Level.INFO, "re-using worker thread for secure connection");
                            w = (Worker) m_Threads.elementAt(0);
                            m_Threads.removeElementAt(0);
                            w.setSocket(socket);
                        }
                    }
                }
            }
            catch (java.net.SocketException e)
            {
                m_logger.log(Level.INFO, "Server secure accept thread is exiting.");
            }
            catch (java.io.IOException e)
            {
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }
            catch (Exception e)
            {
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }
            finally
            {
                if (m_ServerSocket != null)
                {
                    try
                    {
                        m_ServerSocket.close();
                    }
                    catch (java.io.IOException e)
                    {
                    }
                }
                m_logger.log(Level.INFO, "QVCSEnterpriseServer: closing listener thread for secure port: " + localPort);
            }
        }
    }

    class VanillaWorker implements Runnable
    {
        /* Socket to client we're handling */
        private Socket m_socket;

        synchronized void setSocket(Socket s)
        {
            this.m_socket = s;
            notifyAll();
        }

        public synchronized void run()
        {
            while(true && !ServerResponseFactoryBaseClass.getShutdownInProgress())
            {
                if (m_socket == null)
                {
                    /* nothing to do */
                    try
                    {
                        wait();
                    }
                    catch (InterruptedException e)
                    {
                        /* should not happen */
                        continue;
                    }
                }
                handleVanillaClientRequests();

                /* go back in wait queue if there's fewer
                 * than numHandler connections.
                 */
                m_socket = null;
                synchronized (m_VanillaThreads)
                {
                    // If shutdown is not in progress...
                    if (!ServerResponseFactoryBaseClass.getShutdownInProgress())
                    {
                        if (m_VanillaThreads.size() >= m_workerThreads)
                        {
                            // too many threads, exit this one
                            return;
                        }
                        else
                        {
                            m_VanillaThreads.addElement(this);
                        }
                    }
                    else
                    {
                        // Let the server thread know that this thread is done.
                        m_VanillaThreads.notifyAll();
                    }
                }
            }
        }

        private void handleVanillaClientRequests()
        {
            String connectedTo = null;

            VanillaClientRequestFactory  requestFactory  = null;
            VanillaServerResponseFactory responseFactory = null;
            try
            {
                requestFactory   = new VanillaClientRequestFactory(m_socket.getInputStream());
                responseFactory  = new VanillaServerResponseFactory(m_socket.getOutputStream(), m_socket.getPort(), m_socket.getInetAddress().getHostAddress());
                connectedTo = m_socket.getInetAddress().getHostAddress();
                m_logger.log(Level.INFO, "Connected to: " + connectedTo);

                while (!ServerResponseFactoryBaseClass.getShutdownInProgress() && responseFactory.getConnectionAliveFlag())
                {
                    try
                    {
                        ClientRequestInterface clientRequest = requestFactory.createClientRequest(responseFactory);
                        if (clientRequest != null)
                        {
                            clientRequest.moveArguments();
                            SerializableObjectInterface returnObject = clientRequest.execute(requestFactory.getUserName(), responseFactory);

                            if (clientRequest instanceof ClientRequestLogin)
                            {
                                ServerResponseLogin serverResponseLogin = (ServerResponseLogin) returnObject;
                                if (serverResponseLogin.getLoginResult())
                                {
                                    requestFactory.setIsUserLoggedIn(true);
                                    requestFactory.setUserName(serverResponseLogin.getUserName());

                                    responseFactory.setIsUserLoggedIn(true);
                                    responseFactory.setUserName(serverResponseLogin.getUserName());
                                    ClientRequestLogin loginRequest = (ClientRequestLogin) clientRequest;
                                    responseFactory.setServerName(loginRequest.getServerName());

                                    getConnectedUsersCollection().add(responseFactory);
                                }
                            }

                            // Send the response back to the client.
                            responseFactory.createServerResponse(returnObject);

                            // If this was a login request that succeeded, we also
                            // need to send the list of projects for this user.
                            if (clientRequest instanceof ClientRequestLogin)
                            {
                                ClientRequestLogin clientRequestLogin = (ClientRequestLogin)clientRequest;
                                ServerResponseMessage message = null;

                                if (responseFactory.getIsUserLoggedIn() == false)
                                {
                                    // The user failed to login.  Report the problem to the user.
                                    if (clientRequestLogin.getAuthenticationFailedFlag())
                                    {
                                        message = new ServerResponseMessage("Invalid username/password", null, null, null, ServerResponseMessage.HIGH_PRIORITY);
                                        responseFactory.createServerResponse(message);
                                    }
                                }

                                // Report any status information back to the user.
                                if (clientRequestLogin.getMessage() != null)
                                {
                                    message = new ServerResponseMessage(clientRequestLogin.getMessage(), null, null, null, ServerResponseMessage.HIGH_PRIORITY);
                                    responseFactory.createServerResponse(message);
                                }
                            }
                        }
                        else
                        {
                            m_logger.log(Level.INFO, "clientRequest is null!!");
                            m_logger.log(Level.INFO, "Breaking connection to: " + connectedTo);
                            break;
                        }
                    }
                    catch (QVCSShutdownException e)
                    {
                        // We are shutting down this server.
                        m_logger.log(Level.INFO, "Shutting down server at request from: " + connectedTo);
                        break;
                    }
                    catch (RuntimeException e)
                    {
                        m_logger.log(Level.INFO, "Breaking connection to: " + connectedTo);
                        m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
                        break;
                    }
                    catch (Exception e)
                    {
                        m_logger.log(Level.INFO, "Breaking connection to: " + connectedTo);
                        m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                m_logger.log(Level.INFO, "Breaking connection to: " + connectedTo);
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }
            finally
            {
                try
                {
                    m_socket.close();

                    // The connection to the client is gone.  Remove the response
                    // factory as a listener for any archive directory managers
                    // so we don't waste time trying to inform a client that we
                    // can no longer talk to.
                    if (responseFactory != null)
                    {
                        Set<ArchiveDirManagerInterface> directoryManagers = responseFactory.getDirectoryManagers();
                        Iterator<ArchiveDirManagerInterface> it = directoryManagers.iterator();
                        while (it.hasNext())
                        {
                            ArchiveDirManagerInterface directoryManagerInterface = it.next();
                            directoryManagerInterface.removeLogFileListener(responseFactory);
                        }

                        getConnectedUsersCollection().remove(responseFactory);

                        // Decrement the number of logged on users with the
                        // license manager.
                        if (responseFactory.getIsUserLoggedIn())
                        {
                            ServerTransactionManager.getInstance().flushClientTransaction(responseFactory);
                            LicenseManager.getInstance().logoutUser(responseFactory.getUserName(), responseFactory.getClientIPAddress());
                        }
                    }
                }
                catch (Exception e)
                {
                    m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
                }
            }
        }
    }

    class Worker implements Runnable
    {
        /* Socket to client we're handling */
        private Socket m_socket;

        synchronized void setSocket(Socket s)
        {
            this.m_socket = s;
            notifyAll();
        }

        public synchronized void run()
        {
            while(true && !ServerResponseFactoryBaseClass.getShutdownInProgress())
            {
                if (m_socket == null)
                {
                    /* nothing to do */
                    try
                    {
                        wait();
                    }
                    catch (InterruptedException e)
                    {
                        /* should not happen */
                        continue;
                    }
                }
                handleClientRequests();

                /* go back in wait queue if there's fewer
                 * than numHandler connections.
                 */
                m_socket = null;
                synchronized (m_Threads)
                {
                    // If shutdown is not in progress...
                    if (!ServerResponseFactoryBaseClass.getShutdownInProgress())
                    {
                        if (m_Threads.size() >= m_workerThreads)
                        {
                            // too many threads, exit this one
                            return;
                        }
                        else
                        {
                            m_Threads.addElement(this);
                        }
                    }
                    else
                    {
                        // Let the server thread know that this thread is done.
                        m_Threads.notifyAll();
                    }
                }
            }
        }

        private void handleClientRequests()
        {
            String connectedTo = null;

            ServerResponseFactory responseFactory = null;
            ClientRequestFactory  requestFactory  = null;
            try
            {
                requestFactory   = new ClientRequestFactory(m_socket.getInputStream());
                responseFactory  = new ServerResponseFactory(m_socket.getOutputStream(), m_socket.getPort(), m_socket.getInetAddress().getHostAddress());
                connectedTo = m_socket.getInetAddress().getHostAddress();
                m_logger.log(Level.INFO, "Connected to: " + connectedTo);

                while (!ServerResponseFactoryBaseClass.getShutdownInProgress() && responseFactory.getConnectionAliveFlag())
                {
                    try
                    {
                        ClientRequestInterface clientRequest = requestFactory.createClientRequest(responseFactory);
                        if (clientRequest != null)
                        {
                            clientRequest.moveArguments();
                            SerializableObjectInterface returnObject = clientRequest.execute(requestFactory.getUserName(), responseFactory);

                            if (clientRequest instanceof ClientRequestLogin)
                            {
                                ServerResponseLogin serverResponseLogin = (ServerResponseLogin) returnObject;
                                if (serverResponseLogin.getLoginResult())
                                {
                                    requestFactory.setIsUserLoggedIn(true);
                                    requestFactory.setUserName(serverResponseLogin.getUserName());

                                    responseFactory.setIsUserLoggedIn(true);
                                    responseFactory.setUserName(serverResponseLogin.getUserName());
                                    ClientRequestLogin loginRequest = (ClientRequestLogin) clientRequest;
                                    responseFactory.setServerName(loginRequest.getServerName());

                                    getConnectedUsersCollection().add(responseFactory);
                                }
                            }

                            // Send the response back to the client.
                            responseFactory.createServerResponse(returnObject);

                            // If this was a login request that succeeded, we also
                            // need to send the list of projects for this user.
                            if (clientRequest instanceof ClientRequestLogin)
                            {
                                ClientRequestLogin clientRequestLogin = (ClientRequestLogin)clientRequest;
                                ServerResponseMessage message = null;

                                if (responseFactory.getIsUserLoggedIn() == false)
                                {
                                    // The user failed to login.  Report the problem to the user.
                                    if (clientRequestLogin.getAuthenticationFailedFlag())
                                    {
                                        message = new ServerResponseMessage("Invalid username/password", null, null, null, ServerResponseMessage.HIGH_PRIORITY);
                                        responseFactory.createServerResponse(message);
                                    }
                                }
                                else
                                {
                                    // Report any status information back to the user.
                                    if (clientRequestLogin.getMessage() != null)
                                    {
                                        message = new ServerResponseMessage(clientRequestLogin.getMessage(), null, null, null, ServerResponseMessage.HIGH_PRIORITY);
                                        responseFactory.createServerResponse(message);
                                    }
                                }
                            }
                        }
                        else
                        {
                            m_logger.log(Level.INFO, "clientRequest is null!!");
                            m_logger.log(Level.INFO, "Breaking connection to: " + connectedTo);
                            break;
                        }
                    }
                    catch (QVCSShutdownException e)
                    {
                        // We are shutting down this server.
                        m_logger.log(Level.INFO, "Shutting down server at request from: " + connectedTo);
                        break;
                    }
                    catch (RuntimeException e)
                    {
                        m_logger.log(Level.INFO, "Breaking connection to: " + connectedTo);
                        m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
                        break;
                    }
                    catch (Exception e)
                    {
                        m_logger.log(Level.INFO, "Breaking connection to: " + connectedTo);
                        m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                m_logger.log(Level.INFO, "Breaking connection to: " + connectedTo);
                m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
            }
            finally
            {
                try
                {
                    m_socket.close();

                    // The connection to the client is gone.  Remove the response
                    // factory as a listener for any archive directory managers
                    // so we don't waste time trying to inform a client that we
                    // can no longer talk to.
                    if (responseFactory != null)
                    {
                        Set<ArchiveDirManagerInterface> directoryManagers = responseFactory.getDirectoryManagers();
                        Iterator<ArchiveDirManagerInterface> it = directoryManagers.iterator();
                        while (it.hasNext())
                        {
                            ArchiveDirManagerInterface directoryManagerInterface = it.next();
                            directoryManagerInterface.removeLogFileListener(responseFactory);
                        }

                        getConnectedUsersCollection().remove(responseFactory);

                        // Decrement the number of logged on users with the
                        // license manager.
                        if (responseFactory.getIsUserLoggedIn())
                        {
                            ServerTransactionManager.getInstance().flushClientTransaction(responseFactory);
                            LicenseManager.getInstance().logoutUser(responseFactory.getUserName(), responseFactory.getClientIPAddress());
                        }
                    }
                }
                catch (Exception e)
                {
                    m_logger.log(Level.WARNING, Utility.expandStackTraceToString(e));
                }
            }
        }
    }

    static class QVCSWebServer implements Runnable
    {
        String[] m_Args;

        QVCSWebServer(String[] args)
        {
            if (args != null && args.length > 0)
            {
                m_Args = new String[2];
                m_Args[0] = args[0];
                if (args.length > 5)
                {
                    m_Args[1] = args[5];
                }
                else
                {
                    m_Args[1] = WEB_SERVER_PORT;
                }
            }
        }

        /** When an object implementing interface Runnable is used
         * to create a thread, starting the thread causes the object's
         * run method to be called in that separately executing
         * thread.
         *

         * The general contract of the method run is that it may
         * take any action whatsoever.
         *
         * @see     java.lang.Thread#run()
         *
         */
        public void run()
        {
            try
            {
                WebServer.main(m_Args);
            }
            catch (InterruptedException e)
            {
                m_logger.log(Level.INFO, "Web server exiting.");
            }
            catch (Exception e)
            {
                m_logger.log(Level.INFO, "Web server exiting due to exception: " + e.toString());
            }
        }
    }
}


text:
classdef (Abstract) ChildManager < handle
%CHILDMANAGER Abstract superclass to handle child management.
    %
    % CHILDMANAGER properties:
    %  Children - Read-only cell array of children in CHILDMANAGER.
    %
    % CHILDMANAGER methods:
    %  addChild    - adds a child to CHILDMANAGER
    %  removeChild - removes a child from CHILDMANAGER

    % Copyright 2014 The MathWorks, Inc.

    properties (SetAccess = private)
        Children
    end

end

redpajama_set_name: RedPajamaGithub


text: Docker wrapping API service to monitor and start docker containers.


text:
#ifndef HK_COLLIDE2_COLLISION_AGENT_TRACK_H
#define HK_COLLIDE2_COLLISION_AGENT_TRACK_H

#include <Physics2012/Collide/Agent3/hkpAgent3.h>
typedef void hkpAgentData;
struct hkpAgentNnEntry;
struct hkpAgentNnSector;
class hkpCollidable;

#if defined(HK_REAL_IS_DOUBLE)

#if ( HK_POINTER_SIZE == 4 )
#	define HK_AGENT3_MIDPHASE_AGENT_SIZE 80
#	define HK_AGENT3_NARROWPHASE_AGENT_SIZE 160
#	define HK_AGENT3_MAX_AGENT_SIZE 160
#	define HK_AGENT3_SECTOR_SIZE 640
#else
#	define HK_AGENT3_MIDPHASE_AGENT_SIZE 96
#	define HK_AGENT3_NARROWPHASE_AGENT_SIZE 192
#	define HK_AGENT3_MAX_AGENT_SIZE 192
#	define HK_AGENT3_SECTOR_SIZE 960
#endif

#else

#if ( HK_POINTER_SIZE == 4 )
#	define HK_AGENT3_MIDPHASE_AGENT_SIZE 64
#	define HK_AGENT3_NARROWPHASE_AGENT_SIZE 128
#	define HK_AGENT3_MAX_AGENT_SIZE 128
#	define HK_AGENT3_SECTOR_SIZE 512
#else
#	define HK_AGENT3_MIDPHASE_AGENT_SIZE 80
#	define HK_AGENT3_NARROWPHASE_AGENT_SIZE 160
#	define HK_AGENT3_MAX_AGENT_SIZE 160
#	define HK_AGENT3_SECTOR_SIZE 960
#endif

#endif

#define HK_AGENT3_FEWEST_AGENTS_PER_1N_SECTOR ( (HK_AGENT3_SECTOR_SIZE - HK_REAL_ALIGNMENT ) / HK_AGENT3_MAX_AGENT_SIZE )
#define HK_AGENT3_MIDPHASE_AGENTS_PER_NN_SECTOR ( HK_AGENT3_SECTOR_SIZE / HK_AGENT3_MIDPHASE_AGENT_SIZE )
#define HK_AGENT3_NARROWPHASE_AGENTS_PER_NN_SECTOR ( HK_AGENT3_SECTOR_SIZE / HK_AGENT3_NARROWPHASE_AGENT_SIZE )

enum hkpAgentNnTrackType
{
	HK_AGENT3_INVALID_TRACK = 0,
	HK_AGENT3_MIDPHASE_TRACK = 1,	///< For collisions which require midphase processing.
	HK_AGENT3_NARROWPHASE_TRACK = 2	///< For convex-convex collisions only.
};

	// Make sure if you use this entry that you pad to get a 16 byte alignment
	// Notes:
	//
	//   HK_POINTER_SIZE == 4
	//   --------------------
	//   - sizeof(hkpAgentEntry) = 8
	//   - sizeof(hkpAgentNnEntry) = 8 + 20
	//
	//   HK_POINTER_SIZE == 8
	//   --------------------
	//   - sizeof(hkpAgentEntry) = 16
	//   - sizeof(hkpAgentNnEntry) = 16 + 32
struct hkpAgentNnEntry: public hkpAgentEntry
{
	HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_CDINFO, hkpAgentNnEntry );

	hkObjectIndex		m_agentIndexOnCollidable[2]; // this value must not be written back from spu!
	hkpContactMgr*		m_contactMgr;

	hkUchar				m_collisionQualityIndex;
	hkUchar				m_forceCollideOntoPpu;	// only used if the platform has an spu
	hkEnum<hkpAgentNnTrackType, hkUint8> m_nnTrackType; // Is this a convex-convex collision.
	hkUchar				m_padding;
	// Additional 4 bytes padding on 64-bit platforms
	hkpLinkedCollidable*	m_collidable[2];

	inline hkpCollidable*  getCollidableA(){ return reinterpret_cast<hkpCollidable*>(m_collidable[0]); }
	inline hkpCollidable*  getCollidableB(){ return reinterpret_cast<hkpCollidable*>(m_collidable[1]); }
};

struct hkpAgentNnSector
{
	HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR(HK_MEMORY_CLASS_AGENT, hkpAgentNnSector);

	hkUint8 m_data[ HK_AGENT3_SECTOR_SIZE ];

	hkpAgentNnEntry* getBegin()
	{
		return reinterpret_cast<hkpAgentNnEntry*>( &m_data[0] );
	}

	hkpAgentNnEntry* getEnd()
	{
		return reinterpret_cast<hkpAgentNnEntry*>( &m_data[HK_AGENT3_SECTOR_SIZE] );
	}
};

struct hkpAgentNnTrack
{
	hkpAgentNnTrack( hkpAgentNnTrackType nnTrackType )
	{
		m_bytesUsedInLastSector = HK_AGENT3_SECTOR_SIZE;
		m_nnTrackType = nnTrackType;
	}

	int getSectorSize( int sectorIndex ) const
	{
		if ( sectorIndex+1 == m_sectors.getSize())
		{
			return m_bytesUsedInLastSector;
		}
		return HK_AGENT3_SECTOR_SIZE;
	}

		/// Get the size of the space allocated to each agent in tracks of the given type.
	HK_FORCE_INLINE static unsigned int getAgentSize( hkpAgentNnTrackType nnTrackType )
	{
		// Works because HK_AGENT3_MIDPHASE_AGENT_SIZE * 2 == HK_AGENT3_NARROWPHASE_AGENT_SIZE

		return nnTrackType * HK_AGENT3_MIDPHASE_AGENT_SIZE;
	}

		/// Get the size of the space allocated to each agent the track.
	HK_FORCE_INLINE unsigned int getAgentSize() const
	{
		return getAgentSize( m_nnTrackType );
	}

	HK_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( HK_MEMORY_CLASS_CDINFO, hkpAgentNnTrack );

	hkUint16	m_bytesUsedInLastSector;

		/// Does the track contain midphase or narrowphase agent entries?
	hkEnum<hkpAgentNnTrackType, hkUint8> m_nnTrackType;
	hkUint8     m_padding;

	hkInplaceArray<hkpAgentNnSector*,1> m_sectors;
};

#endif // HK_COLLIDE2_COLLISION_AGENT_TRACK_H

/*
 * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20140907)
 *
 * Confidential Information of Havok.  (C) Copyright 1999-2014
 * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
 * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
 * rights, and intellectual property rights in the Havok software remain in
 * Havok and/or its suppliers.
 *
 * Use of this software for evaluation purposes is subject to and indicates
 * acceptance of the End User licence Agreement for this product. A copy of
 * the license is included with this software and is also available at www.havok.com/tryhavok.
 *
 */


text:
LANG_SERVER_STATS=Statystyki serwera
LANG_STATS_FOR=Zużycie dla
LANG_REC=Odebrane
LANG_TX=Wysłane


text:
Release Notes {#releasenotes}
==============

v3.2.2
==============

Bug Fixes
--------------

* Fixed [memory leak](https://github.com/arrayfire/arrayfire/pull/1145) in
  CUDA Random number generators
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1157) in
  af::select() and af::replace() tests
* Fixed [exception](https://github.com/arrayfire/arrayfire/issues/1164)
  thrown when printing empty arrays with af::print()
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1170) in CPU
  random number generation. Changed the generator to
  [mt19937](http://en.cppreference.com/w/cpp/numeric/random)
* Fixed exception handling (internal)
    * [Exceptions](https://github.com/arrayfire/arrayfire/issues/1188)
      now show function, short file name and line number
    * Added [AF_RETURN_ERROR](https://github.com/arrayfire/arrayfire/issues/1186)
      macro to handle returning errors.
    * Removed THROW macro, and renamed AF_THROW_MSG to AF_THROW_ERR.
* Fixed [bug](https://github.com/arrayfire/arrayfire/commit/9459c6)
  in \ref af::identity() that may have affected CUDA Compute 5.2 cards

Build
------
* Added a [MIN_BUILD_TIME](https://github.com/arrayfire/arrayfire/issues/1193)
  option to build with minimum optimization compiler flags resulting in faster
  compile times
* Fixed [issue](https://github.com/arrayfire/arrayfire/issues/1143) in CBLAS
  detection by CMake
* Fixed tests failing for builds without optional components
  [FreeImage](https://github.com/arrayfire/arrayfire/issues/1143) and
  [LAPACK](https://github.com/arrayfire/arrayfire/issues/1167)
* Added a [test](https://github.com/arrayfire/arrayfire/issues/1192)
  for unified backend
* Only [info and backend tests](https://github.com/arrayfire/arrayfire/issues/1192)
  are now built for unified backend
* [Sort tests](https://github.com/arrayfire/arrayfire/issues/1199)
  execution alphabetically
* Fixed compilation flags and errors in tests and examples
* [Moved AF_REVISION and AF_COMPILER_STR](https://github.com/arrayfire/arrayfire/commit/2287c5)
  into src/backend. This is because as revision is updated with every commit,
  entire ArrayFire would have to be rebuilt in the old code.
    * v3.3 will add a af_get_revision() function to get the revision string.
* [Clean up examples](https://github.com/arrayfire/arrayfire/pull/1158)
    * Remove getchar for Windows (this will be handled by the installer)
    * Other miscellaneous code cleanup
    * Fixed bug in [plot3.cpp](\ref graphics/plot3.cpp) example
* [Rename](https://github.com/arrayfire/arrayfire/commit/35f0fc2) clBLAS/clFFT
  external project suffix from external -> ext
* [Add OpenBLAS](https://github.com/arrayfire/arrayfire/pull/1197) as a
  lapack/lapacke alternative

Improvements
------------
* Added \ref AF_MEM_INFO macro to print memory info from ArrayFire's memory
  manager ([cross issue](https://github.com/arrayfire/arrayfire/issues/1172))
* Added [additional paths](https://github.com/arrayfire/arrayfire/issues/1184)
  for searching for `libaf*` for Unified backend on unix-style OS.
    * Note: This still requires dependencies such as forge, CUDA, NVVM etc to be
      in `LD_LIBRARY_PATH` as described in [Unified Backend](\ref unifiedbackend)
* [Create streams](https://github.com/arrayfire/arrayfire/commit/ed0373f)
  for devices only when required in CUDA Backend

Documentation
------
* [Hide scrollbars](https://github.com/arrayfire/arrayfire/commit/9d218a5)
  appearing for pre and code styles
* Fix [documentation](https://github.com/arrayfire/arrayfire/commit/ac09f91) for af::replace
* Add [code sample](https://github.com/arrayfire/arrayfire/commit/4e06483)
  for converting the output of af::getAvailableBackends() into bools
* Minor fixes in documentation

v3.2.1
==============

Bug Fixes
--------------

* Fixed [bug](https://github.com/arrayfire/arrayfire/pull/1136) in homography()
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1135) in behavior
  of af::array::device()
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1129) when
  indexing with span along trailing dimension
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1127) when
  indexing in [GFor](\ref gfor)
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1122) in CPU
  information fetching
* Fixed compilation [bug](https://github.com/arrayfire/arrayfire/issues/1117)
  in unified backend caused by missing link library
* Add [missing symbol](https://github.com/arrayfire/arrayfire/pull/1114) for
  af_draw_surface()

Build
------
* Tests can now be used as a [standalone project](https://github.com/arrayfire/arrayfire/pull/1120)
    * Tests can now be built using pre-compiled libraries
    * Similar to how the examples are built
* The install target now installs the examples source irrespective of the
  BUILD_EXAMPLES value
    * Examples are not built if BUILD_EXAMPLES is off

Documentation
------
* HTML documentation is now [built and installed](https://github.com/arrayfire/arrayfire/pull/1109)
  in docs/html
* Added documentation for \ref af::seq class
* Updated [Matrix Manipulation](\ref matrixmanipulation) tutorial
* Examples list is now generated by CMake
    * Examples are now listed as dir/example.cpp
* Removed dummy groups used for indexing documentation (affcted doxygen < 1.8.9)

v3.2.0
=================

Major Updates
-------------

* Added Unified backend
    * Allows switching backends at runtime
    * Read [Unified Backend](\ref unifiedbackend) for more.
* Support for 16-bit integers (\ref s16 and \ref u16)
    * All functions that support 32-bit interger types (\ref s32, \ref u32),
      now also support 16-bit interger types

Function Additions
------------------
* Unified Backend
    * \ref setBackend() - Sets a backend as active
    * \ref getBackendCount() - Gets the number of backends available for use
    * \ref getAvailableBackends() - Returns information about available backends
    * \ref getBackendId() - Gets the backend enum for an array

* Vision
    * \ref homography() - Homography estimation
    * \ref gloh() - GLOH Descriptor for SIFT

* Image Processing
    * \ref loadImageNative() - Load an image as native data without modification
    * \ref saveImageNative() - Save an image without modifying data or type

* Graphics
    * \ref af::Window::plot3() - 3-dimensional line plot
    * \ref af::Window::surface() - 3-dimensional curve plot

* Indexing
    * \ref af_create_indexers()
    * \ref af_set_array_indexer()
    * \ref af_set_seq_indexer()
    * \ref af_set_seq_param_indexer()
    * \ref af_release_indexers()

* CUDA Backend Specific
    * \ref setNativeId() - Set the CUDA device with given native id as active
        * ArrayFire uses a modified order for devices. The native id for a
          device can be retreived using `nvidia-smi`

* OpenCL Backend Specific
    * \ref setDeviceId() - Set the OpenCL device using the `clDeviceId`

Other Improvements
------------------------
* Added \ref c32 and \ref c64 support for \ref isNaN(), \ref isInf() and \ref iszero()
* Added CPU information for `x86` and `x86_64` architectures in CPU backend's \ref info()
* Batch support for \ref approx1() and \ref approx2()
    * Now can be used with gfor as well
* Added \ref s64 and \ref u64 support to:
    * \ref sort() (along with sort index and sort by key)
    * \ref setUnique(), \ref setUnion(), \ref setIntersect()
    * \ref convolve() and \ref fftConvolve()
    * \ref histogram() and \ref histEqual()
    * \ref lookup()
    * \ref mean()
* Added \ref AF_MSG macro

Build Improvements
------------------
* Submodules update is now automatically called if not cloned recursively
* [Fixes for compilation](https://github.com/arrayfire/arrayfire/issues/766) on Visual Studio 2015
* Option to use [fallback to CPU LAPACK](https://github.com/arrayfire/arrayfire/pull/1053)
  for linear algebra functions in case of CUDA 6.5 or older versions.

Bug Fixes
--------------
* Fixed [memory leak](https://github.com/arrayfire/arrayfire/pull/1096) in \ref susan()
* Fixed [failing test](https://github.com/arrayfire/arrayfire/commit/144a2db)
  in \ref lower() and \ref upper() for CUDA compute 53
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1092) in CUDA for indexing out of bounds
* Fixed [dims check](https://github.com/arrayfire/arrayfire/commit/6975da8) in \ref iota()
* Fixed [out-of-bounds access](https://github.com/arrayfire/arrayfire/commit/7fc3856) in \ref sift()
* Fixed [memory allocation](https://github.com/arrayfire/arrayfire/commit/5e88e4a) in \ref fast() OpenCL
* Fixed [memory leak](https://github.com/arrayfire/arrayfire/pull/994) in image I/O functions
* \ref dog() now returns float-point type arrays

Documentation Updates
---------------------
* Improved tutorials documentation
    * More detailed Using on [Linux](\ref using_on_windows), [OSX](\ref using_on_windows),
      [Windows](\ref using_on_windows) pages.
* Added return type information for functions that return different type
  arrays

New Examples
------------
* Graphics
    * [Plot3](\ref graphics/plot3.cpp)
    * [Surface](\ref graphics/surface.cpp)
* [Shallow Water Equation](\ref pde/swe.cpp)
* [Basic](\ref unified/basic.cpp) as a Unified backend example

Installers
-----------
* All installers now include the Unified backend and corresponding CMake files
* Visual Studio projects include Unified in the Platform Configurations
* Added installer for Jetson TX1
* SIFT and GLOH do not ship with the installers as SIFT is protected by
  patents that do not allow commercial distribution without licensing.

v3.1.3
==============

Bug Fixes
---------

* Fixed [bugs](https://github.com/arrayfire/arrayfire/issues/1042) in various OpenCL kernels without offset additions
* Remove ARCH_32 and ARCH_64 flags
* Fix [missing symbols](https://github.com/arrayfire/arrayfire/issues/1040) when freeimage is not found
* Use CUDA driver version for Windows
* Improvements to SIFT
* Fixed [memory leak](https://github.com/arrayfire/arrayfire/issues/1045) in median
* Fixes for Windows compilation when not using MKL [#1047](https://github.com/arrayfire/arrayfire/issues/1047)
* Fixed for building without LAPACK

Other
-------

* Documentation: Fixed documentation for select and replace
* Documentation: Fixed documentation for af_isnan

v3.1.2
==============

Bug Fixes
---------

* Fixed [bug](https://github.com/arrayfire/arrayfire/commit/4698f12) in assign that was causing test to fail
* Fixed bug in convolve. Frequency condition now depends on kernel size only
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1005) in indexed reductions for complex type in OpenCL backend
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1006) in kernel name generation in ireduce for OpenCL backend
* Fixed non-linear to linear indices in ireduce
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1011) in reductions for small arrays
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/1010) in histogram for indexed arrays
* Fixed [compiler error](https://github.com/arrayfire/arrayfire/issues/1015) CPUID for non-compliant devices
* Fixed [failing tests](https://github.com/arrayfire/arrayfire/issues/1008) on i386 platforms
* Add missing AFAPI

Other
-------

* Documentation: Added missing examples and other corrections
* Documentation: Fixed warnings in documentation building
* Installers: Send error messages to log file in OSX Installer

v3.1.1
==============

Installers
-----------

* CUDA backend now depends on CUDA 7.5 toolkit
* OpenCL backend now require OpenCL 1.2 or greater

Bug Fixes
--------------

* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/981) in reductions after indexing
* Fixed [bug](https://github.com/arrayfire/arrayfire/issues/976) in indexing when using reverse indices

Build
------

* `cmake` now includes `PKG_CONFIG` in the search path for CBLAS and LAPACKE libraries
* [heston_model.cpp](\ref financial/heston_model.cpp) example now builds with the default ArrayFire cmake files after installation

Other
------

* Fixed bug in [image_editing.cpp](\ref image_processing/image_editing.cpp)

v3.1.0
==============

Function Additions
------------------
* Computer Vision Functions
    * \ref nearestNeighbour() - Nearest Neighbour with SAD, SSD and SHD distances
    * \ref harris() - Harris Corner Detector
    * \ref susan() - Susan Corner Detector
    * \ref sift() - Scale Invariant Feature Transform (SIFT)
        * Method and apparatus for identifying scale invariant features"
          "in an image and use of same for locating an object in an image,\" David"
          "G. Lowe, US Patent 6,711,293 (March 23, 2004). Provisional application"
          "filed March 8, 1999. Asignee: The University of British Columbia. For"
          "further details, contact David Lowe (lowe@cs.ubc.ca) or the"
          "University-Industry Liaison Office of the University of British"
          "Columbia.")
        * SIFT is available for compiling but does not ship with ArrayFire
          hosted installers/pre-built libraries
    * \ref dog() -  Difference of Gaussians

* Image Processing Functions
    * \ref ycbcr2rgb() and \ref rgb2ycbcr() - RGB <->YCbCr color space conversion
    * \ref wrap() and \ref unwrap() Wrap and Unwrap
    * \ref sat() - Summed Area Tables
    * \ref loadImageMem() and \ref saveImageMem() - Load and Save images to/from memory
        * \ref af_image_format - Added imageFormat (af_image_format) enum

* Array & Data Handling
    * \ref copy() - Copy
    * array::lock() and array::unlock() - Lock and Unlock
    * \ref select() and \ref replace() - Select and Replace
    * Get array reference count (af_get_data_ref_count)

* Signal Processing
    * \ref fftInPlace() - 1D in place FFT
    * \ref fft2InPlace() - 2D in place FFT
    * \ref fft3InPlace() - 3D in place FFT
    * \ref ifftInPlace() - 1D in place Inverse FFT
    * \ref ifft2InPlace() - 2D in place Inverse FFT
    * \ref ifft3InPlace() - 3D in place Inverse FFT
    * \ref fftR2C() - Real to complex FFT
    * \ref fftC2R() - Complex to Real FFT

* Linear Algebra
    * \ref svd() and \ref svdInPlace() - Singular Value Decomposition

* Other operations
    * \ref sigmoid() - Sigmoid
    * Sum (with option to replace NaN values)
    * Product (with option to replace NaN values)

* Graphics
    * Window::setSize() - Window resizing using Forge API

* Utility
    * Allow users to set print precision (print, af_print_array_gen)
    * \ref saveArray() and \ref readArray() - Stream arrays to binary files
    * \ref toString() - toString function returns the array and data as a string

* CUDA specific functionality
    * \ref getStream() - Returns default CUDA stream ArrayFire uses for the current device
    * \ref getNativeId() - Returns native id of the CUDA device

Improvements
------------
* dot
    * Allow complex inputs with conjugate option
* AF_INTERP_LOWER interpolation
    * For resize, rotate and transform based functions
* 64-bit integer support
    * For reductions, random, iota, range, diff1, diff2, accum, join, shift
      and tile
* convolve
    * Support for non-overlapping batched convolutions
* Complex Arrays
    * Fix binary ops on complex inputs of mixed types
    * Complex type support for exp
* tile
    * Performance improvements by using JIT when possible.
* Add AF_API_VERSION macro
    * Allows disabling of API to maintain consistency with previous versions
* Other Performance Improvements
    * Use reference counting to reduce unnecessary copies
* CPU Backend
    * Device properties for CPU
    * Improved performance when all buffers are indexed linearly
* CUDA Backend
    * Use streams in CUDA (no longer using default stream)
    * Using async cudaMem ops
    * Add 64-bit integer support for JIT functions
    * Performance improvements for CUDA JIT for non-linear 3D and 4D arrays
* OpenCL Backend
    * Improve compilation times for OpenCL backend
    * Performance improvements for non-linear JIT kernels on OpenCL
    * Improved shared memory load/store in many OpenCL kernels (PR 933)
    * Using cl.hpp v1.2.7

Bug Fixes
---------
* Common
    * Fix compatibility of c32/c64 arrays when operating with scalars
    * Fix median for all values of an array
    * Fix double free issue when indexing (30cbbc7)
    * Fix [bug](https://github.com/arrayfire/arrayfire/issues/901) in rank
    * Fix default values for scale throwing exception
    * Fix conjg raising exception on real input
    * Fix bug when using conjugate transpose for vector input
    * Fix issue with const input for array_proxy::get()
* CPU Backend
    * Fix randn generating same sequence for multiple calls
    * Fix setSeed for randu
    * Fix casting to and from complex
    * Check NULL values when allocating memory
    * Fix [offset issue](https://github.com/arrayfire/arrayfire/issues/923) for CPU element-wise operations

New Examples
------------
* Match Template
* Susan
* Heston Model (contributed by Michael Nowotny)

Installer
----------
* Fixed bug in automatic detection of ArrayFire when using with CMake in Windows
* The Linux libraries are now compiled with static version of FreeImage

Known Issues
------------
* OpenBlas can cause issues with QR factorization in CPU backend
* FreeImage older than 3.10 can cause issues with loadImageMem and
  saveImageMem
* OpenCL backend issues on OSX
    * AMD GPUs not supported because of driver issues
    * Intel CPUs not supported
    * Linear algebra functions do not work on Intel GPUs.
* Stability and correctness issues with open source OpenCL implementations such as Beignet, GalliumCompute.

v3.0.2
==============

Bug Fixes
--------------

* Added missing symbols from the compatible API
* Fixed a bug affecting corner rows and elements in \ref grad()
* Fixed linear interpolation bugs affecting large images in the following:
    - \ref approx1()
    - \ref approx2()
    - \ref resize()
    - \ref rotate()
    - \ref scale()
    - \ref skew()
    - \ref transform()

Documentation
-----------------

* Added missing documentation for \ref constant()
* Added missing documentation for `array::scalar()`
* Added supported input types for functions in `arith.h`

v3.0.1
==============

Bug Fixes
--------------

* Fixed header to work in Visual Studio 2015
* Fixed a bug in batched mode for FFT based convolutions
* Fixed graphics issues on OSX
* Fixed various bugs in visualization functions

Other improvements
---------------

* Improved fractal example
* New OSX installer
* Improved Windows installer
  * Default install path has been changed
* Fixed bug in machine learning examples

v3.0.0
=================

Major Updates
-------------

* ArrayFire is now open source
* Major changes to the visualization library
* Introducing handle based C API
* New backend: CPU fallback available for systems without GPUs
* Dense linear algebra functions available for all backends
* Support for 64 bit integers

Function Additions
------------------
* Data generation functions
    * range()
    * iota()

* Computer Vision Algorithms
    * features()
        * A data structure to hold features
    * fast()
        * FAST feature detector
    * orb()
        * ORB A feature descriptor extractor

* Image Processing
    * convolve1(), convolve2(), convolve3()
        * Specialized versions of convolve() to enable better batch support
    * fftconvolve1(), fftconvolve2(), fftconvolve3()
        * Convolutions in frequency domain to support larger kernel sizes
    * dft(), idft()
        * Unified functions for calling multi dimensional ffts.
    * matchTemplate()
        * Match a kernel in an image
    * sobel()
        * Get sobel gradients of an image
    * rgb2hsv(), hsv2rgb(), rgb2gray(), gray2rgb()
        * Explicit function calls to colorspace conversions
    * erode3d(), dilate3d()
        * Explicit erode and dilate calls for image morphing

* Linear Algebra
    * matmulNT(), matmulTN(), matmulTT()
        * Specialized versions of matmul() for transposed inputs
    * luInPlace(), choleskyInPlace(), qrInPlace()
        * In place factorizations to improve memory requirements
    * solveLU()
        * Specialized solve routines to improve performance
    * OpenCL backend now Linear Algebra functions

* Other functions
    * lookup() - lookup indices from a table
    * batchFunc() - helper function to perform batch operations

* Visualization functions
    * Support for multiple windows
    * window.hist()
        * Visualize the output of the histogram

* C API
    * Removed old pointer based C API
    * Introducing handle base C API
    * Just In Time compilation available in C API
    * C API has feature parity with C++ API
    * bessel functions removed
    * cross product functions removed
    * Kronecker product functions removed

Performance Improvements
------------------------
* Improvements across the board for OpenCL backend

API Changes
---------------------
* `print` is now af_print()
* seq(): The step parameter is now the third input
    * seq(start, step, end) changed to seq(start, end, step)
* gfor(): The iterator now needs to be seq()

Deprecated Function APIs
------------------------
Deprecated APIs are in af/compatible.h

* devicecount() changed to getDeviceCount()
* deviceset() changed to setDevice()
* deviceget() changed to getDevice()
* loadimage() changed to loadImage()
* saveimage() changed to saveImage()
* gaussiankernel() changed to gaussianKernel()
* alltrue() changed to allTrue()
* anytrue() changed to anyTrue()
* setunique() changed to setUnique()
* setunion() changed to setUnion()
* setintersect() changed to setIntersect()
* histequal() changed to histEqual()
* colorspace() changed to colorSpace()
* filter() deprecated. Use convolve1() and convolve2()
* mul() changed to product()
* deviceprop() changed to deviceProp()

Known Issues
----------------------
* OpenCL backend issues on OSX
    * AMD GPUs not supported because of driver issues
    * Intel CPUs not supported
    * Linear algebra functions do not work on Intel GPUs.
* Stability and correctness issues with open source OpenCL implementations such as Beignet, GalliumCompute.


text: Playground project for Raspberry Pi, I2C oled displays, AndroidThings, and more.


text:
namespace OmmitedDatabaseModel3WithCollections;

public class Entity6 : BaseEntity
{
    public Entity6()
    {
        this.Entities12 = new List<Entity12>();
    }

    public Guid Entity5Id { get; set; }
    public Entity5 Entity5 { get; set; }
    public Guid Entity20Id { get; set; }
    public Entity20 Entity20 { get; set; }
    public ICollection<Entity12> Entities12 { get; set; }
}


text:
package com.payu.ratel.tests;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.payu.ratel.Discover;
import com.payu.ratel.tests.service.Test2Service;
import com.payu.ratel.tests.service.TestServiceConfiguration;

@RunWith(SpringJUnit4ClassRunner.class)
@RatelTest(registerServices = TestServiceConfiguration.class)
public class ServiceTwoInterfacesDiscoverTest {

    @Discover
    private Test2Service test2Service;

    @Test
    public void shouldDiscoverTest2Service() {

        // when
        final int result = test2Service.power(2);

        // then
        assertThat(result).isEqualTo(4);
    }

}


text:
.tooltip {
    position: absolute;
    text-align: center;
    padding: 5px;
    background: #202020;
    color: #fff;
    border: 0px;
    border-radius: 5px;
    pointer-events: none;
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>Uses of Class org.drip.execution.generator.OptimalTrajectorySchemeDiscrete</title>
<meta name="date" content="2016-12-03">
<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes

Uses of Class
org.drip.execution.generator.OptimalTrajectorySchemeDiscrete

Packages that use OptimalTrajectorySchemeDiscrete

Package
Description

org.drip.execution.generator

Uses of OptimalTrajectorySchemeDiscrete in org.drip.execution.generator

Subclasses of OptimalTrajectorySchemeDiscrete in org.drip.execution.generator

Modifier and Type
Class and Description

class
Almgren2003LinearTradingEnhanced

Almgren2003LinearTradingEnhanced contains the Volatility Trading Trajectory generated by the Almgren
  (2003) Scheme under the Criterion of No-Drift AND Linear Temporary Impact Volatility.

class
AlmgrenChriss2000

AlmgrenChriss2000 generates the Trade/Holdings List of Optimal Execution Schedule for the Equally Spaced
  Trading Intervals based on the No-Drift Linear Impact Evolution Walk Parameters specified.

class
AlmgrenChriss2000Drift

AlmgrenChriss2000Drift generates the Trade/Holdings List of Optimal Execution Schedule for the Equally
  Spaced Trading Intervals based on the Linear Impact Evolution Walk Parameters with Drift specified.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes


text:
Ext.provide('Phlexible.elements.ElementTabPanel');

Ext.require('Phlexible.elements.tab.Data');
Ext.require('Phlexible.elements.tab.List');
Ext.require('Phlexible.elements.tab.Preview');
Ext.require('Phlexible.elements.tab.Links');
Ext.require('Phlexible.elements.tab.History');
Ext.require('Phlexible.elements.tab.AccessControl');
Ext.require('Phlexible.elements.tab.Routing');
Ext.require('Phlexible.elements.tab.Security');
Ext.require('Phlexible.elements.tab.Cache');

Phlexible.elements.ElementTabPanel = Ext.extend(Ext.TabPanel, {
    title: 'Element',
    cls: 'p-elements-tabs',
    border: false,
    plain: false,
    layoutOnTabChange: true,
    deferredRender: false,
    autoHeight: false,
    hideMode: 'offsets',
    accordionCollapsed: false,

    initComponent: function () {
        this.element.on({
            afterload: this.onAfterLoadElement,
            scope: this
        });

        /*
         this.on({
         xbeforetabchange: function(tabPanel, newTab, currentTab) {
         if (newTab.xtype !== 'elements-elementdatapanel') {
         tabPanel.element.fireEvent('disableSave');
         }
         },
         xtabchange: function(tabPanel, tab) {
         if (tab.element.tid && tab.xtype === 'elements-elementdatapanel') {
         tabPanel.element.fireEvent('enableSave');
         }
         }
         });
         */

        this.populateItems();

        Phlexible.elements.ElementTabPanel.superclass.initComponent.call(this);
    },

    onAfterLoadElement: function (element) {
        // set active tab to default value
        this.items.each(function (item) {
            //Phlexible.console.debug('xxx', element.data.default_tab, item.tabKey);
            if (element.data.default_tab === item.tabKey) {
                this.setActiveTab(item);
                return false;
            }
        }, this);

        // if current tab is disabled, select list tab (because it's always active)
        if (this.activeTab.disabled) {
            this.setActiveTab(0);

            if (this.activeTab.disabled) {
                this.setActiveTab(1);
            }
        }

        //if (this.activeTab && this.activeTab.xtype === 'elements-elementdatapanel') {
        //    element.fireEvent('enableSave');
        //}
    },

    populateItems: function () {
        this.items = [
            {
                xtype: 'elements-tab-list',
                tabKey: 'list',
                element: this.element,
                listeners: {
                    listLoadTeaser: function (teaser_id) {
                        this.fireEvent('listLoadTeaser', teaser_id);
                    },
                    listLoadNode: function (tid) {
                        this.fireEvent('listLoadNode', tid);
                    },
                    listReloadNode: function (tid) {
                        this.fireEvent('listReloadNode', tid);
                    },
                    scope: this
                }
            },
            {
                xtype: 'elements-tab-data',
                tabKey: 'data',
                element: this.element,
                accordionCollapsed: this.accordionCollapsed
            },
            {
                xtype: 'elements-tab-preview',
                tabKey: 'preview',
                element: this.element
            },
            {
                xtype: 'elements-tab-routing',
                tabKey: 'routing',
                element: this.element
            },
            {
                xtype: 'elements-tab-security',
                tabKey: 'security',
                element: this.element
            },
            {
                xtype: 'elements-tab-cache',
                tabKey: 'cache',
                element: this.element
            },
            {
                xtype: 'elements-tab-accesscontrol',
                tabKey: 'rights',
                element: this.element
            },
            {
                xtype: 'elements-tab-links',
                tabKey: 'links',
                element: this.element
            },
            {
                xtype: 'elements-tab-history',
                tabKey: 'history',
                element: this.element
            }
        ];
    }
});

Ext.reg('elements-elementtabpanel', Phlexible.elements.ElementTabPanel);