What is the meaning of the input variables when registering a new group? - asch

The (smart) contract function to register a new group looks as follows:
async registerGroup(name, members, min, max, m, updateInterval) {
...
}
What is the meaning of min,max, m and updateInterval in the above?

name is the name of the group
members is the list of member added to the group at initialization. The list contains probably the public keys.
min and max set the minimum and maximum number of members, min should be >= 3.
m that is the minimum vote weight a request transaction must get.
m sets the total weight of votes required to activate a group transaction the group, the check can be found in the asch/src/contract/group.js file in the activate() function:
const group = await app.sdb.load('Group', account.name)
if (totalWeight < group.m) return 'Vote weight not enough'
Notice that m also can be set when adding a new group member with group.addMember:
async addMember(address, weight, m) {
...
if (m) {
const group = await app.sdb.load('Group', this.sender.name)
if (!group) return 'Group not found'
group.m = m
app.sdb.update('Group', { m }, { name: this.sender.name })
}
...
}
The updateInterval is unclear till now. Possible related to the time a group member should lock it's XAS.

Related

How do I add the first and last value in a map reduce RavenDB index

When having a map reduce I would like to also include the first value of user current balance and last value of user balnce ordered by the date
from r in results
group r by new {r.Date, r.UserId} into g
select new
{
Date = g.Key.Date,
UserId = g.Key.UserId,
Count = g.Sum(x => x.Count),
** StartBalance = g.First(x=>x.Balance),
EndBalance = g.Last(x => x.Balance)**
}
I am expecting to get the first balance of the user when he just logged in to the game and also the last balance of the same player of the user at the end of the day.
Is this something possible?
This should work:
g.OrderyBy(x => x.Date).Select(x => x.Balance).FirstOrDefault()

DynamoDB - Get all items which overlap a search time interval

