Search in sources :

Example 71 with Pair

use of org.apache.beam.repackaged.core.org.apache.commons.lang3.tuple.Pair in project twister2 by DSC-SPIDAL.

the class MPIDataFlowGather method init.

/**
 * Initialize
 * @param cfg
 * @param t
 * @param taskPlan
 * @param edge
 */
public void init(Config cfg, MessageType t, TaskPlan taskPlan, int edge) {
    this.type = t;
    this.instancePlan = taskPlan;
    this.executor = taskPlan.getThisExecutor();
    // we only have one path
    this.router = new InvertedBinaryTreeRouter(cfg, taskPlan, destination, sources, index);
    // initialize the receive
    if (this.partialReceiver != null && !isLastReceiver()) {
        partialReceiver.init(cfg, this, receiveExpectedTaskIds());
    }
    if (this.finalReceiver != null && isLastReceiver()) {
        this.finalReceiver.init(cfg, this, receiveExpectedTaskIds());
    }
    Map<Integer, ArrayBlockingQueue<Pair<Object, MPISendMessage>>> pendingSendMessagesPerSource = new HashMap<>();
    Map<Integer, Queue<Pair<Object, MPIMessage>>> pendingReceiveMessagesPerSource = new HashMap<>();
    Map<Integer, Queue<MPIMessage>> pendingReceiveDeSerializations = new HashMap<>();
    Map<Integer, MessageSerializer> serializerMap = new HashMap<>();
    Map<Integer, MessageDeSerializer> deSerializerMap = new HashMap<>();
    Set<Integer> srcs = router.sendQueueIds();
    for (int s : srcs) {
        // later look at how not to allocate pairs for this each time
        ArrayBlockingQueue<Pair<Object, MPISendMessage>> pendingSendMessages = new ArrayBlockingQueue<Pair<Object, MPISendMessage>>(MPIContext.sendPendingMax(cfg));
        pendingSendMessagesPerSource.put(s, pendingSendMessages);
        serializerMap.put(s, new MPIMultiMessageSerializer(new KryoSerializer(), executor));
    }
    int maxReceiveBuffers = MPIContext.receiveBufferCount(cfg);
    int receiveExecutorsSize = receivingExecutors().size();
    if (receiveExecutorsSize == 0) {
        receiveExecutorsSize = 1;
    }
    Set<Integer> execs = router.receivingExecutors();
    for (int e : execs) {
        int capacity = maxReceiveBuffers * 2 * receiveExecutorsSize;
        Queue<Pair<Object, MPIMessage>> pendingReceiveMessages = new ArrayBlockingQueue<Pair<Object, MPIMessage>>(capacity);
        pendingReceiveMessagesPerSource.put(e, pendingReceiveMessages);
        pendingReceiveDeSerializations.put(e, new ArrayBlockingQueue<MPIMessage>(capacity));
        deSerializerMap.put(e, new MPIMultiMessageDeserializer(new KryoSerializer(), executor));
    }
    Set<Integer> sourcesOfThisExec = TaskPlanUtils.getTasksOfThisExecutor(taskPlan, sources);
    for (int s : sourcesOfThisExec) {
        sendRoutingParameters(s, pathToUse);
        partialSendRoutingParameters(s, pathToUse);
    }
    delegete.init(cfg, t, taskPlan, edge, router.receivingExecutors(), router.isLastReceiver(), this, pendingSendMessagesPerSource, pendingReceiveMessagesPerSource, pendingReceiveDeSerializations, serializerMap, deSerializerMap, isKeyed);
    delegete.setKeyType(keyType);
}
Also used : MessageSerializer(edu.iu.dsc.tws.comms.mpi.io.MessageSerializer) MPIMultiMessageSerializer(edu.iu.dsc.tws.comms.mpi.io.MPIMultiMessageSerializer) HashMap(java.util.HashMap) MPIMultiMessageDeserializer(edu.iu.dsc.tws.comms.mpi.io.MPIMultiMessageDeserializer) KryoSerializer(edu.iu.dsc.tws.comms.utils.KryoSerializer) InvertedBinaryTreeRouter(edu.iu.dsc.tws.comms.routing.InvertedBinaryTreeRouter) MessageDeSerializer(edu.iu.dsc.tws.comms.mpi.io.MessageDeSerializer) MPIMultiMessageSerializer(edu.iu.dsc.tws.comms.mpi.io.MPIMultiMessageSerializer) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) Queue(java.util.Queue) Pair(org.apache.commons.lang3.tuple.Pair)

