-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'dev' into transfer-opt
- Loading branch information
Showing
19 changed files
with
482 additions
and
204 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
src/main/java/ldbc/finbench/datagen/generation/events/AccountActivitiesEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package ldbc.finbench.datagen.generation.events; | ||
|
||
import java.io.Serializable; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Random; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.concurrent.atomic.AtomicLong; | ||
import ldbc.finbench.datagen.entities.edges.Transfer; | ||
import ldbc.finbench.datagen.entities.edges.Withdraw; | ||
import ldbc.finbench.datagen.entities.nodes.Account; | ||
import ldbc.finbench.datagen.generation.DatagenParams; | ||
import ldbc.finbench.datagen.generation.distribution.DegreeDistribution; | ||
import ldbc.finbench.datagen.util.RandomGeneratorFarm; | ||
|
||
public class AccountActivitiesEvent implements Serializable { | ||
private final RandomGeneratorFarm randomFarm; | ||
private final DegreeDistribution multiplicityDist; | ||
private final double partRatio; | ||
private final Random randIndex; | ||
private final Map<String, AtomicLong> multiplicityMap; | ||
|
||
public AccountActivitiesEvent() { | ||
this.partRatio = 1.0 / DatagenParams.transferShuffleTimes; | ||
randomFarm = new RandomGeneratorFarm(); | ||
multiplicityDist = DatagenParams.getTransferMultiplicityDistribution(); | ||
multiplicityDist.initialize(); | ||
randIndex = new Random(DatagenParams.defaultSeed); | ||
multiplicityMap = new ConcurrentHashMap<>(); | ||
} | ||
|
||
private void resetState(int seed) { | ||
randomFarm.resetRandomGenerators(seed); | ||
multiplicityDist.reset(seed); | ||
randIndex.setSeed(seed); | ||
} | ||
|
||
private LinkedList<Integer> getIndexList(int size) { | ||
LinkedList<Integer> indexList = new LinkedList<>(); | ||
for (int i = 0; i < size; i++) { | ||
indexList.add(i); | ||
} | ||
return indexList; | ||
} | ||
|
||
// Generation to parts will mess up the average degree(make it bigger than expected) caused by ceiling operations. | ||
// Also, it will mess up the long tail range of powerlaw distribution of degrees caused by 1 rounded to 2. | ||
// See the plot drawn by check_transfer.py for more details. | ||
public List<Account> accountActivities(List<Account> accounts, List<Account> cards, int blockId) { | ||
resetState(blockId); | ||
Random pickAccountForWithdrawal = randomFarm.get(RandomGeneratorFarm.Aspect.ACCOUNT_WHETHER_WITHDRAW); | ||
|
||
|
||
// scale to percentage | ||
for (Account account : accounts) { | ||
account.setMaxOutDegree((long) Math.ceil(account.getRawMaxOutDegree() * partRatio)); | ||
account.setMaxInDegree((long) Math.ceil(account.getRawMaxInDegree() * partRatio)); | ||
} | ||
LinkedList<Integer> availableToAccountIds = getIndexList(accounts.size()); // available transferTo accountIds | ||
for (int i = 0; i < accounts.size(); i++) { | ||
Account from = accounts.get(i); | ||
// account transfer to other accounts | ||
while (from.getAvailableOutDegree() != 0) { | ||
int skippedCount = 0; | ||
for (int j = 0; j < availableToAccountIds.size(); j++) { | ||
int toIndex = availableToAccountIds.get(j); | ||
Account to = accounts.get(toIndex); | ||
if (toIndex == i || cannotTransfer(from, to)) { | ||
skippedCount++; | ||
continue; | ||
} | ||
long numTransfers = Math.min(multiplicityDist.nextDegree(), | ||
Math.min(from.getAvailableOutDegree(), to.getAvailableInDegree())); | ||
for (int mindex = 0; mindex < numTransfers; mindex++) { | ||
Transfer.createTransferNew(randomFarm, from, to, mindex); | ||
} | ||
if (to.getAvailableInDegree() == 0) { | ||
availableToAccountIds.remove(j); | ||
j--; | ||
} | ||
if (from.getAvailableOutDegree() == 0) { | ||
break; | ||
} | ||
} | ||
if (skippedCount == availableToAccountIds.size()) { | ||
System.out.println("[Transfer] All accounts skipped for " + from.getAccountId()); | ||
break; // end loop if all accounts are skipped | ||
} | ||
} | ||
// account withdraw to cards | ||
if (pickAccountForWithdrawal.nextDouble() < DatagenParams.accountWithdrawFraction) { | ||
for (int count = 0; count < DatagenParams.maxWithdrawals; count++) { | ||
Account to = cards.get(randIndex.nextInt(cards.size())); | ||
if (cannotWithdraw(from, to)) { | ||
continue; | ||
} | ||
Withdraw.createWithdrawNew(randomFarm, from, to, getMultiplicityIdAndInc(from, to)); | ||
} | ||
} | ||
|
||
} | ||
return accounts; | ||
} | ||
|
||
// Transfer to self is not allowed | ||
private boolean cannotTransfer(Account from, Account to) { | ||
return from.getDeletionDate() < to.getCreationDate() + DatagenParams.activityDelta | ||
|| from.getCreationDate() + DatagenParams.activityDelta > to.getDeletionDate() | ||
|| from.equals(to) || from.getAvailableOutDegree() == 0 || to.getAvailableInDegree() == 0; | ||
} | ||
|
||
private boolean cannotWithdraw(Account from, Account to) { | ||
return from.getDeletionDate() < to.getCreationDate() + DatagenParams.activityDelta | ||
|| from.getCreationDate() + DatagenParams.activityDelta > to.getDeletionDate() | ||
|| from.equals(to); | ||
} | ||
|
||
private long getMultiplicityIdAndInc(Account from, Account to) { | ||
String key = from.getAccountId() + "-" + to.getAccountId(); | ||
AtomicLong atomicInt = multiplicityMap.computeIfAbsent(key, k -> new AtomicLong()); | ||
return atomicInt.getAndIncrement(); | ||
} | ||
|
||
} |
76 changes: 76 additions & 0 deletions
76
src/main/java/ldbc/finbench/datagen/generation/events/CompanyActivitiesEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package ldbc.finbench.datagen.generation.events; | ||
|
||
import java.io.Serializable; | ||
import java.util.List; | ||
import java.util.Random; | ||
import ldbc.finbench.datagen.entities.edges.CompanyApplyLoan; | ||
import ldbc.finbench.datagen.entities.edges.CompanyGuaranteeCompany; | ||
import ldbc.finbench.datagen.entities.edges.CompanyOwnAccount; | ||
import ldbc.finbench.datagen.entities.nodes.Account; | ||
import ldbc.finbench.datagen.entities.nodes.Company; | ||
import ldbc.finbench.datagen.entities.nodes.Loan; | ||
import ldbc.finbench.datagen.generation.DatagenParams; | ||
import ldbc.finbench.datagen.generation.dictionary.Dictionaries; | ||
import ldbc.finbench.datagen.generation.generators.AccountGenerator; | ||
import ldbc.finbench.datagen.generation.generators.LoanGenerator; | ||
import ldbc.finbench.datagen.util.RandomGeneratorFarm; | ||
|
||
public class CompanyActivitiesEvent implements Serializable { | ||
private final RandomGeneratorFarm randomFarm; | ||
private final Random randIndex; | ||
|
||
public CompanyActivitiesEvent() { | ||
randomFarm = new RandomGeneratorFarm(); | ||
randIndex = new Random(DatagenParams.defaultSeed); | ||
} | ||
|
||
private void resetState(int seed) { | ||
randomFarm.resetRandomGenerators(seed); | ||
randIndex.setSeed(seed); | ||
} | ||
|
||
public List<Company> companyActivities(List<Company> companies, AccountGenerator accountGenerator, | ||
LoanGenerator loanGenerator, int blockId) { | ||
resetState(blockId); | ||
accountGenerator.resetState(blockId); | ||
|
||
Random numAccRand = randomFarm.get(RandomGeneratorFarm.Aspect.NUM_ACCOUNTS_PER_COMPANY); | ||
|
||
Random pickCompanyGuaRand = randomFarm.get(RandomGeneratorFarm.Aspect.PICK_COMPANY_GUARANTEE); | ||
Random numGuaranteesRand = randomFarm.get(RandomGeneratorFarm.Aspect.NUM_GUARANTEES_PER_COMPANY); | ||
|
||
Random pickCompanyLoanRand = randomFarm.get(RandomGeneratorFarm.Aspect.PICK_COMPANY_FOR_LOAN); | ||
Random numLoansRand = randomFarm.get(RandomGeneratorFarm.Aspect.NUM_LOANS_PER_COMPANY); | ||
Random dateRand = randomFarm.get(RandomGeneratorFarm.Aspect.COMPANY_APPLY_LOAN_DATE); | ||
|
||
for (Company from : companies) { | ||
// register accounts | ||
int numAccounts = numAccRand.nextInt(DatagenParams.maxAccountsPerOwner); | ||
for (int i = 0; i < Math.max(1, numAccounts); i++) { | ||
Account account = accountGenerator.generateAccount(from.getCreationDate(), "company", blockId); | ||
CompanyOwnAccount.createCompanyOwnAccount(randomFarm, from, account, account.getCreationDate()); | ||
} | ||
// guarantee other companies | ||
if (pickCompanyGuaRand.nextDouble() < DatagenParams.companyGuaranteeFraction) { | ||
int numGuarantees = numGuaranteesRand.nextInt(DatagenParams.maxTargetsToGuarantee); | ||
for (int i = 0; i < Math.max(1, numGuarantees); i++) { | ||
Company to = companies.get(randIndex.nextInt(companies.size())); | ||
if (from.canGuarantee(to)) { | ||
CompanyGuaranteeCompany.createCompanyGuaranteeCompany(randomFarm, from, to); | ||
} | ||
} | ||
} | ||
// apply loans | ||
if (pickCompanyLoanRand.nextDouble() < DatagenParams.companyLoanFraction) { | ||
int numLoans = numLoansRand.nextInt(DatagenParams.maxLoans); | ||
for (int i = 0; i < Math.max(1, numLoans); i++) { | ||
long applyDate = Dictionaries.dates.randomCompanyToLoanDate(dateRand, from); | ||
Loan to = loanGenerator.generateLoan(applyDate, "company", blockId); | ||
CompanyApplyLoan.createCompanyApplyLoan(randomFarm, applyDate, from, to); | ||
} | ||
} | ||
} | ||
|
||
return companies; | ||
} | ||
} |
Oops, something went wrong.