<commit_before>/*  Sirikata
 *  CassandraStorage.cpp
 *
 *  Copyright (c) 2011, Stanford University
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "CassandraStorage.hpp"
#include <sirikata/core/network/IOService.hpp>
#include <sirikata/core/network/IOWork.hpp>

#define CF_NAME "persistence"  // Column Family Name

namespace Sirikata {
namespace OH {

CassandraStorage::StorageAction::StorageAction()
 : type(Error),
   key(),
   value(NULL)
{
}

CassandraStorage::StorageAction::StorageAction(const StorageAction& rhs) {
    *this = rhs;
}

CassandraStorage::StorageAction::~StorageAction() {
    if (value != NULL)
        delete value;
}

CassandraStorage::StorageAction& CassandraStorage::StorageAction::operator=(const StorageAction& rhs) {
    type = rhs.type;
    key = rhs.key;
    keyEnd = rhs.keyEnd;
    if (rhs.value != NULL)
        value = new String(*(rhs.value));
    else<commit_msg>Add explanation of data layout for CassandraStorage.<commit_after>/*  Sirikata
 *  CassandraStorage.cpp
 *
 *  Copyright (c) 2011, Stanford University
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "CassandraStorage.hpp"
#include <sirikata/core/network/IOService.hpp>
#include <sirikata/core/network/IOWork.hpp>

#define CF_NAME "persistence"  // Column Family Name

/** Implementation Notes
 *  ====================
 *
 *  Data Layout
 *  -----------
 *  See http://wiki.apache.org/cassandra/DataModel for an explanation of the
 *  Cassandra data
 *  model. http://arin.me/blog/wtf-is-a-supercolumn-cassandra-data-model may be
 *  helpful too. In short, Cassandra is a multidimensional map (each ... means a
 *  set of these elements are maintained):
 *
 *   Keyspace {
 *    Super Column Family {
 *     Row {
 *      Super Column {
 *       Column (each column is key -> value pair w/ timestamp)
 *       ...
 *       Column
 *      } // Super Column
 *      ...
 *      Super Column {}
 *     } // Row
 *     ...
 *     Row {}
 *    } // Super Column Family
 *    ...
 *    Super Column Family {}
 *  } // Keyspace
 *  ...
 *  Keyspace {}
 *
 *  We map to this model as follows:
 *   * A keyspace is shared with other Sirikata storage - 'sirikata' by default.
 *   * A Super Column Family isolates Cassandra Storage - 'persistence' by
 *     default.
 *   * Buckets (i.e. HostedObjects) are each a Row in the persistence Super
 *     Column Family
 *   * Timestamps are each a Super Column.
 *   * Individual key -> value pairs are each a Column within the timestamps
 *     Super Column.
 *  This means you can think of Cassandra as one giant, 5-dimensional map and we
 *  use it as:
 *   Cassandra['sirikata']['persistence'][bucket][timestamp][key] = value;
 *   |--------fixed by settings---------|
 *   |-----------get per object storage---------|
 *   |-------get active timestamp storage for object-------|
 *
 *  You can see this structure when you use cassandra-cli to explore the data:
 *   > cassandra-cli
 *   >> connect localhost/9160;
 *   >> use sirikata; # Use 'sirikata' keyspace.
 *   # Change a few settings that force display to strings, which assumes you're
 *   # using utf8 keys
 *   >> assume persistence keys as utf8; # Bucket (row) names
 *   >> assume persistence comparator as utf8; # Timestamp (super column) names
 *   >> assume persistence sub_comparator as utf8; # Key (column) names
 *   # List 2 rows from persistence
 *   >> list persistence limit 2;
 *    -------------------
 *    RowKey: b10c1c63686e6b050000020002000001
 *    => (super_column=current,
 *         (column=foo, value=120608c0af271005120608808, timestamp=1329197745156495)
 *         (column=bar, value=c0af271005120608808, timestamp=1329197738171366))
 *    -------------------
 *    RowKey: b10c1c63686e6b050000020002000001
 *    => (super_column=current,
 *         (column=foo, value=120608c0af271005120608808, timestamp=1329197745156495)
 *        (column=bar, value=c0af271005120608808, timestamp=1329197738171366))
 *
 */

namespace Sirikata {
namespace OH {

CassandraStorage::StorageAction::StorageAction()
 : type(Error),
   key(),
   value(NULL)
{
}

CassandraStorage::StorageAction::StorageAction(const StorageAction& rhs) {
    *this = rhs;
}

CassandraStorage::StorageAction::~StorageAction() {
    if (value != NULL)
        delete value;
}

CassandraStorage::StorageAction& CassandraStorage::StorageAction::operator=(const StorageAction& rhs) {
    type = rhs.type;
    key = rhs.key;
    keyEnd = rhs.keyEnd;
    if (rhs.value != NULL)
        value = new String(*(rhs.value));
    else
{'fraction_non_alphanumeric': 0.10095897709110283, 'fraction_numerical': 0.0283697389451252, 'mean_word_length': 3.3733255678509027, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '664749', 'n_tokens_mistral': 2282, 'n_tokens_neox': 2040, 'n_words': 791}