Example 72 with Pair

use of org.apache.beam.repackaged.core.org.apache.commons.lang3.tuple.Pair in project samourai-wallet-android by Samourai-Wallet.

the class RefreshService method onHandleIntent.

@Override
protected void onHandleIntent(Intent intent) {
    // 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, FOREGROUND_SERVICE_CHANNEL_ID).setPriority(NotificationCompat.PRIORITY_LOW).setContentTitle("Updating Wallet...").setSmallIcon(R.drawable.ic_samourai_logo_trans2x).setOngoing(true).setCategory(Notification.CATEGORY_SERVICE).setAutoCancel(true);
        Notification notification = builder.build();
        startForeground(1001, notification);
    }
    dragged = intent.getBooleanExtra("dragged", false);
    launch = intent.getBooleanExtra("launch", false);
    notifTx = intent.getBooleanExtra("notifTx", false);
    APIFactory.getInstance(RefreshService.this).stayingAlive();
    APIFactory.getInstance(RefreshService.this).initWallet();
    try {
        int acc = 0;
        if (AddressFactory.getInstance().getHighestTxReceiveIdx(acc) > HD_WalletFactory.getInstance(RefreshService.this).get().getAccount(acc).getReceive().getAddrIdx()) {
            HD_WalletFactory.getInstance(RefreshService.this).get().getAccount(acc).getReceive().setAddrIdx(AddressFactory.getInstance().getHighestTxReceiveIdx(acc));
        }
        if (AddressFactory.getInstance().getHighestTxChangeIdx(acc) > HD_WalletFactory.getInstance(RefreshService.this).get().getAccount(acc).getChange().getAddrIdx()) {
            HD_WalletFactory.getInstance(RefreshService.this).get().getAccount(acc).getChange().setAddrIdx(AddressFactory.getInstance().getHighestTxChangeIdx(acc));
        }
        if (AddressFactory.getInstance().getHighestBIP49ReceiveIdx() > BIP49Util.getInstance(RefreshService.this).getWallet().getAccount(0).getReceive().getAddrIdx()) {
            BIP49Util.getInstance(RefreshService.this).getWallet().getAccount(0).getReceive().setAddrIdx(AddressFactory.getInstance().getHighestBIP49ReceiveIdx());
        }
        if (AddressFactory.getInstance().getHighestBIP49ChangeIdx() > BIP49Util.getInstance(RefreshService.this).getWallet().getAccount(0).getChange().getAddrIdx()) {
            BIP49Util.getInstance(RefreshService.this).getWallet().getAccount(0).getChange().setAddrIdx(AddressFactory.getInstance().getHighestBIP49ChangeIdx());
        }
        if (AddressFactory.getInstance().getHighestBIP84ReceiveIdx() > BIP84Util.getInstance(RefreshService.this).getWallet().getAccount(0).getReceive().getAddrIdx()) {
            BIP84Util.getInstance(RefreshService.this).getWallet().getAccount(0).getReceive().setAddrIdx(AddressFactory.getInstance().getHighestBIP84ReceiveIdx());
        }
        if (AddressFactory.getInstance().getHighestBIP84ChangeIdx() > BIP84Util.getInstance(RefreshService.this).getWallet().getAccount(0).getChange().getAddrIdx()) {
            BIP84Util.getInstance(RefreshService.this).getWallet().getAccount(0).getChange().setAddrIdx(AddressFactory.getInstance().getHighestBIP84ChangeIdx());
        }
    } catch (IOException ioe) {
        ioe.printStackTrace();
    } catch (MnemonicException.MnemonicLengthException mle) {
        mle.printStackTrace();
    } catch (NullPointerException npe) {
        npe.printStackTrace();
    } finally {
        Intent _intent = new Intent("com.samourai.wallet.BalanceFragment.DISPLAY");
        LocalBroadcastManager.getInstance(RefreshService.this).sendBroadcast(_intent);
    }
    PrefsUtil.getInstance(RefreshService.this).setValue(PrefsUtil.FIRST_RUN, false);
    if (notifTx && !AppUtil.getInstance(RefreshService.this).isOfflineMode()) {
        // 
        try {
            PaymentCode pcode = BIP47Util.getInstance(RefreshService.this).getPaymentCode();
            // Log.i("BalanceFragment", "payment code:" + pcode.toString());
            // Log.i("BalanceFragment", "notification address:" + pcode.notificationAddress().getAddressString());
            APIFactory.getInstance(RefreshService.this).getNotifAddress(pcode.notificationAddress(SamouraiWallet.getInstance().getCurrentNetworkParams()).getAddressString());
        } catch (AddressFormatException afe) {
            afe.printStackTrace();
            Toast.makeText(RefreshService.this, "HD wallet error", Toast.LENGTH_SHORT).show();
        }
        // 
        // check on outgoing payment code notification tx
        // 
        List<Pair<String, String>> outgoingUnconfirmed = BIP47Meta.getInstance().getOutgoingUnconfirmed();
        // Log.i("BalanceFragment", "outgoingUnconfirmed:" + outgoingUnconfirmed.size());
        for (Pair<String, String> pair : outgoingUnconfirmed) {
            // Log.i("BalanceFragment", "outgoing payment code:" + pair.getLeft());
            // Log.i("BalanceFragment", "outgoing payment code tx:" + pair.getRight());
            int confirmations = APIFactory.getInstance(RefreshService.this).getNotifTxConfirmations(pair.getRight());
            if (confirmations > 0) {
                BIP47Meta.getInstance().setOutgoingStatus(pair.getLeft(), BIP47Meta.STATUS_SENT_CFM);
            }
            if (confirmations == -1) {
                BIP47Meta.getInstance().setOutgoingStatus(pair.getLeft(), BIP47Meta.STATUS_NOT_SENT);
            }
        }
        Intent _intent = new Intent("com.samourai.wallet.MainActivity2.RESTART_SERVICE");
        LocalBroadcastManager.getInstance(RefreshService.this).sendBroadcast(_intent);
    }
    if (launch) {
        if (PrefsUtil.getInstance(RefreshService.this).getValue(PrefsUtil.GUID_V, 0) < 4) {
            Log.i("RefreshService", "guid_v < 4");
            try {
                String _guid = AccessFactory.getInstance(RefreshService.this).createGUID();
                String _hash = AccessFactory.getInstance(RefreshService.this).getHash(_guid, new CharSequenceX(AccessFactory.getInstance(RefreshService.this).getPIN()), AESUtil.DefaultPBKDF2Iterations);
                PayloadUtil.getInstance(RefreshService.this).saveWalletToJSON(new CharSequenceX(_guid + AccessFactory.getInstance().getPIN()));
                PrefsUtil.getInstance(RefreshService.this).setValue(PrefsUtil.ACCESS_HASH, _hash);
                PrefsUtil.getInstance(RefreshService.this).setValue(PrefsUtil.ACCESS_HASH2, _hash);
                Log.i("RefreshService", "guid_v == 4");
            } catch (MnemonicException.MnemonicLengthException | IOException | JSONException | DecryptionException e) {
                ;
            }
        }
        if (PrefsUtil.getInstance(RefreshService.this).getValue(PrefsUtil.XPUB44LOCK, false) == false) {
            try {
                String[] s = HD_WalletFactory.getInstance(RefreshService.this).get().getXPUBs();
                APIFactory.getInstance(RefreshService.this).lockXPUB(s[0], 44, null);
            } catch (IOException | MnemonicException.MnemonicLengthException e) {
                ;
            }
        }
        if (PrefsUtil.getInstance(RefreshService.this).getValue(PrefsUtil.XPUB49LOCK, false) == false) {
            String ypub = BIP49Util.getInstance(RefreshService.this).getWallet().getAccount(0).ypubstr();
            APIFactory.getInstance(RefreshService.this).lockXPUB(ypub, 49, null);
        }
        if (PrefsUtil.getInstance(RefreshService.this).getValue(PrefsUtil.XPUB84LOCK, false) == false) {
            String zpub = BIP84Util.getInstance(RefreshService.this).getWallet().getAccount(0).zpubstr();
            APIFactory.getInstance(RefreshService.this).lockXPUB(zpub, 84, null);
        }
        if (PrefsUtil.getInstance(RefreshService.this).getValue(PrefsUtil.XPUBPRELOCK, false) == false) {
            String zpub = BIP84Util.getInstance(RefreshService.this).getWallet().getAccountAt(WhirlpoolMeta.getInstance(RefreshService.this).getWhirlpoolPremixAccount()).zpubstr();
            APIFactory.getInstance(RefreshService.this).lockXPUB(zpub, 84, PrefsUtil.XPUBPRELOCK);
        }
        if (PrefsUtil.getInstance(RefreshService.this).getValue(PrefsUtil.XPUBPOSTLOCK, false) == false) {
            String zpub = BIP84Util.getInstance(RefreshService.this).getWallet().getAccountAt(WhirlpoolMeta.getInstance(RefreshService.this).getWhirlpoolPostmix()).zpubstr();
            APIFactory.getInstance(RefreshService.this).lockXPUB(zpub, 84, PrefsUtil.XPUBPRELOCK);
        }
        if (PrefsUtil.getInstance(RefreshService.this).getValue(PrefsUtil.XPUBBADBANKLOCK, false) == false) {
            String zpub = BIP84Util.getInstance(RefreshService.this).getWallet().getAccountAt(WhirlpoolMeta.getInstance(RefreshService.this).getWhirlpoolBadBank()).zpubstr();
            APIFactory.getInstance(RefreshService.this).lockXPUB(zpub, 84, PrefsUtil.XPUBBADBANKLOCK);
        }
    } else {
        try {
            PayloadUtil.getInstance(RefreshService.this).saveWalletToJSON(new CharSequenceX(AccessFactory.getInstance(RefreshService.this).getGUID() + AccessFactory.getInstance(RefreshService.this).getPIN()));
        } catch (Exception e) {
            ;
        }
    }
    Intent _intent = new Intent("com.samourai.wallet.BalanceFragment.DISPLAY");
    LocalBroadcastManager.getInstance(RefreshService.this).sendBroadcast(_intent);
}
Also used : AddressFormatException(org.bitcoinj.core.AddressFormatException) PaymentCode(com.samourai.wallet.bip47.rpc.PaymentCode) CharSequenceX(com.samourai.wallet.util.CharSequenceX) JSONException(org.json.JSONException) Intent(android.content.Intent) IOException(java.io.IOException) Notification(android.app.Notification) MnemonicException(org.bitcoinj.crypto.MnemonicException) JSONException(org.json.JSONException) DecryptionException(com.samourai.wallet.crypto.DecryptionException) AddressFormatException(org.bitcoinj.core.AddressFormatException) IOException(java.io.IOException) MnemonicException(org.bitcoinj.crypto.MnemonicException) NotificationCompat(android.support.v4.app.NotificationCompat) DecryptionException(com.samourai.wallet.crypto.DecryptionException) Pair(org.apache.commons.lang3.tuple.Pair)

