如何在O(1)上完成getMetricByStatString(statString)方法?

时间:2015-04-14 15:18:48

标签: javascript time-complexity

//  CatalogAPI is a object that contains two methods for data retrieving
var CatalogAPI = {
    // Returns a promise.  When it resolves, it returns an array of arrays, containing category data.    
    getCategories: function () {
        return new Promise(function (resolve) {
            var categoriesData = [[1, 'device', 'http', 'HTTP'],
                                  [2, 'device', 'dns', 'DNS'],
                                  [3, 'application', 'ldap', 'LDAP'],
                                  [4, 'application', 'mongo', 'MongoDB']];
            resolve(categoriesData);
        });
    },
    // Returns a promise.  When it resolves, it returns an array of arrays, containing metric data.
    getMetrics: function () {
        return new Promise(function (resolve) {
            var metricsData = [[1, 1, 'req', 'Requests'],
                               [2, 1, 'rsp', 'Responses'],
                               [3, 1, 'tprocess', 'Server Processing Time'],
                               [4, 2, 'req', 'Requests'],
                               [5, 2, 'rsp', 'Responses'],
                               [6, 2, 'trunc', 'Truncated Responses'],
                               [7, 3, 'plain', 'Plain Text Messages'],
                               [8, 3, 'sasl', 'SASL Messages'],
                               [9, 3, 'error', 'Errors'],
                               [10, 4, 'req', 'Requests'],
                               [11, 4, 'rsp', 'Responses'],
                               [12, 4, 'tprocess', 'Server Processing Time']];
            resolve(metricsData);
        });
    }
};

/*  custom constructor that creates a Category object
    parameters: categoryData, an array containing category data in the following order:
    [0] = ID, [1] = objectType, [2] = statName, [3] = displayName
*/
function Category(categoryData) {
    this.ID = categoryData[0];
    this.objectType = categoryData[1];
    this.statName = categoryData[2];
    this.displayName = categoryData[3];
};

/*  custom constructor that creates a Metric object
    parameters: metricData, an array containing metric data in the following order:
    [0] = ID, [1] = categoryID, [2] = fieldName, [3] = displayName
*/
function Metric(metricData) {
    this.ID = metricData[0];
    this.categoryID = metricData[1];
    this.fieldName = metricData[2];
    this.displayName = metricData[3];
};

/*  custom contructor that creates a Catalog object
    attributes: initilized --> indicates if the object Catalog has been initialized already, set to false when first created
                categories --> contains the categories data downloaded thru the CatalogAPI, set to empty when first created
                metrics    --> contains the metrics data downloaded thru the CatalogAPI, set to empty when first created
    methods:    getCategoryByID(ID)
                getCategoryByStatString(statString)
                getMetricByID(ID)
                getMetricByStatString(statString)
                initialize()
*/
function Catalog() {
    this.initialized = false;
    this.categories = [];
    this.metrics = [];

    /*  searches the categories to check if a category matches a given ID,
        if found, it returns a Category object with the found category's attributes
        else, it returns a Category object with null attributes
    */
    this.getCategoryByID = function (ID) {
        var categoryObj = new Category([null, null, null, null]);

        for (var i = 0; i < this.categories.length; i++) {
            if (this.categories[i][0] === ID) {
                categoryObj = new Category(this.categories[i]);
            }
        }
        return categoryObj;
    };

    /*  searches the categories to check if a category matches a given statString,
        if found, it returns a Category object with the found category's attributes
        else, it returns a Category object with null attributes
    */
    this.getCategoryByStatString = function (statString) {
        var categoryObj = new Category([null, null, null, null]);
        var splittedStatString = statString.split(".");

        for (var i = 0; i < this.categories.length; i++) {
            if ((this.categories[i][1] === splittedStatString[1]) &&
                (this.categories[i][2] === splittedStatString[2])) {
                categoryObj = new Category(this.categories[i]);
            }
        }
        return categoryObj;
    };

    /*  searches the metrics to check if a metric matches a given ID,
        if found, it returns a Metric object with the found metric's attributes
        else, it returns a Metric object with null attributes
    */
    this.getMetricByID = function (ID) {
        var metricObj = new Metric([null, null, null, null]);

        for (var i = 0; i < this.metrics.length; i++) {
            if (this.metrics[i][0] === ID) {
                metricObj = new Metric(this.metrics[i]);
            }
        }
        return metricObj;

    };

    /*  searches the metrics to check if a metric matches a given statString,
        if found, it returns a Metric object with the found metric's attributes
        else, it returns a Metric object with null attributes
    */
    this.getMetricByStatString = function (statString) {
        var metricObj = new Metric([null, null, null, null]);

        // method getCategoryByStatString is called to identify the cateogry that the metric belongs to
        var splittedStatString = statString.split(":");
        var categoryObj = this.getCategoryByStatString(splittedStatString[0]);

        // once the metric's cateogry is known, the metric is found by searching for categoryID and fieldName
        for (var i = ((categoryObj.ID - 1) * 3) ; i < (categoryObj.ID * 3) ; i++) {
            if (this.metrics[i][2] === splittedStatString[1]) {
                metricObj = new Metric(this.metrics[i]);
            }
        }
        return metricObj;
    };

    /*  it returns a promise when the Catalog is ready to use, 
        if the catalog data was already downloaded, it does not downloads the data again
    */
    this.initialize = function () {
        // reference to catalog class, so that refering to catalog inside functions is easier
        var catalogReference = this;

        /* if initialized === true, then do not download catalog data, 
           just return promise acknowloging that the Catalog is ready to be use */
        if (catalogReference.initialized) {
            return new Promise(function (resolve) {
                resolve();
            });
        }
            /* if initialized === false, then download the catalog 
            data by calling the CatalogAPI methods */
        else {
            var categoriesData = CatalogAPI.getCategories();
            var metricsData = CatalogAPI.getMetrics();
            var dataReady = Promise.all([categoriesData, metricsData]).then(function (catalogData) {
                catalogReference.categories = catalogData[0];
                catalogReference.metrics = catalogData[1];
            });

            catalogReference.initialized = true;
            return dataReady;
        }
    };
};

var c = new Catalog();
c.initialize().then(function () {

    var category1, category2, metric1, metric2;

    // Test category lookups
    category1 = c.getCategoryByID(1);
    category2 = c.getCategoryByStatString('extrahop.device.http');

    if (category1.ID === category2.ID) {
        console.log(category1.displayName + ' lookups match!');
    }

    // Test metric lookups
    metric1 = c.getMetricByID(12);
    metric2 = c.getMetricByStatString('extrahop.application.mongo:tprocess');

    if (metric1.ID === metric2.ID) {
        console.log(metric1.displayName + ' lookups match!');
    }
});

方法getMetricBySatString(statString)有一个参数,它是一个包含来自categoriesData数组的2个属性和一个来自metricData的字符串,它应该在O(1)中完成,任何关于如何实现的想法要做到这一点?

感谢。

0 个答案:

没有答案