AvlIndex AvlNode::balance(AvlIndex tree) { int balance, lh, rh; balance = get_balance(tree); if (balance < -1) { balance = get_balance(AVLNODE(tree)->left); if (balance > 0) tree = left_right(tree); else tree = left_left(tree); } else if (balance > 1) { balance = get_balance(AVLNODE(tree)->right); if (balance < 0) tree = right_left(tree); else tree = right_right(tree); } lh = node_height(AVLNODE(tree)->left); rh = node_height(AVLNODE(tree)->right); AVLNODE(tree)->height = (lh > rh ? lh : rh) + 1; return tree; }
asset market_order::get_quantity( const price& relative )const { switch( order_type_enum( type ) ) { case relative_bid_order: case bid_order: { // balance is in USD divide by price return get_balance() * get_price(relative); } case relative_ask_order: case ask_order: { // balance is in USD divide by price return get_balance(); } case short_order: { return get_balance(); } case cover_order: { return asset( (*collateral * BTS_BLOCKCHAIN_MCALL_D2C_NUMERATOR) / BTS_BLOCKCHAIN_MCALL_D2C_DENOMINATOR ); } default: FC_ASSERT( false, "Not Implemented" ); } // NEVER GET HERE..... //return get_balance() * get_price(); }
asset market_order::get_quote_quantity( const price& relative )const { switch( order_type_enum( type ) ) { case relative_bid_order: case bid_order: { // balance is in USD divide by price return get_balance(); } case relative_ask_order: case ask_order: { // balance is in USD divide by price return get_balance() * get_price(relative); } case short_order: { return get_balance() * get_price(relative); } case cover_order: { return get_balance(); } default: FC_ASSERT( false, "Not Implemented" ); } // NEVER GET HERE..... // return get_balance() * get_price(); }
NODE *balance_tree (NODE **node) { int height_diff; height_diff = get_balance(*node); printf("밸런스값 %d\n", height_diff); if (height_diff > 1) { if (get_balance((*node)->left) > 0) { *node = rotate_LL(*node); }else { *node = rotate_LR(*node); } } else if (height_diff < -1) { if (get_balance((*node)->right) < 0) { *node = rotate_RR(*node); } else { *node = rotate_LL(*node); } } return *node; }
void Node::balance_function(Node *&root) { if(!root) return; int balance_factor = get_balance(root); //TODO remove //cout << "balance_factor at : " << root->word // << " is " << balance_factor << endl; if(balance_factor == 2) { int left_balance = get_balance(root->left); //left has more than right //so left should become root if(left_balance == 0) { cout << "this shouldn't happen, if it does we have a problem" << endl; } if(left_balance == 1) { rotate_clockwise(root); } if(left_balance == -1) { rotate_counter_clockwise(root->left); rotate_clockwise(root); } } if(balance_factor == -2) { int right_balance = get_balance(root->right); //right has more than left if(right_balance == 0) { cout << "this shouldn't happen, if it does we have a problem" << endl; } if(right_balance == 1) { rotate_clockwise(root->right); rotate_counter_clockwise(root); } if(right_balance == -1) { rotate_counter_clockwise(root); } } return; }
limit_order_id_type trigger_swan(share_type amount1, share_type amount2) { set_expiration( db, trx ); // starting out with price 1:1 set_feed( 1, 1 ); // start out with 2:1 collateral borrow(borrower(), swan().amount(amount1), back().amount(2*amount1)); borrow(borrower2(), swan().amount(amount2), back().amount(4*amount2)); FC_ASSERT( get_balance(borrower(), swan()) == amount1 ); FC_ASSERT( get_balance(borrower2(), swan()) == amount2 ); FC_ASSERT( get_balance(borrower() , back()) == init_balance - 2*amount1 ); FC_ASSERT( get_balance(borrower2(), back()) == init_balance - 4*amount2 ); set_feed( 1, 2 ); // this sell order is designed to trigger a black swan limit_order_id_type oid = create_sell_order( borrower2(), swan().amount(1), back().amount(3) )->id; FC_ASSERT( get_balance(borrower(), swan()) == amount1 ); FC_ASSERT( get_balance(borrower2(), swan()) == amount2 - 1 ); FC_ASSERT( get_balance(borrower() , back()) == init_balance - 2*amount1 ); FC_ASSERT( get_balance(borrower2(), back()) == init_balance - 2*amount2 ); BOOST_CHECK( swan().bitasset_data(db).has_settlement() ); return oid; }
/* * 'pparent', 'unbalanced' and 'is_left' are only used for * insertions. Normally GCC will notice this and get rid of them for * lookups. */ static inline struct avltree_node *do_lookup(const struct avltree_node *key, const struct avltree *tree, struct avltree_node **pparent, struct avltree_node **unbalanced, int *is_left) { struct avltree_node *node = tree->root; int res = 0; *pparent = NULL; *unbalanced = node; *is_left = 0; while (node) { if (get_balance(node) != 0) *unbalanced = node; res = tree->cmp_fn(node, key); if (res == 0) return node; *pparent = node; if ((*is_left = res > 0)) node = node->left; else node = node->right; } return NULL; }
static inline struct FwAvlNode* do_lookup(const uint32_t key, const struct FwAvlTree* tree, struct FwAvlNode** pparent, struct FwAvlNode** unbalanced, int* is_left) { struct FwAvlNode* node = tree->root; *pparent = NULL; *unbalanced = node; *is_left = 0; while (node != NULL) { if(get_balance(node) != 0) { *unbalanced = node; } *pparent = node; if(key == node->key) { return node; } else { if((*is_left = node->key > key) != 0) node = node->left; else node = node->right; } } return NULL; }
int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct i2c_client *client = v4l2_get_subdevdata(sd); switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: ctrl->value = get_volume(client); break; case V4L2_CID_AUDIO_BASS: ctrl->value = get_bass(client); break; case V4L2_CID_AUDIO_TREBLE: ctrl->value = get_treble(client); break; case V4L2_CID_AUDIO_BALANCE: ctrl->value = get_balance(client); break; case V4L2_CID_AUDIO_MUTE: ctrl->value = get_mute(client); break; default: return -EINVAL; } return 0; }
template <typename T, typename X> bool scaler<T, X>::scale_with_log_balance() { T balance = get_balance(); T balance_before_scaling = balance; // todo : analyze the scale order : rows-columns, or columns-rows. Iterate if needed for (int i = 0; i < 10; i++) { scale_rows(); scale_columns(); T nb = get_balance(); if (nb < T(0.9) * balance) { balance = nb; } else { balance = nb; break; } } return balance <= balance_before_scaling; }
uint64_t database_fixture::fund( const account_object& account, const asset& amount /* = asset(500000) */ ) { transfer(account_id_type()(db), account, amount); return get_balance(account, amount.asset_id(db)); }
int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) { struct v4l2_control *ctrl = arg; switch (cmd) { case VIDIOC_INT_AUDIO_CLOCK_FREQ: return set_audclk_freq(client, *(u32 *)arg); case VIDIOC_G_CTRL: switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: ctrl->value = get_volume(client); break; case V4L2_CID_AUDIO_BASS: ctrl->value = get_bass(client); break; case V4L2_CID_AUDIO_TREBLE: ctrl->value = get_treble(client); break; case V4L2_CID_AUDIO_BALANCE: ctrl->value = get_balance(client); break; case V4L2_CID_AUDIO_MUTE: ctrl->value = get_mute(client); break; default: return -EINVAL; } break; case VIDIOC_S_CTRL: switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: set_volume(client, ctrl->value); break; case V4L2_CID_AUDIO_BASS: set_bass(client, ctrl->value); break; case V4L2_CID_AUDIO_TREBLE: set_treble(client, ctrl->value); break; case V4L2_CID_AUDIO_BALANCE: set_balance(client, ctrl->value); break; case V4L2_CID_AUDIO_MUTE: set_mute(client, ctrl->value); break; default: return -EINVAL; } break; default: return -EINVAL; } return 0; }
NODE *balance_tree(NODE **node){ int height_diff; height_diff = get_balance(*node); printf("밸런스 값 : %d\n", height_diff); if(height_diff > 1){ if(get_balance((*node)->left) > 0) *node = rotate_LL(node); else *node = rotate_LR(node); } else if(height_diff <-1){ if(get_balance((*node)->left) >0) *node = rotate_RR(node); else *node = rotate_RL(node); } return *node; }
node *fixup(node *root) { int balance = get_balance(root); if(balance >1 && get_balance(root->left)>=0) { return right_rotate(root); } if(balance >1 && get_balance(root->left)<0) { root->left = left_rotate(root->left); return right_rotate(root); } if(balance < -1 && get_balance(root->right)<=0) { return left_rotate(root); } if(balance < -1 && get_balance(root->right)>0) { root->right = right_rotate(root->right); return left_rotate(root); } return root; }
int main(){ NODE *node = 0; int i; int height; int in; NODE *temp = 0; int a[] = {6,3,1,5,7,12}; display(root); for(i=0; i<6; i++){ insert_data(a[i]); display(root); } insert_data(9); display(root); printf("Tree height test\n"); getchar(); //height = get_height(root); //printf("root height : %d\n", height); /* while(1){ printf("input the node data(exit -1):"); scanf("%d",&in)); if(in == -1){ printf("exit\n"); break; } temp->data = in; height = get_height(temp); printf("%d의 높이: %d\n", temp->data, height); temp = 0; height = 0; }*/ while(1){ printf("input the node data(exit -1) : "); scanf("%d", &in); fflush(stdin); if(in==-1) break; node = search(root, in); height = get_height(node); printf("%d의 높이는 %d\n", in, height); height = get_balance(node); printf("%d의 밸런스 값 : %d\n", in ,height); getchar(); } return 0; }
static switch_status_t process_hangup(switch_core_session_t *session) { const char* billaccount; switch_channel_t *channel = NULL; channel = switch_core_session_get_channel(session); /* Resume any paused billings, just in case */ /* nibblebill_resume(session); */ /* Now go handle like normal billing */ do_billing(session); billaccount = switch_channel_get_variable(channel, "nibble_account"); if (billaccount) { switch_channel_set_variable_printf(channel, "nibble_current_balance", "%f", get_balance(billaccount, channel)); } return SWITCH_STATUS_SUCCESS; }
int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl) { switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: ctrl->value = get_volume(cx); break; case V4L2_CID_AUDIO_BASS: ctrl->value = get_bass(cx); break; case V4L2_CID_AUDIO_TREBLE: ctrl->value = get_treble(cx); break; case V4L2_CID_AUDIO_BALANCE: ctrl->value = get_balance(cx); break; case V4L2_CID_AUDIO_MUTE: ctrl->value = get_mute(cx); break; default: return -EINVAL; } return 0; }
void wait_for_action() { interface_hardware.send(display_withdrawal_options()); incoming.wait() .handle<withdraw_pressed>( [&](withdraw_pressed const & msg) { withdrawal_amount = msg.amount; bank.send(withdraw(account, msg.amount, incoming)); state = &atm::process_withdrawal; } ) .handle<balance_pressed>( [&](balance_pressed const & msg) { bank.send(get_balance(account, incoming)); state = &atm::process_balance; } ) .handle<cancel_pressed>( [&](cancel_pressed const & msg) { state = &atm::done_processing; } ); }
node insert(node n, int e) { if (!n) return new_Node(e); if (e < n->element) n->left = insert(n->left, e); else n->right = insert(n->right, e); n->height = max(height(n->left), height(n->right)) + 1; int balance = get_balance(n); // Left-Left case if (balance > 1 && e < n->left->element) return right_rotate(n); // Left-Right case if (balance > 1 && e > n->left->element) { n->left = left_rotate(n->left); return right_rotate(n); } // Right-Right case if (balance < -1 && e > n->right->element) return left_rotate(n); // Right-Left case if (balance < -1 && e < n->right->element) { n->right = right_rotate(n->right); return left_rotate(n); } return n; }
/* Insertion never needs more than 2 rotations */ struct avltree_node *avltree_insert(struct avltree_node *node, struct avltree *tree) { struct avltree_node *parent = 0, *unbalanced = tree->root; bool is_left; // Find a suitable parent. for (struct avltree_node *next_parent = tree->root; next_parent != 0;) { parent = next_parent; if (get_balance(parent) != 0) unbalanced = parent; int cmp_r = tree->cmp_fn(parent, node); if (cmp_r == 0) { if (tree->unique_index) return parent; // For non unique indexes any insert direction is acceptable. if (parent->left == 0) { is_left = true; break; } else if (parent->right == 0) { is_left = false; break; } else { // Be smart and travel to the least balanced subtree to minimize balancing overhead. next_parent = (get_balance(parent) <= 0)? parent->left: parent->right; } } else { is_left = (cmp_r > 0); next_parent = is_left? parent->left: parent->right; } } INIT_NODE(node); if (!parent) { tree->root = node; tree->first = tree->last = node; tree->height++; return 0; } if (is_left) { if (parent == tree->first) tree->first = node; } else { if (parent == tree->last) tree->last = node; } set_parent(parent, node); set_child(node, parent, is_left); for (;;) { if (parent->left == node) dec_balance(parent); else inc_balance(parent); if (parent == unbalanced) { for (;;) { node = parent; node->count++; if (is_root(node)) break; parent = get_parent(parent); } break; } node = parent; node->count++; parent = get_parent(parent); } switch (get_balance(unbalanced)) { case 1: case -1: tree->height++; /* fall through */ case 0: break; case 2: { struct avltree_node *right = unbalanced->right; if (get_balance(right) == 1) { set_balance(0, unbalanced); set_balance(0, right); } else { switch (get_balance(right->left)) { case 1: set_balance(-1, unbalanced); set_balance(0, right); break; case 0: set_balance(0, unbalanced); set_balance(0, right); break; case -1: set_balance(0, unbalanced); set_balance(1, right); break; } set_balance(0, right->left); rotate_right(right, tree); } rotate_left(unbalanced, tree); break; } case -2: { struct avltree_node *left = unbalanced->left; if (get_balance(left) == -1) { set_balance(0, unbalanced); set_balance(0, left); } else { switch (get_balance(left->right)) { case 1: set_balance(0, unbalanced); set_balance(-1, left); break; case 0: set_balance(0, unbalanced); set_balance(0, left); break; case -1: set_balance(1, unbalanced); set_balance(0, left); break; } set_balance(0, left->right); rotate_left(left, tree); } rotate_right(unbalanced, tree); break; } } return 0; }
/* **Insert node in the binary tree whose root is root. The innsertion is made to create an AVL binary tree. **Returns 1 if the word was inserted or 0 if the word already existed. */ int insert_word(AVL_Node *&root, string word, string translation) { if(root == NULL) { root = new_node(word, translation, NULL); return 1; } AVL_Node *aux = root; while(1) { int comparison = word.compare(aux->word); if(comparison < 0) { if(aux->son_left == NULL) { //insert new node to the left of the subtree aux->son_left = new_node(word, translation, aux); break; } aux = aux->son_left; } else if(comparison > 0) { if(aux->son_right == NULL) { //insert new node to the right of the subtree aux->son_right = new_node(word, translation, aux); break; } aux = aux->son_right; } else { //There's a node with that word return 0; } } //Go up the tree and correct the heights. If the height is changed then check //if rebalance is needed. Notice that aux begins in the parent of the new node while(aux != NULL) { update_height(aux); int balance = get_balance(aux); if(balance == 2) { if(get_balance(aux->son_right) == -1) { rotate_right(aux->son_right);//Double rotation } rotate_left(aux); if(aux == root) { //Updates the root of the tree if it shifts root = aux->parent; } } else if(balance == -2) { if(get_balance(aux->son_left) == 1) { rotate_left(aux->son_left);//Double rotation } rotate_right(aux); if(aux == root) { //Updates the root of the tree if it shifts root = aux->parent; } } aux = aux->parent; } return 1; }
void database::init_genesis(const genesis_state_type& genesis_state) { try { FC_ASSERT( genesis_state.initial_timestamp != time_point_sec(), "Must initialize genesis timestamp." ); FC_ASSERT( genesis_state.initial_timestamp.sec_since_epoch() % GRAPHENE_DEFAULT_BLOCK_INTERVAL == 0, "Genesis timestamp must be divisible by GRAPHENE_DEFAULT_BLOCK_INTERVAL." ); FC_ASSERT(genesis_state.initial_witness_candidates.size() > 0, "Cannot start a chain with zero witnesses."); FC_ASSERT(genesis_state.initial_active_witnesses <= genesis_state.initial_witness_candidates.size(), "initial_active_witnesses is larger than the number of candidate witnesses."); _undo_db.disable(); struct auth_inhibitor { auth_inhibitor(database& db) : db(db), old_flags(db.node_properties().skip_flags) { db.node_properties().skip_flags |= skip_authority_check; } ~auth_inhibitor() { db.node_properties().skip_flags = old_flags; } private: database& db; uint32_t old_flags; } inhibitor(*this); transaction_evaluation_state genesis_eval_state(this); flat_index<block_summary_object>& bsi = get_mutable_index_type< flat_index<block_summary_object> >(); bsi.resize(0xffff+1); // Create blockchain accounts fc::ecc::private_key null_private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key"))); create<account_balance_object>([](account_balance_object& b) { b.balance = GRAPHENE_MAX_SHARE_SUPPLY; }); const account_object& committee_account = create<account_object>( [&](account_object& n) { n.membership_expiration_date = time_point_sec::maximum(); n.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; n.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; n.owner.weight_threshold = 1; n.active.weight_threshold = 1; n.name = "committee-account"; n.statistics = create<account_statistics_object>( [&](account_statistics_object& s){ s.owner = n.id; }).id; }); FC_ASSERT(committee_account.get_id() == GRAPHENE_COMMITTEE_ACCOUNT); FC_ASSERT(create<account_object>([this](account_object& a) { a.name = "witness-account"; a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id; a.owner.weight_threshold = 1; a.active.weight_threshold = 1; a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_WITNESS_ACCOUNT; a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; }).get_id() == GRAPHENE_WITNESS_ACCOUNT); FC_ASSERT(create<account_object>([this](account_object& a) { a.name = "relaxed-committee-account"; a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id; a.owner.weight_threshold = 1; a.active.weight_threshold = 1; a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_RELAXED_COMMITTEE_ACCOUNT; a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; }).get_id() == GRAPHENE_RELAXED_COMMITTEE_ACCOUNT); FC_ASSERT(create<account_object>([this](account_object& a) { a.name = "null-account"; a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id; a.owner.weight_threshold = 1; a.active.weight_threshold = 1; a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_NULL_ACCOUNT; a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = 0; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT; }).get_id() == GRAPHENE_NULL_ACCOUNT); FC_ASSERT(create<account_object>([this](account_object& a) { a.name = "temp-account"; a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id; a.owner.weight_threshold = 0; a.active.weight_threshold = 0; a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_TEMP_ACCOUNT; a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; }).get_id() == GRAPHENE_TEMP_ACCOUNT); FC_ASSERT(create<account_object>([this](account_object& a) { a.name = "proxy-to-self"; a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id; a.owner.weight_threshold = 1; a.active.weight_threshold = 1; a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_NULL_ACCOUNT; a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = 0; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT; }).get_id() == GRAPHENE_PROXY_TO_SELF_ACCOUNT); // Create more special accounts while( true ) { uint64_t id = get_index<account_object>().get_next_id().instance(); if( id >= genesis_state.immutable_parameters.num_special_accounts ) break; const account_object& acct = create<account_object>([&](account_object& a) { a.name = "special-account-" + std::to_string(id); a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id; a.owner.weight_threshold = 1; a.active.weight_threshold = 1; a.registrar = a.lifetime_referrer = a.referrer = id; a.membership_expiration_date = time_point_sec::maximum(); a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; }); FC_ASSERT( acct.get_id() == account_id_type(id) ); remove( acct ); } // Create core asset const asset_dynamic_data_object& dyn_asset = create<asset_dynamic_data_object>([&](asset_dynamic_data_object& a) { a.current_supply = GRAPHENE_MAX_SHARE_SUPPLY; }); const asset_object& core_asset = create<asset_object>( [&]( asset_object& a ) { a.symbol = GRAPHENE_SYMBOL; a.options.max_supply = genesis_state.max_core_supply; a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS; a.options.flags = 0; a.options.issuer_permissions = 0; a.issuer = GRAPHENE_NULL_ACCOUNT; a.options.core_exchange_rate.base.amount = 1; a.options.core_exchange_rate.base.asset_id = 0; a.options.core_exchange_rate.quote.amount = 1; a.options.core_exchange_rate.quote.asset_id = 0; a.dynamic_asset_data_id = dyn_asset.id; }); assert( asset_id_type(core_asset.id) == asset().asset_id ); assert( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) ); // Create more special assets while( true ) { uint64_t id = get_index<asset_object>().get_next_id().instance(); if( id >= genesis_state.immutable_parameters.num_special_assets ) break; const asset_dynamic_data_object& dyn_asset = create<asset_dynamic_data_object>([&](asset_dynamic_data_object& a) { a.current_supply = 0; }); const asset_object& asset_obj = create<asset_object>( [&]( asset_object& a ) { a.symbol = "SPECIAL" + std::to_string( id ); a.options.max_supply = 0; a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS; a.options.flags = 0; a.options.issuer_permissions = 0; a.issuer = GRAPHENE_NULL_ACCOUNT; a.options.core_exchange_rate.base.amount = 1; a.options.core_exchange_rate.base.asset_id = 0; a.options.core_exchange_rate.quote.amount = 1; a.options.core_exchange_rate.quote.asset_id = 0; a.dynamic_asset_data_id = dyn_asset.id; }); FC_ASSERT( asset_obj.get_id() == asset_id_type(id) ); remove( asset_obj ); } chain_id_type chain_id = genesis_state.compute_chain_id(); // Create global properties create<global_property_object>([&](global_property_object& p) { p.parameters = genesis_state.initial_parameters; // Set fees to zero initially, so that genesis initialization needs not pay them // We'll fix it at the end of the function p.parameters.current_fees->zero_all_fees(); }); create<dynamic_global_property_object>([&](dynamic_global_property_object& p) { p.time = genesis_state.initial_timestamp; p.dynamic_flags = 0; p.witness_budget = 0; p.recent_slots_filled = fc::uint128::max_value(); }); FC_ASSERT( (genesis_state.immutable_parameters.min_witness_count & 1) == 1, "min_witness_count must be odd" ); FC_ASSERT( (genesis_state.immutable_parameters.min_committee_member_count & 1) == 1, "min_committee_member_count must be odd" ); create<chain_property_object>([&](chain_property_object& p) { p.chain_id = chain_id; p.immutable_parameters = genesis_state.immutable_parameters; } ); create<block_summary_object>([&](block_summary_object&) {}); // Create initial accounts for( const auto& account : genesis_state.initial_accounts ) { account_create_operation cop; cop.name = account.name; cop.registrar = GRAPHENE_TEMP_ACCOUNT; cop.owner = authority(1, account.owner_key, 1); if( account.active_key == public_key_type() ) { cop.active = cop.owner; cop.options.memo_key = account.owner_key; } else { cop.active = authority(1, account.active_key, 1); cop.options.memo_key = account.active_key; } account_id_type account_id(apply_operation(genesis_eval_state, cop).get<object_id_type>()); if( account.is_lifetime_member ) { account_upgrade_operation op; op.account_to_upgrade = account_id; op.upgrade_to_lifetime_member = true; apply_operation(genesis_eval_state, op); } } // Helper function to get account ID by name const auto& accounts_by_name = get_index_type<account_index>().indices().get<by_name>(); auto get_account_id = [&accounts_by_name](const string& name) { auto itr = accounts_by_name.find(name); FC_ASSERT(itr != accounts_by_name.end(), "Unable to find account '${acct}'. Did you forget to add a record for it to initial_accounts?", ("acct", name)); return itr->get_id(); }; // Helper function to get asset ID by symbol const auto& assets_by_symbol = get_index_type<asset_index>().indices().get<by_symbol>(); const auto get_asset_id = [&assets_by_symbol](const string& symbol) { auto itr = assets_by_symbol.find(symbol); // TODO: This is temporary for handling BTS snapshot if( symbol == "BTS" ) itr = assets_by_symbol.find(GRAPHENE_SYMBOL); FC_ASSERT(itr != assets_by_symbol.end(), "Unable to find asset '${sym}'. Did you forget to add a record for it to initial_assets?", ("sym", symbol)); return itr->get_id(); }; map<asset_id_type, share_type> total_supplies; map<asset_id_type, share_type> total_debts; // Create initial assets for( const genesis_state_type::initial_asset_type& asset : genesis_state.initial_assets ) { asset_id_type new_asset_id = get_index_type<asset_index>().get_next_id(); total_supplies[ new_asset_id ] = 0; asset_dynamic_data_id_type dynamic_data_id; optional<asset_bitasset_data_id_type> bitasset_data_id; if( asset.is_bitasset ) { int collateral_holder_number = 0; total_debts[ new_asset_id ] = 0; for( const auto& collateral_rec : asset.collateral_records ) { account_create_operation cop; cop.name = asset.symbol + "-collateral-holder-" + std::to_string(collateral_holder_number); boost::algorithm::to_lower(cop.name); cop.registrar = GRAPHENE_TEMP_ACCOUNT; cop.owner = authority(1, collateral_rec.owner, 1); cop.active = cop.owner; account_id_type owner_account_id = apply_operation(genesis_eval_state, cop).get<object_id_type>(); modify( owner_account_id(*this).statistics(*this), [&]( account_statistics_object& o ) { o.total_core_in_orders = collateral_rec.collateral; }); create<call_order_object>([&](call_order_object& c) { c.borrower = owner_account_id; c.collateral = collateral_rec.collateral; c.debt = collateral_rec.debt; c.call_price = price::call_price(chain::asset(c.debt, new_asset_id), chain::asset(c.collateral, core_asset.id), GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO); }); total_supplies[ 0 ] += collateral_rec.collateral; total_debts[ new_asset_id ] += collateral_rec.debt; ++collateral_holder_number; } bitasset_data_id = create<asset_bitasset_data_object>([&](asset_bitasset_data_object& b) { b.options.short_backing_asset = core_asset.id; b.options.minimum_feeds = GRAPHENE_DEFAULT_MINIMUM_FEEDS; }).id; } dynamic_data_id = create<asset_dynamic_data_object>([&](asset_dynamic_data_object& d) { d.accumulated_fees = asset.accumulated_fees; }).id; total_supplies[ new_asset_id ] += asset.accumulated_fees; create<asset_object>([&](asset_object& a) { a.symbol = asset.symbol; a.options.description = asset.description; a.precision = asset.precision; string issuer_name = asset.issuer_name; a.issuer = get_account_id(issuer_name); a.options.max_supply = asset.max_supply; a.options.flags = witness_fed_asset; a.options.issuer_permissions = charge_market_fee | global_settle | witness_fed_asset | committee_fed_asset; a.dynamic_asset_data_id = dynamic_data_id; a.bitasset_data_id = bitasset_data_id; }); } // Create initial balances share_type total_allocation; for( const auto& handout : genesis_state.initial_balances ) { const auto asset_id = get_asset_id(handout.asset_symbol); create<balance_object>([&handout,&get_asset_id,total_allocation,asset_id](balance_object& b) { b.balance = asset(handout.amount, asset_id); b.owner = handout.owner; }); total_supplies[ asset_id ] += handout.amount; } // Create initial vesting balances for( const genesis_state_type::initial_vesting_balance_type& vest : genesis_state.initial_vesting_balances ) { const auto asset_id = get_asset_id(vest.asset_symbol); create<balance_object>([&](balance_object& b) { b.owner = vest.owner; b.balance = asset(vest.amount, asset_id); linear_vesting_policy policy; policy.begin_timestamp = vest.begin_timestamp; policy.vesting_cliff_seconds = 0; policy.vesting_duration_seconds = vest.vesting_duration_seconds; policy.begin_balance = vest.begin_balance; b.vesting_policy = std::move(policy); }); total_supplies[ asset_id ] += vest.amount; } if( total_supplies[ 0 ] > 0 ) { adjust_balance(GRAPHENE_COMMITTEE_ACCOUNT, -get_balance(GRAPHENE_COMMITTEE_ACCOUNT,{})); } else { total_supplies[ 0 ] = GRAPHENE_MAX_SHARE_SUPPLY; } const auto& idx = get_index_type<asset_index>().indices().get<by_symbol>(); auto it = idx.begin(); bool has_imbalanced_assets = false; while( it != idx.end() ) { if( it->bitasset_data_id.valid() ) { auto supply_itr = total_supplies.find( it->id ); auto debt_itr = total_debts.find( it->id ); FC_ASSERT( supply_itr != total_supplies.end() ); FC_ASSERT( debt_itr != total_debts.end() ); if( supply_itr->second != debt_itr->second ) { has_imbalanced_assets = true; elog( "Genesis for asset ${aname} is not balanced\n" " Debt is ${debt}\n" " Supply is ${supply}\n", ("debt", debt_itr->second) ("supply", supply_itr->second) ); } } ++it; } FC_ASSERT( !has_imbalanced_assets ); // Save tallied supplies for( const auto& item : total_supplies ) { const auto asset_id = item.first; const auto total_supply = item.second; modify( get( asset_id ), [ & ]( asset_object& asset ) { modify( get( asset.dynamic_asset_data_id ), [ & ]( asset_dynamic_data_object& asset_data ) { asset_data.current_supply = total_supply; } ); } ); } // Create special witness account const witness_object& wit = create<witness_object>([&](witness_object& w) {}); FC_ASSERT( wit.id == GRAPHENE_NULL_WITNESS ); remove(wit); // Create initial witnesses std::for_each(genesis_state.initial_witness_candidates.begin(), genesis_state.initial_witness_candidates.end(), [&](const genesis_state_type::initial_witness_type& witness) { witness_create_operation op; op.witness_account = get_account_id(witness.owner_name); op.block_signing_key = witness.block_signing_key; apply_operation(genesis_eval_state, op); }); // Create initial committee members std::for_each(genesis_state.initial_committee_candidates.begin(), genesis_state.initial_committee_candidates.end(), [&](const genesis_state_type::initial_committee_member_type& member) { committee_member_create_operation op; op.committee_member_account = get_account_id(member.owner_name); apply_operation(genesis_eval_state, op); }); // Create initial workers std::for_each(genesis_state.initial_worker_candidates.begin(), genesis_state.initial_worker_candidates.end(), [&](const genesis_state_type::initial_worker_type& worker) { worker_create_operation op; op.owner = get_account_id(worker.owner_name); op.work_begin_date = genesis_state.initial_timestamp; op.work_end_date = time_point_sec::maximum(); op.daily_pay = worker.daily_pay; op.name = "Genesis-Worker-" + worker.owner_name; op.initializer = vesting_balance_worker_initializer{uint16_t(0)}; apply_operation(genesis_eval_state, std::move(op)); }); // Set active witnesses modify(get_global_properties(), [&](global_property_object& p) { for( uint32_t i = 1; i <= genesis_state.initial_active_witnesses; ++i ) { p.active_witnesses.insert(i); p.witness_accounts.insert(get(witness_id_type(i)).witness_account); } }); // Enable fees modify(get_global_properties(), [&genesis_state](global_property_object& p) { p.parameters.current_fees = genesis_state.initial_parameters.current_fees; }); // Create witness scheduler create<witness_schedule_object>([&]( witness_schedule_object& wso ) { for( const witness_id_type& wid : get_global_properties().active_witnesses ) wso.current_shuffled_witnesses.push_back( wid ); }); debug_dump(); _undo_db.enable(); } FC_CAPTURE_AND_RETHROW() }
/* This is where we actually charge the guy This can be called anytime a call is in progress or at the end of a call before the session is destroyed */ static switch_status_t do_billing(switch_core_session_t *session) { /* FS vars we will use */ switch_channel_t *channel; switch_caller_profile_t *profile; /* Local vars */ nibble_data_t *nibble_data; switch_time_t ts = switch_micro_time_now(); double billamount; char date[80] = ""; char *uuid; switch_size_t retsize; switch_time_exp_t tm; const char *billrate; const char *billincrement; const char *billaccount; double nobal_amt = globals.nobal_amt; double lowbal_amt = globals.lowbal_amt; double balance; if (!session) { /* Why are we here? */ return SWITCH_STATUS_SUCCESS; } uuid = switch_core_session_get_uuid(session); /* Get channel var */ if (!(channel = switch_core_session_get_channel(session))) { return SWITCH_STATUS_SUCCESS; } /* Variables kept in FS but relevant only to this module */ billrate = switch_channel_get_variable(channel, "nibble_rate"); billincrement = switch_channel_get_variable(channel, "nibble_increment"); billaccount = switch_channel_get_variable(channel, "nibble_account"); if (!zstr(switch_channel_get_variable(channel, "nobal_amt"))) { nobal_amt = atof(switch_channel_get_variable(channel, "nobal_amt")); } if (!zstr(switch_channel_get_variable(channel, "lowbal_amt"))) { lowbal_amt = atof(switch_channel_get_variable(channel, "lowbal_amt")); } /* Return if there's no billing information on this session */ if (!billrate || !billaccount) { return SWITCH_STATUS_SUCCESS; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Attempting to bill at $%s per minute to account %s\n", billrate, billaccount); /* Get caller profile info from channel */ profile = switch_channel_get_caller_profile(channel); if (!profile || !profile->times) { /* No caller profile (why would this happen?) */ return SWITCH_STATUS_SUCCESS; } if (profile->times->answered < 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Not billing %s - call is not in answered state\n", billaccount); /* See if this person has enough money left to continue the call */ balance = get_balance(billaccount, channel); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Comparing %f to hangup balance of %f\n", balance, nobal_amt); if (balance <= nobal_amt) { /* Not enough money - reroute call to nobal location */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n", balance, nobal_amt, billaccount); transfer_call(session, globals.nobal_action); } return SWITCH_STATUS_SUCCESS; } /* Lock this session's data for this module while we tinker with it */ if (globals.mutex) { switch_mutex_lock(globals.mutex); } /* Get our nibble data var. This will be NULL if it's our first call here for this session */ nibble_data = (nibble_data_t *) switch_channel_get_private(channel, "_nibble_data_"); /* Are we in paused mode? If so, we don't do anything here - go back! */ if (nibble_data && (nibble_data->pausets > 0)) { if (globals.mutex) { switch_mutex_unlock(globals.mutex); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Received heartbeat, but we're paused - ignoring\n"); return SWITCH_STATUS_SUCCESS; } /* Have we done any billing on this channel yet? If no, set up vars for doing so */ if (!nibble_data) { nibble_data = switch_core_session_alloc(session, sizeof(*nibble_data)); memset(nibble_data, 0, sizeof(*nibble_data)); /* Setup new billing data (based on call answer time, in case this module started late with active calls) */ nibble_data->lastts = profile->times->answered; /* Set the initial answer time to match when the call was really answered */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Beginning new billing on %s\n", uuid); } switch_time_exp_lt(&tm, nibble_data->lastts); switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%d seconds passed since last bill time of %s\n", (int) ((ts - nibble_data->lastts) / 1000000), date); if ((ts - nibble_data->lastts) >= 0) { /* If billincrement is set we bill by it and not by time elapsed */ if (!(switch_strlen_zero(billincrement))) { switch_time_t chargedunits = (ts - nibble_data->lastts) / 1000000 <= atol(billincrement) ? atol(billincrement) * 1000000 : (switch_time_t)(ceil((ts - nibble_data->lastts) / (atol(billincrement) * 1000000.0))) * atol(billincrement) * 1000000; billamount = (atof(billrate) / 1000000 / 60) * chargedunits - nibble_data->bill_adjustments; /* Account for the prepaid amount */ nibble_data->lastts += chargedunits; } else { /* Convert billrate into microseconds and multiply by # of microseconds that have passed since last *successful* bill */ billamount = (atof(billrate) / 1000000 / 60) * ((ts - nibble_data->lastts)) - nibble_data->bill_adjustments; /* Update the last time we billed */ nibble_data->lastts = ts; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Billing $%f to %s (Call: %s / %f so far)\n", billamount, billaccount, uuid, nibble_data->total); /* DO ODBC BILLING HERE and reset counters if it's successful! */ if (bill_event(billamount, billaccount, channel) == SWITCH_STATUS_SUCCESS) { /* Increment total cost */ nibble_data->total += billamount; /* Reset manual billing adjustments from pausing */ nibble_data->bill_adjustments = 0; /* Update channel variable with current billing */ switch_channel_set_variable_printf(channel, "nibble_total_billed", "%f", nibble_data->total); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed to log to database!\n"); } } else { if (switch_strlen_zero(billincrement)) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Just tried to bill %s negative minutes! That should be impossible.\n", uuid); } /* Save this location */ if (channel) { switch_channel_set_private(channel, "_nibble_data_", nibble_data); /* don't verify balance and transfer to nobal if we're done with call */ if (switch_channel_get_state(channel) != CS_REPORTING && switch_channel_get_state(channel) != CS_HANGUP) { balance = get_balance(billaccount, channel); /* See if we've achieved low balance */ if (!nibble_data->lowbal_action_executed && balance <= lowbal_amt) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below low balance amount of %f! (Account %s)\n", balance, lowbal_amt, billaccount); if (exec_app(session, globals.lowbal_action) != SWITCH_STATUS_SUCCESS) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Low balance action didn't execute\n"); else nibble_data->lowbal_action_executed = 1; } /* See if this person has enough money left to continue the call */ if (balance <= nobal_amt) { /* Not enough money - reroute call to nobal location */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Balance of %f fell below allowed amount of %f! (Account %s)\n", balance, nobal_amt, billaccount); /* IMPORTANT: Billing must be paused before the transfer occurs! This prevents infinite loops, since the transfer will result */ /* in nibblebill checking the call again in the routing process for an allowed balance! */ /* If you intend to give the user the option to re-up their balance, you must clear & resume billing once the balance is updated! */ nibblebill_pause(session); transfer_call(session, globals.nobal_action); } } } /* Done changing - release lock */ if (globals.mutex) { switch_mutex_unlock(globals.mutex); } /* Go check if this call is allowed to continue */ return SWITCH_STATUS_SUCCESS; }
void database::init_genesis(const genesis_allocation& initial_allocation) { try { _undo_db.disable(); fc::ecc::private_key genesis_private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis"))); const key_object& genesis_key = create<key_object>( [&genesis_private_key](key_object& k) { k.key_data = public_key_type(genesis_private_key.get_public_key()); }); const account_statistics_object& genesis_statistics = create<account_statistics_object>( [&](account_statistics_object& b){ }); create<account_balance_object>( [](account_balance_object& b) { b.balance = GRAPHENE_INITIAL_SUPPLY; }); const account_object& genesis_account = create<account_object>( [&](account_object& n) { n.name = "genesis"; n.owner.add_authority(genesis_key.get_id(), 1); n.owner.weight_threshold = 1; n.active = n.owner; n.memo_key = genesis_key.id; n.statistics = genesis_statistics.id; }); vector<delegate_id_type> init_delegates; vector<witness_id_type> init_witnesses; flat_set<witness_id_type> init_witness_set; auto delegates_and_witnesses = std::max(GRAPHENE_MIN_WITNESS_COUNT, GRAPHENE_MIN_DELEGATE_COUNT); for( int i = 0; i < delegates_and_witnesses; ++i ) { const account_statistics_object& stats_obj = create<account_statistics_object>( [&](account_statistics_object&){ }); const account_object& delegate_account = create<account_object>( [&](account_object& a) { a.active = a.owner = genesis_account.owner; a.name = string("init") + fc::to_string(i); a.statistics = stats_obj.id; }); const delegate_object& init_delegate = create<delegate_object>( [&](delegate_object& d) { d.delegate_account = delegate_account.id; d.vote_id = i * 2; }); init_delegates.push_back(init_delegate.id); const witness_object& init_witness = create<witness_object>( [&](witness_object& d) { d.witness_account = delegate_account.id; d.vote_id = i * 2 + 1; secret_hash_type::encoder enc; fc::raw::pack( enc, genesis_private_key ); fc::raw::pack( enc, d.last_secret ); d.next_secret = secret_hash_type::hash(enc.result()); }); init_witnesses.push_back(init_witness.id); init_witness_set.insert(init_witness.id); } create<block_summary_object>( [&](block_summary_object& p) { }); const witness_schedule_object& wso = create<witness_schedule_object>( [&]( witness_schedule_object& _wso ) { memset( _wso.rng_seed.begin(), 0, _wso.rng_seed.size() ); witness_scheduler_rng rng( _wso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV ); _wso.scheduler = witness_scheduler(); _wso.scheduler._min_token_count = init_witnesses.size() / 2; _wso.scheduler.update( init_witness_set ); for( int i=0; i<init_witnesses.size(); i++ ) _wso.scheduler.produce_schedule( rng ); _wso.last_scheduling_block = 0; } ) ; assert( wso.id == witness_schedule_id_type() ); const global_property_object& properties = create<global_property_object>( [&](global_property_object& p) { p.active_delegates = init_delegates; for( const witness_id_type& wit : init_witnesses ) p.active_witnesses.insert( wit ); p.next_available_vote_id = delegates_and_witnesses * 2; p.chain_id = fc::digest(initial_allocation); }); (void)properties; create<dynamic_global_property_object>( [&](dynamic_global_property_object& p) { p.time = fc::time_point_sec( GRAPHENE_GENESIS_TIMESTAMP ); }); const asset_dynamic_data_object& dyn_asset = create<asset_dynamic_data_object>( [&]( asset_dynamic_data_object& a ) { a.current_supply = GRAPHENE_INITIAL_SUPPLY; }); const asset_object& core_asset = create<asset_object>( [&]( asset_object& a ) { a.symbol = GRAPHENE_SYMBOL; a.options.max_supply = GRAPHENE_INITIAL_SUPPLY; a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS; a.options.flags = 0; a.options.issuer_permissions = 0; a.issuer = genesis_account.id; a.options.core_exchange_rate.base.amount = 1; a.options.core_exchange_rate.base.asset_id = 0; a.options.core_exchange_rate.quote.amount = 1; a.options.core_exchange_rate.quote.asset_id = 0; a.dynamic_asset_data_id = dyn_asset.id; }); assert( asset_id_type(core_asset.id) == asset().asset_id ); assert( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) ); (void)core_asset; if( !initial_allocation.empty() ) { share_type total_allocation = 0; for( const auto& handout : initial_allocation ) total_allocation += handout.second; auto mangle_to_name = [](const fc::static_variant<public_key_type, address>& key) { string addr = string(key.which() == std::decay<decltype(key)>::type::tag<address>::value? key.get<address>() : key.get<public_key_type>()); string result = "bts"; string key_string = string(addr).substr(sizeof(GRAPHENE_ADDRESS_PREFIX)-1); for( char c : key_string ) { if( isupper(c) ) result += string("-") + char(tolower(c)); else result += c; } return result; }; fc::time_point start_time = fc::time_point::now(); for( const auto& handout : initial_allocation ) { asset amount(handout.second); amount.amount = ((fc::uint128(amount.amount.value) * GRAPHENE_INITIAL_SUPPLY)/total_allocation.value).to_uint64(); if( amount.amount == 0 ) { wlog("Skipping zero allocation to ${k}", ("k", handout.first)); continue; } signed_transaction trx; trx.operations.emplace_back(key_create_operation({asset(), genesis_account.id, handout.first})); relative_key_id_type key_id(0); authority account_authority(1, key_id, 1); account_create_operation cop; cop.name = mangle_to_name(handout.first); cop.registrar = account_id_type(1); cop.active = account_authority; cop.owner = account_authority; cop.memo_key = key_id; trx.operations.push_back(cop); trx.validate(); auto ptrx = apply_transaction(trx, ~0); trx = signed_transaction(); account_id_type account_id(ptrx.operation_results.back().get<object_id_type>()); trx.operations.emplace_back(transfer_operation({ asset(), genesis_account.id, account_id, amount, memo_data()//vector<char>() })); trx.validate(); apply_transaction(trx, ~0); } asset leftovers = get_balance(account_id_type(), asset_id_type()); if( leftovers.amount > 0 ) { modify(*get_index_type<account_balance_index>().indices().get<by_balance>().find(boost::make_tuple(account_id_type(), asset_id_type())), [](account_balance_object& b) { b.adjust_balance(-b.get_balance()); }); modify(core_asset.dynamic_asset_data_id(*this), [&leftovers](asset_dynamic_data_object& d) { d.accumulated_fees += leftovers.amount; }); } fc::microseconds duration = fc::time_point::now() - start_time; ilog("Finished allocating to ${n} accounts in ${t} milliseconds.", ("n", initial_allocation.size())("t", duration.count() / 1000)); } _undo_db.enable(); } FC_LOG_AND_RETHROW() }
int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) { struct cx25840_state *state = i2c_get_clientdata(client); struct v4l2_control *ctrl = arg; int retval; switch (cmd) { case VIDIOC_INT_AUDIO_CLOCK_FREQ: if (!state->is_cx25836) cx25840_and_or(client, 0x810, ~0x1, 1); if (state->aud_input != CX25840_AUDIO_SERIAL) { cx25840_and_or(client, 0x803, ~0x10, 0); cx25840_write(client, 0x8d3, 0x1f); } retval = set_audclk_freq(client, *(u32 *)arg); if (state->aud_input != CX25840_AUDIO_SERIAL) { cx25840_and_or(client, 0x803, ~0x10, 0x10); } if (!state->is_cx25836) cx25840_and_or(client, 0x810, ~0x1, 0); return retval; case VIDIOC_G_CTRL: switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: ctrl->value = get_volume(client); break; case V4L2_CID_AUDIO_BASS: ctrl->value = get_bass(client); break; case V4L2_CID_AUDIO_TREBLE: ctrl->value = get_treble(client); break; case V4L2_CID_AUDIO_BALANCE: ctrl->value = get_balance(client); break; case V4L2_CID_AUDIO_MUTE: ctrl->value = get_mute(client); break; default: return -EINVAL; } break; case VIDIOC_S_CTRL: switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: set_volume(client, ctrl->value); break; case V4L2_CID_AUDIO_BASS: set_bass(client, ctrl->value); break; case V4L2_CID_AUDIO_TREBLE: set_treble(client, ctrl->value); break; case V4L2_CID_AUDIO_BALANCE: set_balance(client, ctrl->value); break; case V4L2_CID_AUDIO_MUTE: set_mute(client, ctrl->value); break; default: return -EINVAL; } break; default: return -EINVAL; } return 0; }
/* Deletion might require up to log(n) rotations */ void avltree_remove(struct avltree_node *node, struct avltree *tree) { struct avltree_node *parent = get_parent(node); struct avltree_node *left = node->left; struct avltree_node *right = node->right; struct avltree_node *next; int is_left = is_left; if (node == tree->first) tree->first = avltree_next(node); if (node == tree->last) tree->last = avltree_prev(node); if (!left) next = right; else if (!right) next = left; else next = get_first(right); if (parent) { is_left = parent->left == node; set_child(next, parent, is_left); } else tree->root = next; if (left && right) { set_balance(get_balance(node), next); next->left = left; set_parent(next, left); if (next != right) { parent = get_parent(next); set_parent(get_parent(node), next); node = next->right; parent->left = node; is_left = 1; next->right = right; set_parent(next, right); } else { set_parent(parent, next); parent = next; node = parent->right; is_left = 0; } assert(parent != NULL); } else node = next; if (node) set_parent(parent, node); /* * At this point, 'parent' can only be null, if 'node' is the * tree's root and has at most one child. * * case 1: the subtree is now balanced but its height has * decreased. * * case 2: the subtree is mostly balanced and its height is * unchanged. * * case 3: the subtree is unbalanced and its height may have * been changed during the rebalancing process, see below. * * case 3.1: after a left rotation, the subtree becomes mostly * balanced and its height is unchanged. * * case 3.2: after a left rotation, the subtree becomes * balanced but its height has decreased. * * case 3.3: after a left and a right rotation, the subtree * becomes balanced or mostly balanced but its height has * decreased for all cases. */ while (parent) { int balance; node = parent; parent = get_parent(parent); if (is_left) { is_left = parent && parent->left == node; balance = inc_balance(node); if (balance == 0) /* case 1 */ continue; if (balance == 1) /* case 2 */ return; right = node->right; /* case 3 */ switch (get_balance(right)) { case 0: /* case 3.1 */ set_balance( 1, node); set_balance(-1, right); rotate_left(node, tree); return; case 1: /* case 3.2 */ set_balance(0, node); set_balance(0, right); break; case -1: /* case 3.3 */ switch (get_balance(right->left)) { case 1: set_balance(-1, node); set_balance( 0, right); break; case 0: set_balance(0, node); set_balance(0, right); break; case -1: set_balance(0, node); set_balance(1, right); break; } set_balance(0, right->left); rotate_right(right, tree); } rotate_left(node, tree); } else { is_left = parent && parent->left == node; balance = dec_balance(node); if (balance == 0) continue; if (balance == -1) return; left = node->left; switch (get_balance(left)) { case 0: set_balance(-1, node); set_balance(1, left); rotate_right(node, tree); return; case -1: set_balance(0, node); set_balance(0, left); break; case 1: switch (get_balance(left->right)) { case 1: set_balance(0, node); set_balance(-1, left); break; case 0: set_balance(0, node); set_balance(0, left); break; case -1: set_balance(1, node); set_balance(0, left); break; } set_balance(0, left->right); rotate_left(left, tree); } rotate_right(node, tree); } } tree->height--; }
int main(int argc, char **argv) { // MPI variables int my_rank, NP; int source, dest; int tag; int length; char name[MPI_MAX_PROCESSOR_NAME + 1]; char message[MESSAGE_SIZE]; MPI_Status status; MPI_Init(&argc, &argv); // argc and argv passed by address to all MPI processes MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); // returns taskID = rank of calling process MPI_Comm_size(MPI_COMM_WORLD, &NP); // returns total no of MPI processes available if (my_rank == MASTER) { // Head Office (master) // Print startup info printf("HO: started\n"); MPI_Get_processor_name(name, &length); printf("HO: name = %s, my_rank = %d\n", name, my_rank); // Socket stuff int socket_descriptor, client_sock, c, *new_sock; struct sockaddr_in server, client; void *thread_status = 0; // Create socket socket_descriptor = socket(AF_INET, SOCK_STREAM, 0); if (socket_descriptor == -1) { printf("HO: Could not create socket"); } puts("HO: Socket created"); // Prepare sockaddr_in structure server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons( PORT_NUMBER ); // Bind if ( bind(socket_descriptor, (struct sockaddr *)&server, sizeof(server)) < 0 ) { perror("HO: Socket bind failed. Error"); return 1; } puts("HO: Socket bind done"); // Listen for new requests listen(socket_descriptor, MAX_CONN_REQ_IN_QUEUE); puts("HO: Waiting for incoming connections..."); // Accept incoming connection c = sizeof(struct sockaddr_in); while ( (client_sock = accept(socket_descriptor, (struct sockaddr *)&client, (socklen_t*)&c)) ) { puts("HO: Connection accepted!"); pthread_t sniffer_thread; new_sock = malloc(1); *new_sock = client_sock; // Start a new thread with connection_handler if ( pthread_create(&sniffer_thread, NULL, connection_handler, (void*) new_sock) < 0) { perror("HO: Could not create thread"); return 1; } // Join the thread, so that MASTER doesn't terminate before the thread pthread_join(sniffer_thread, &thread_status); if (thread_status == 42) { printf("HO: Killing signal sent, shutdown system!\n"); // What to do here? // MPI_Abort? // MPI_Finalize? // break should get us down to MPI_Finalize and return 0, but doesn't work.. break; } puts("HO: Socket handler thread exited"); } if (client_sock < 0) { perror("HO: Connection accept failed"); return 1; } // for (source = 1; source < NP; source++) { // MPI_Recv(message, MESSAGE_SIZE, MPI_CHAR, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &status); // printf("HO received: %s\n", message); // } } else { // Branch Office (slave) // Branch variables pid_t pid = 0; int account_status = 0, wpid; // sqlite3 variables sqlite3 *db; int rc; char query[QUERY_SIZE]; MPI_Get_processor_name(name, &length); printf("BO %d: starting on name = %s\n", my_rank, name); // Get the number of accounts to start from DB rc = sqlite3_open_v2("accounts.db", &db, SQLITE_OPEN_READONLY, NULL); if (rc) { fprintf(stderr, "BO %d: Can't open database: %s\n", my_rank, sqlite3_errmsg(db)); sqlite3_close(db); return(1); } // Find all account ids for this branch sqlite3_stmt *statement; sprintf(query, "SELECT id, balance FROM accounts WHERE branch = %d", my_rank); sqlite3_prepare_v2(db, query, strlen(query) + 1, &statement, NULL); // For each account, start a new process while (1) { int row = sqlite3_step(statement); if (row == SQLITE_ROW) { int account_id; account_id = sqlite3_column_int(statement, 0); balance = sqlite3_column_double(statement, 1); pid = fork(); if (pid < 0 ) { printf("BO %d: pid < 0, fork failed!\n", my_rank); continue; } if (pid == 0) { // Inside bank account process printf("BO %d: account_id = %d, balance = %f\n", my_rank, account_id, balance); // RPC // printf("BO %d_%d: before execl", my_rank, account_id); // execl("rpc/accounts/account_server", "account_server", (char*)NULL); // printf("BO %d_%d: after execl", my_rank, account_id); // return 0; } else { printf("BO %d: created pid = %d\n", my_rank, pid); } } else if (row == SQLITE_DONE) { printf("BO %d: Done creating account processes.\n", my_rank); break; } else { fprintf(stderr, "BO : sqlite row failed..\n"); return 1; } } sqlite3_finalize(statement); sqlite3_close(db); // Let Head Office know Branch up and is running // sprintf(message, "Branch %d successfully started on processor %s", my_rank, name); // MPI_Send(message, strlen(message) + 1, MPI_CHAR, MASTER, tag, MPI_COMM_WORLD); // Wait for messages from Head Office for eternity while (1) { printf("BO %d waiting for MPI_Recv again\n", my_rank); MPI_Recv(message, MESSAGE_SIZE, MPI_CHAR, MASTER, MPI_ANY_TAG, MPI_COMM_WORLD, &status); printf("BO %d MPI_Recv from master with tag %d: %s\n", my_rank, status.MPI_TAG, message); char *token, *params[3]; int account_id, to_account_id; double amount, result; int j = 0; // Separate message parameters token = strtok(message, separator); while (token != NULL) { params[j++] = token; token = strtok(NULL, separator); } account_id = atoi(params[0]); amount = atof(params[1]); to_account_id = atoi(params[2]); // Query process for account... // RPC not working, use DB instead // Operation sent as TAG, get it from status switch (status.MPI_TAG) { case GET_BALANCE_OPERATION: result = get_balance(account_id); printf("%f\n", result); if (result < 0) { sprintf(message, "Couldn't get balance...\n"); } else { sprintf(message, "Balance is £%.2f\n", result); } break; case DEPOSIT_OPERATION: result = deposit(account_id, amount); if (result < 0) { sprintf(message, "Couldn't make deposit...\n"); } else { sprintf(message, "New balance is £%.2f\n", result); } break; case WITHDRAW_OPERATION: result = withdraw(account_id, amount); if (result < 0) { sprintf(message, "Couldn't make withdraw...\n"); } else { sprintf(message, "New balance is £%.2f\n", result); } break; case TRANSFER_OPERATION: sprintf(message, transfer(account_id, to_account_id, amount)); break; } MPI_Send(message, MESSAGE_SIZE, MPI_CHAR, MASTER, status.MPI_TAG, MPI_COMM_WORLD); printf("BO %d sent: %s\n", my_rank, message); } printf("BO %d: shutting down\n", my_rank); // RPC // wait for all children to exit // while ( (wpid = wait(&account_status) ) > 0) {} } MPI_Finalize(); return 0; }
int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg) { struct cx18_av_state *state = &cx->av_state; struct v4l2_control *ctrl = arg; int retval; switch (cmd) { case VIDIOC_INT_AUDIO_CLOCK_FREQ: if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { cx18_av_and_or(cx, 0x803, ~0x10, 0); cx18_av_write(cx, 0x8d3, 0x1f); } cx18_av_and_or(cx, 0x810, ~0x1, 1); retval = set_audclk_freq(cx, *(u32 *)arg); cx18_av_and_or(cx, 0x810, ~0x1, 0); if (state->aud_input > CX18_AV_AUDIO_SERIAL2) cx18_av_and_or(cx, 0x803, ~0x10, 0x10); return retval; case VIDIOC_G_CTRL: switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: ctrl->value = get_volume(cx); break; case V4L2_CID_AUDIO_BASS: ctrl->value = get_bass(cx); break; case V4L2_CID_AUDIO_TREBLE: ctrl->value = get_treble(cx); break; case V4L2_CID_AUDIO_BALANCE: ctrl->value = get_balance(cx); break; case V4L2_CID_AUDIO_MUTE: ctrl->value = get_mute(cx); break; default: return -EINVAL; } break; case VIDIOC_S_CTRL: switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: set_volume(cx, ctrl->value); break; case V4L2_CID_AUDIO_BASS: set_bass(cx, ctrl->value); break; case V4L2_CID_AUDIO_TREBLE: set_treble(cx, ctrl->value); break; case V4L2_CID_AUDIO_BALANCE: set_balance(cx, ctrl->value); break; case V4L2_CID_AUDIO_MUTE: set_mute(cx, ctrl->value); break; default: return -EINVAL; } break; default: return -EINVAL; } return 0; }
int fwAvlInsert(uint32_t key, void* data, struct FwAvlTree* tree) { int is_left; struct FwAvlNode* parent; struct FwAvlNode* right; struct FwAvlNode* left; struct FwAvlNode* unbalanced; struct FwAvlNode* node; if(do_lookup(key, tree, &parent, &unbalanced, &is_left) != NULL) return 1; if(!(node = new_node(key, data))) return -1; tree->count++; if(parent == NULL) { tree->root = node; tree->first = node; tree->last = node; return 0; } if(is_left != 0) { if(parent == tree->first) tree->first = node; } else { if(parent == tree->last) tree->last = node; } set_parent(parent, node); set_child(node, parent, is_left); while(1) { if(parent->left == node) dec_balance(parent); else inc_balance(parent); if(parent == unbalanced) break; node = parent; parent = get_parent(node); } switch(get_balance(unbalanced)) { case 1: case -1: tree->height++; break; case 0: break; case 2: right = unbalanced->right; if(get_balance(right) == 1) { set_balance(0, unbalanced); set_balance(0, right); } else { switch(get_balance(right->left)) { case 1: set_balance(-1, unbalanced); set_balance(0, right); break; case 0: set_balance(0, unbalanced); set_balance(0, right); break; case -1: set_balance(0, unbalanced); set_balance(1, right); break; } set_balance(0, right->left); rotate_right(right, tree); } rotate_left(unbalanced, tree); break; case -2: left = unbalanced->left; if(get_balance(left) == -1) { set_balance(0, unbalanced); set_balance(0, left); } else { switch(get_balance(left->right)) { case 1: set_balance(0, unbalanced); set_balance(-1, left); break; case 0: set_balance(0, unbalanced); set_balance(0, left); break; case -1: set_balance(1, unbalanced); set_balance(0, left); break; } set_balance(0, left->right); rotate_left(left, tree); } rotate_right(unbalanced, tree); break; } return 0; }
/* Insertion never needs more than 2 rotations */ struct avltree_node *avltree_insert(struct avltree_node *node, struct avltree *tree) { struct avltree_node *key, *parent, *unbalanced; int is_left; key = do_lookup(node, tree, &parent, &unbalanced, &is_left); if (key) return key; INIT_NODE(node); if (!parent) { tree->root = node; tree->first = tree->last = node; tree->height++; return NULL; } if (is_left) { if (parent == tree->first) tree->first = node; } else { if (parent == tree->last) tree->last = node; } set_parent(parent, node); set_child(node, parent, is_left); for (;;) { if (parent->left == node) dec_balance(parent); else inc_balance(parent); if (parent == unbalanced) break; node = parent; parent = get_parent(parent); } switch (get_balance(unbalanced)) { case 1: case -1: tree->height++; /* fall through */ case 0: break; case 2: { struct avltree_node *right = unbalanced->right; if (get_balance(right) == 1) { set_balance(0, unbalanced); set_balance(0, right); } else { switch (get_balance(right->left)) { case 1: set_balance(-1, unbalanced); set_balance( 0, right); break; case 0: set_balance(0, unbalanced); set_balance(0, right); break; case -1: set_balance(0, unbalanced); set_balance(1, right); break; } set_balance(0, right->left); rotate_right(right, tree); } rotate_left(unbalanced, tree); break; } case -2: { struct avltree_node *left = unbalanced->left; if (get_balance(left) == -1) { set_balance(0, unbalanced); set_balance(0, left); } else { switch (get_balance(left->right)) { case 1: set_balance( 0, unbalanced); set_balance(-1, left); break; case 0: set_balance(0, unbalanced); set_balance(0, left); break; case -1: set_balance(1, unbalanced); set_balance(0, left); break; } set_balance(0, left->right); rotate_left(left, tree); } rotate_right(unbalanced, tree); break; } } return NULL; }