Example 73 with Pair

use of org.apache.beam.repackaged.core.org.apache.commons.lang3.tuple.Pair in project graal by graphik-team.

the class NFC2WithLimit method select.

// /////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
// /////////////////////////////////////////////////////////////////////////
@Override
protected boolean select(Atom atom, Var v, AtomSet g, Substitution initialSubstitution, Map<Variable, Integer> map, Var[] varData, RulesCompilation rc) throws AtomSetException, IteratorException {
    boolean contains = false;
    int nbAns = 0;
    Iterator<Pair<Atom, Substitution>> rewIt = rc.getRewritingOf(atom).iterator();
    Set<Var> postVarsFromThisAtom = new HashSet<Var>();
    while (rewIt.hasNext() && nbAns < LIMIT) {
        Atom a = rewIt.next().getLeft();
        Var[] postV = this.computePostVariablesPosition(a, v.shared.level, map, varData, postVarsFromThisAtom);
        Atom im = BacktrackUtils.createImageOf(a, initialSubstitution, map, varData);
        Profiler profiler = this.getProfiler();
        if (profiler != null) {
            profiler.incr("#Select", 1);
            profiler.start("SelectTime");
        }
        int cpt = 0;
        CloseableIterator<? extends Atom> it = g.match(im);
        while (it.hasNext() && nbAns < LIMIT) {
            ++nbAns;
            ++cpt;
            int i = -1;
            for (Term t : it.next()) {
                ++i;
                if (postV[i] != null) {
                    this.data[postV[i].shared.level].tmp.add(t);
                }
            }
            contains = true;
        }
        if (profiler != null) {
            profiler.stop("SelectTime");
            profiler.incr("#SelectAns", cpt);
        }
    }
    boolean isThereAnEmptiedList = false;
    if (contains) {
        // set computed candidats for post variables
        for (Var z : postVarsFromThisAtom) {
            if (!isThereAnEmptiedList) {
                if (nbAns >= LIMIT) {
                    this.dataWithLimit[z.shared.level].atomsToCheck.add(atom);
                } else {
                    AcceptableCandidats ac = this.data[z.shared.level].candidats[v.shared.level];
                    if (ac.init) {
                        ac.candidats.retainAll(this.data[z.shared.level].tmp);
                        isThereAnEmptiedList |= ac.candidats.isEmpty();
                        if (ac.candidats.isEmpty()) {
                            this.bj.addNeighborhoodToBackjumpSet(z.shared, v.shared);
                        }
                    } else {
                        ac.candidats.addAll(this.data[z.shared.level].tmp);
                        ac.init = true;
                    }
                }
            }
            this.data[z.shared.level].tmp.clear();
        }
    } else {
        Var z = postVarsFromThisAtom.iterator().next();
        this.bj.addNeighborhoodToBackjumpSet(z.shared, v.shared);
    }
    return contains && !isThereAnEmptiedList;
}
Also used : Var(fr.lirmm.graphik.graal.homomorphism.Var) Term(fr.lirmm.graphik.graal.api.core.Term) Atom(fr.lirmm.graphik.graal.api.core.Atom) Profiler(fr.lirmm.graphik.util.profiler.Profiler) Pair(org.apache.commons.lang3.tuple.Pair) HashSet(java.util.HashSet)