My application manages bookings of a user. These bookings are composed by a start_date and end_date, and their current partition in dynamodb is the following:
PK SK DATA
USER#1#BOOKINGS BOOKING#1 {s: '20190601', e: '20190801'}
[GOAL] I would query all reservations which overlap a search time interval as the following:
I tried to find a solution for this issue but I found only a way to query all items inside a search time interval, which solves only this problem:
I decided to make an implementation of it to try to make some change to solve my problem but I didn't found a solution, following you can find my implementation of "query inside interval" (this is not a dynamodb implementation, but I will replace isBetween function with BETWEEN operand):
import { zip } from 'lodash';
const bookings = [
{ s: '20190601', e: '20190801', i: '' },
{ s: '20180702', e: '20190102', i: '' }
];
const search_start = '20190602'.split('');
const search_end = '20190630'.split('');
// s:20190601 e:20190801 -> i:2200119900680011
for (const b of bookings) {
b['i'] = zip(b.s.split(''), b.e.split(''))
.reduce((p, c) => p + c.join(''), '');
}
// (start_search: 20190502, end_search: 20190905) => 22001199005
const start_clause: string[] = [];
for (let i = 0; i < search_start.length; i += 1) {
if (search_start[i] === search_end[i]) {
start_clause.push(search_start[i] + search_end[i]);
} else {
start_clause.push(search_start[i]);
break;
}
}
const s_index = start_clause.join('');
// (end_search: 20190905, start_search: 20190502) => 22001199009
const end_clause: string[] = [];
for (let i = 0; i < search_end.length; i += 1) {
if (search_end[i] === search_start[i]) {
end_clause.push(search_end[i] + search_start[i]);
} else {
end_clause.push(search_end[i]);
break;
}
}
const e_index = (parseInt(end_clause.join('')) + 1).toString();
const isBetween = (s: string, e: string, v: string) => {
const sorted = [s,e,v].sort();
console.info(`sorted: ${sorted}`)
return sorted[1] === v;
}
const filtered_bookings = bookings
.filter(b => isBetween(s_index, e_index, b.i));
console.info(`filtered_bookings: ${JSON.stringify(filtered_bookings)}`)
There’s not going to be a beautiful and simple yet generic answer.
Probably the best approach is to pre-define your time period size (days, hours, minutes, seconds, whatever) and use the value of that as the PK so for each day (or hour or whatever) you have in that item collection a list of the items touching that day with the sort key of the start time (so you can do the inequality there) and you can use a filter on the end time attribute.
If your chosen time period is days and you need to query across a week then you’ll issue seven queries. So pick a time unit that’s around the same size as your selected time periods.
Remember you need to put all items touching that day (or whatever) into the day collection. If an item spans a week it needs to be inserted 7 times.
Disclaimer: This is a very use-case-specific and non-general approach I took when trying to solve the same problem; it picks up on #hunterhacker 's approach.
Observations from my use case:
The data I'm dealing with is financial/stock data, which spans back roughly 50 years in the past up to 150 years into the future.
I have many thousands of items per year, and I would like to avoid pulling in all 200 years of information
The vast majority of the items I want to query spans a time that fits within a year (ie. most items don't go from 30-Dec-2001 to 02-Jan-2002, but rather from 05-Mar-2005 to 10-Mar-2005)
Based on the above, I decided to add an LSI and save the relevant year for every item whose start-to-end time is within a single year. The items that straddle a year (or more) I set that LSI with 0.
The querying looks like:
if query_straddles_year:
# This doesn't happen often in my use case
result = query_all_and_filter_after()
else:
# Most cases end up here (looking for a single day, for instance)
year_constrained_result = query_using_lsi_for_that_year()
result_on_straddling_bins = query_using_lsi_marked_with_0() # <-- this is to get any of the indexes that do straddle a year
filter_and_combine(year_constrained_result, result_on_straddling_bins)

Run SUM(*) on Supabase

I'm starting with Supabase and would like to understand how I can pass the SUM() aggregator in a SELECT.
I noticed that for COUNT we use:
const { data, error, range, count } = supabase
.from('table')
.select('*', { count: 'exact' })
Is there anything similar to SUM that I haven't noticed?
My query is this:
select
"GE_PRODUCTS",
sum("GE_QUANTITY") as Quantity,
sum("GE_SALEVALUE") as Revenue
from "GE_SELLS"
where "GE_ENTERPRISE" = 'G.E.'
and "DELETED" <> '*'
group by "GE_PRODUCTS"
order by Revenue desc
limit 3;
Your best bet is to put this into a PostgreSQL function and call it from Supabase using .rpc():
CREATE OR REPLACE FUNCTION get_my_sums()
RETURNS TABLE (
"GE_PRODUCTS" TEXT,
Quantity NUMBER,
Revenue NUMBER
) AS $$
DECLARE
var_r record;
BEGIN
RETURN QUERY
select
"GE_PRODUCTS",
sum("GE_QUANTITY") as Quantity,
sum("GE_SALEVALUE") as Revenue
from "GE_SELLS"
where "GE_ENTERPRISE" = 'G.E.'
and "DELETED" <> '*'
group by "GE_PRODUCTS"
order by Revenue desc
limit 3;
END; $$
LANGUAGE 'plpgsql';

Group by, sum then sort a list of transaction objects java

I have a list of transactions by day, the transaction contains the following attributes:
Transaction(int transactionID,
DateTime transactionDate,
String shopId,
int productReference,
int quantity,
float price);
Having a list List<Transaction>, I want to extract top 100 selled products by shop.
So I need to group transactions by shopId then by productReference, then summing quantities than sorting from most selled to least.
Thanks you for your Help
private static Collector<Transaction, ?, List<Transaction>> limit(int limit) {
return Collector.of(
ArrayList::new,
(list, transaction) -> { if (list.size() < limit) list.add(transaction); },
(list1, list2) -> {
list1.addAll(list2.subList(0, Math.min(list2.size(), Math.max(0, limit - list1.size()))));
return list1;
}
);
}
public static void main(String[] args) {
Map<String, List<Transaction>> groupedMap = listOfTransactions
.stream()
.sorted((t1, t2) -> Integer.compare(t2.getQuantity(), t1.getQuantity()))
.collect(
Collectors.groupingBy(
Transaction::getShopId,
limit(100)
)
);
}
As a result you'll get a map with shopId as a key, and lists of transactions sorted by quantity as a value.
Is it expected behavior?
I'd suggest using of additional Product type, with overridden equals() and hasCode() which will consist only of shopId and productReference . New type will serve as an output, which will make all the transformation job more obvious. Consider my version, with Lombok lib usage:
import lombok.*;
#Data
#RequiredArgsConstructor(staticName = "of")
#ToString
public class Product {
final String shopId;
final int productReference;
}
and the function code itself:
List<Product> products = transactions.stream()
// grouping transactions by the same product
.collect(Collectors.groupingBy(transaction -> Product.of(
transaction.getShopId(),
transaction.getProductReference())))
.entrySet().stream()
// summing all price * quantity occurrences to find top sellings
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().stream()
.mapToDouble(p -> p.getQuantity() * p.getPrice())
.sum()))
.entrySet().stream()
// sorting by the most expensive ones at the top,
// limiting to 10 and collecting to the list
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.map(Map.Entry::getKey)
.limit(10)
.collect(Collectors.toList());

How to find sum of a field in nested lists with a where condition?

I am having two lists and I need to find sum of nested list and there should be filter on the first list.
Ex:
Class Customer{
string Name
List<Order> Orders
string State
}
Class Order{
int OrderID
int OrderTotal
int ItemCode
}
I need to find sum of Orders in a particular state, I am looking for a lambda expression for this.
Below is the lambda expression with can be used to get the sum of the orderTotal with the filter on state.
Customer customer = new Customer();
Now add some data to your customer object and Order object.
customer.Where(cust => cust.State.Equals("Alaska")).Sum(order => order.OrderTotal);