Example 74 with Pair

use of org.apache.beam.repackaged.core.org.apache.commons.lang3.tuple.Pair in project graal by graphik-team.

the class IDCompilationTest method test.

/**
 * Given p(X,Y) -> q(X,Y,X) <br>
 * Then rew(q(U,V,W)) <br>
 * Return q(U,V,W)-{} AND (p(U,V)-{W->U} || p(W,V)-{U->W})
 */
@Test
public void test() {
    Predicate predicateQ = new Predicate("q", 3);
    Predicate predicateP = new Predicate("p", 2);
    Atom body = new DefaultAtom(predicateP, X, Y);
    Atom head = new DefaultAtom(predicateQ, X, Y, X);
    Atom query = new DefaultAtom(predicateQ, U, V, W);
    RuleSet rules = new LinkedListRuleSet();
    rules.add(DefaultRuleFactory.instance().create(body, head));
    RulesCompilation comp = new IDCompilation();
    comp.compile(rules.iterator());
    Collection<Pair<Atom, Substitution>> rewritingOf = comp.getRewritingOf(query);
    boolean rew1 = false;
    boolean rew2 = false;
    for (Pair<Atom, Substitution> p : rewritingOf) {
        Atom a = p.getLeft();
        Substitution s = p.getRight();
        if (a.getPredicate().equals(predicateQ)) {
            rew1 = true;
            Assert.assertEquals(U, a.getTerm(0));
            Assert.assertEquals(V, a.getTerm(1));
            Assert.assertEquals(W, a.getTerm(2));
            Assert.assertEquals(0, s.getTerms().size());
        } else {
            rew2 = true;
            Assert.assertEquals(predicateP, a.getPredicate());
            Assert.assertTrue(a.getTerm(0).equals(U) || a.getTerm(0).equals(W));
            Assert.assertEquals(V, a.getTerm(1));
            Assert.assertEquals(1, s.getTerms().size());
        }
    }
    Assert.assertTrue(rew1 && rew2);
    Assert.assertEquals(2, rewritingOf.size());
}
Also used : RuleSet(fr.lirmm.graphik.graal.api.core.RuleSet) LinkedListRuleSet(fr.lirmm.graphik.graal.core.ruleset.LinkedListRuleSet) Substitution(fr.lirmm.graphik.graal.api.core.Substitution) DefaultAtom(fr.lirmm.graphik.graal.core.DefaultAtom) LinkedListRuleSet(fr.lirmm.graphik.graal.core.ruleset.LinkedListRuleSet) RulesCompilation(fr.lirmm.graphik.graal.api.core.RulesCompilation) DefaultAtom(fr.lirmm.graphik.graal.core.DefaultAtom) Atom(fr.lirmm.graphik.graal.api.core.Atom) Predicate(fr.lirmm.graphik.graal.api.core.Predicate) Pair(org.apache.commons.lang3.tuple.Pair) Test(org.junit.Test)

Example 75 with Pair

use of org.apache.beam.repackaged.core.org.apache.commons.lang3.tuple.Pair in project graal by graphik-team.

the class IDCompilationTest method test3.

/**
 * Given p(X,Y) -> q(X,Y,X,Y,X) <br>
 * Then rew(q(U,V,A,B,V)) <br>
 * Return q(U,V,A,B,V)-{}
 */
@Test
public void test3() {
    Predicate predicateQ = new Predicate("q", 5);
    Predicate predicateP = new Predicate("p", 2);
    Atom body = new DefaultAtom(predicateP, X, Y);
    Atom head = new DefaultAtom(predicateQ, X, Y, X, Y, X);
    Atom query = new DefaultAtom(predicateQ, U, V, A, B, V);
    RuleSet rules = new LinkedListRuleSet();
    rules.add(DefaultRuleFactory.instance().create(body, head));
    RulesCompilation comp = new IDCompilation();
    comp.compile(rules.iterator());
    Collection<Pair<Atom, Substitution>> rewritingOf = comp.getRewritingOf(query);
    Assert.assertEquals(1, rewritingOf.size());
    Pair<Atom, Substitution> p = rewritingOf.iterator().next();
    Atom a = p.getLeft();
    Substitution s = p.getRight();
    Assert.assertEquals(predicateQ, a.getPredicate());
    Assert.assertEquals(U, a.getTerm(0));
    Assert.assertEquals(V, a.getTerm(1));
    Assert.assertEquals(A, a.getTerm(2));
    Assert.assertEquals(B, a.getTerm(3));
    Assert.assertEquals(V, a.getTerm(4));
    Assert.assertEquals(0, s.getTerms().size());
}
Also used : RuleSet(fr.lirmm.graphik.graal.api.core.RuleSet) LinkedListRuleSet(fr.lirmm.graphik.graal.core.ruleset.LinkedListRuleSet) Substitution(fr.lirmm.graphik.graal.api.core.Substitution) DefaultAtom(fr.lirmm.graphik.graal.core.DefaultAtom) LinkedListRuleSet(fr.lirmm.graphik.graal.core.ruleset.LinkedListRuleSet) RulesCompilation(fr.lirmm.graphik.graal.api.core.RulesCompilation) DefaultAtom(fr.lirmm.graphik.graal.core.DefaultAtom) Atom(fr.lirmm.graphik.graal.api.core.Atom) Predicate(fr.lirmm.graphik.graal.api.core.Predicate) Pair(org.apache.commons.lang3.tuple.Pair) Test(org.junit.Test)

Aggregations

Pair (org.apache.commons.lang3.tuple.Pair)685 ArrayList (java.util.ArrayList)209 List (java.util.List)154 Test (org.junit.Test)150 ImmutablePair (org.apache.commons.lang3.tuple.ImmutablePair)142 HashMap (java.util.HashMap)123 Collectors (java.util.stream.Collectors)123 Map (java.util.Map)112 Message (com.microsoft.azure.sdk.iot.device.Message)71 IOException (java.io.IOException)70 MutablePair (org.apache.commons.lang3.tuple.MutablePair)64 java.util (java.util)55 IotHubTransportMessage (com.microsoft.azure.sdk.iot.device.transport.IotHubTransportMessage)52 Set (java.util.Set)49 StringUtils (org.apache.commons.lang3.StringUtils)48 File (java.io.File)46 Optional (java.util.Optional)45 Arrays (java.util.Arrays)44 HashSet (java.util.HashSet)40 Test (org.junit.jupiter.api.Test)39