Changeset 2daeb6d


Ignore:
Timestamp:
Jul 13, 2018 9:12:25 AM (2 years ago)
Author:
meeh <meeh@…>
Branches:
master
Children:
3fcef90c
Parents:
c8490a3 (diff), 5fd1b69 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge of '54817017a7af30d5a701bb76ce4c5f18479d525c'

and 'b90d952c362ac02ebfadf0049cfdca61e870cd87'

Files:
1 added
23 edited

Legend:

Unmodified
Added
Removed
  • apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java

    rc8490a3 r2daeb6d  
    106106    private static final String PROP_META_ADDED = "added";
    107107    private static final String PROP_META_COMPLETED = "completed";
     108    private static final String PROP_META_INORDER = "inOrder";
    108109    private static final String PROP_META_MAGNET = "magnet";
    109110    private static final String PROP_META_MAGNET_DN = "magnet_dn";
     
    17601761                return false;
    17611762            } else if (bitfield != null) {
    1762                 saveTorrentStatus(metainfo, bitfield, null, baseFile, true, 0, true); // no file priorities
     1763                saveTorrentStatus(metainfo, bitfield, null, false, baseFile, true, 0, true); // no file priorities
    17631764            }
    17641765            // so addTorrent won't recheck           
     
    18991900        Properties config = getConfig(snark);
    19001901        String pri = config.getProperty(PROP_META_PRIORITY);
    1901         if (pri == null)
    1902             return;
    1903         int filecount = metainfo.getFiles().size();
    1904         int[] rv = new int[filecount];
    1905         String[] arr = DataHelper.split(pri, ",");
    1906         for (int i = 0; i < filecount && i < arr.length; i++) {
    1907             if (arr[i].length() > 0) {
    1908                 try {
    1909                     rv[i] = Integer.parseInt(arr[i]);
    1910                 } catch (Throwable t) {}
    1911             }
    1912         }
    1913         storage.setFilePriorities(rv);
     1902        if (pri != null) {
     1903            int filecount = metainfo.getFiles().size();
     1904            int[] rv = new int[filecount];
     1905            String[] arr = DataHelper.split(pri, ",");
     1906            for (int i = 0; i < filecount && i < arr.length; i++) {
     1907                if (arr[i].length() > 0) {
     1908                    try {
     1909                        rv[i] = Integer.parseInt(arr[i]);
     1910                    } catch (Throwable t) {}
     1911                }
     1912            }
     1913            storage.setFilePriorities(rv);
     1914        }
     1915        boolean inOrder = Boolean.parseBoolean(config.getProperty(PROP_META_INORDER));
     1916        storage.setInOrder(inOrder);
    19141917    }
    19151918
     
    20182021        if (meta == null || storage == null)
    20192022            return;
    2020         saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(),
     2023        saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(), storage.getInOrder(),
    20212024                          storage.getBase(), storage.getPreserveFileNames(),
    20222025                          snark.getUploaded(), snark.isStopped(), comments);
     
    20352038     * @param base may be null
    20362039     */
    2037     private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
     2040    private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, boolean inOrder,
    20382041                                   File base, boolean preserveNames, long uploaded, boolean stopped) {
    2039         saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded, stopped, null);
     2042        saveTorrentStatus(metainfo, bitfield, priorities, inOrder, base, preserveNames, uploaded, stopped, null);
    20402043    }
    20412044
     
    20442047     * @since 0.9.31
    20452048     */
    2046     private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
     2049    private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, boolean inOrder,
    20472050                                   File base, boolean preserveNames, long uploaded, boolean stopped,
    20482051                                   Boolean comments) {
    20492052        synchronized (_configLock) {
    2050             locked_saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded, stopped, comments);
    2051         }
    2052     }
    2053 
    2054     private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
     2053            locked_saveTorrentStatus(metainfo, bitfield, priorities, inOrder, base, preserveNames, uploaded, stopped, comments);
     2054        }
     2055    }
     2056
     2057    private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, boolean inOrder,
    20552058                                          File base, boolean preserveNames, long uploaded, boolean stopped,
    20562059                                          Boolean comments) {
     
    20782081        boolean running = !stopped;
    20792082        config.setProperty(PROP_META_RUNNING, Boolean.toString(running));
     2083        config.setProperty(PROP_META_INORDER, Boolean.toString(inOrder));
    20802084        if (base != null)
    20812085            config.setProperty(PROP_META_BASE, base.getAbsolutePath());
     
    20962100                StringBuilder buf = new StringBuilder(2 * priorities.length);
    20972101                for (int i = 0; i < priorities.length; i++) {
    2098                     if (priorities[i] != 0)
     2102                    // only output if !inOrder || !skipped so the string isn't too long
     2103                    if (priorities[i] != 0 &&
     2104                        (!inOrder || priorities[i] < 0))
    20992105                        buf.append(Integer.toString(priorities[i]));
    21002106                    if (i != priorities.length - 1)
     
    24442450        Storage storage = snark.getStorage();
    24452451        if (meta != null && storage != null)
    2446             saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(),
     2452            saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(), storage.getInOrder(),
    24472453                              storage.getBase(), storage.getPreserveFileNames(), snark.getUploaded(),
    24482454                              snark.isStopped());
     
    24682474                return null;
    24692475            }
    2470             saveTorrentStatus(meta, storage.getBitField(), null,
     2476            saveTorrentStatus(meta, storage.getBitField(), null, false,
    24712477                              storage.getBase(), storage.getPreserveFileNames(), 0,
    24722478                              snark.isStopped());
  • apps/i2psnark/java/src/org/klomp/snark/Storage.java

    rc8490a3 r2daeb6d  
    2626import java.io.IOException;
    2727import java.io.RandomAccessFile;
     28import java.io.Serializable;
    2829import java.nio.charset.Charset;
    2930import java.nio.charset.CharsetEncoder;
    3031import java.security.MessageDigest;
     32import java.text.Collator;
    3133import java.util.ArrayList;
    3234import java.util.Collections;
     35import java.util.Comparator;
    3336import java.util.Iterator;
    3437import java.util.List;
     
    7376  private boolean changed;
    7477  private volatile boolean _isChecking;
     78  private boolean _inOrder;
    7579  private final AtomicInteger _allocateCount = new AtomicInteger();
    7680  private final AtomicInteger _checkProgress = new AtomicInteger();
     
    8387  public static final int MAX_PIECES = 32*1024;
    8488  public static final long MAX_TOTAL_SIZE = MAX_PIECE_SIZE * (long) MAX_PIECES;
     89  public static final int PRIORITY_SKIP = -9;
     90  public static final int PRIORITY_NORMAL = 0;
    8591
    8692  private static final Map<String, String> _filterNameCache = new ConcurrentHashMap<String, String>();
     
    146152   
    147153    long total = 0;
    148     ArrayList<Long> lengthsList = new ArrayList<Long>();
     154    ArrayList<Long> lengthsList = new ArrayList<Long>(_torrentFiles.size());
    149155    for (TorrentFile tf : _torrentFiles)
    150156      {
     
    179185    needed = 0;
    180186
    181     List<List<String>> files = new ArrayList<List<String>>();
     187    List<List<String>> files = new ArrayList<List<String>>(_torrentFiles.size());
    182188    for (TorrentFile tf : _torrentFiles)
    183189      {
     
    496502
    497503  /**
     504   *  @return as last set, default false
     505   *  @since 0.9.36
     506   */
     507  public boolean getInOrder() {
     508      return _inOrder;
     509  }
     510
     511  /**
     512   *  Call AFTER setFilePriorites() so we know what's skipped
     513   *  @param yes enable or not
     514   *  @since 0.9.36
     515   */
     516  public void setInOrder(boolean yes) {
     517      if (yes == _inOrder)
     518          return;
     519      _inOrder = yes;
     520      if (complete() || metainfo.getFiles() == null)
     521          return;
     522      if (yes) {
     523          List<TorrentFile> sorted = _torrentFiles;
     524          int sz = sorted.size();
     525          if (sz > 1) {
     526              sorted = new ArrayList<TorrentFile>(sorted);
     527              Collections.sort(sorted, new FileNameComparator());
     528          }
     529          for (int i = 0; i < sz; i++) {
     530              TorrentFile tf = sorted.get(i);
     531              // higher number is higher priority
     532              if (tf.priority >= PRIORITY_NORMAL)
     533                  tf.priority = sz - i;
     534          }
     535      } else {
     536          for (TorrentFile tf : _torrentFiles) {
     537              if (tf.priority > PRIORITY_NORMAL)
     538                  tf.priority = PRIORITY_NORMAL;
     539          }
     540      }
     541  }
     542
     543  /**
     544   *  Sort with locale comparator.
     545   *  (not using TorrentFile.compareTo())
     546   *  @since 0.9.36
     547   */
     548  private static class FileNameComparator implements Comparator<TorrentFile>, Serializable {
     549
     550     private final Collator c = Collator.getInstance();
     551
     552     public int compare(TorrentFile l, TorrentFile r) {
     553         return c.compare(l.toString(), r.toString());
     554     }
     555  }
     556
     557  /**
    498558   *  Call setPriority() for all changed files first,
    499559   *  then call this.
     
    524584          rv[i] = pri;
    525585      }
     586      if (_inOrder) {
     587          // Do a second pass to set the priority of the pieces within each file
     588          // this only works because MAX_PIECES * MAX_FILES_PER_TORRENT < Integer.MAX_VALUE
     589          // the base file priority
     590          int pri = PRIORITY_SKIP;
     591          for (int i = 0; i < rv.length; i++) {
     592              int val = rv[i];
     593              if (val <= PRIORITY_NORMAL)
     594                  continue;
     595              if (val != pri) {
     596                  pri = val;
     597                  // new file
     598                  rv[i] *= MAX_PIECES;
     599              } else {
     600                  // same file, decrement priority from previous piece
     601                  rv[i] = rv[i-1] - 1;
     602              }
     603          }
     604      }
    526605      return rv;
    527606  }
     
    545624      final int end = pri.length - 1;
    546625      for (int i = 0; i <= end; i++) {
    547           if (pri[i] <= -9 && !bitfield.get(i)) {
     626          if (pri[i] <= PRIORITY_SKIP && !bitfield.get(i)) {
    548627              rv += (i != end) ? piece_size : metainfo.getPieceLength(i);
    549628          }
  • apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java

    rc8490a3 r2daeb6d  
    29322932                String nonce = val[0];
    29332933                if (String.valueOf(_nonce).equals(nonce)) {
    2934                     if (postParams.get("savepri") != null) {
     2934                    if (postParams.get("savepri") != null ||
     2935                        postParams.get("setInOrderEnabled") != null) {
    29352936                        savePriorities(snark, postParams);
    29362937                    } else if (postParams.get("addComment") != null) {
     
    29752976
    29762977        boolean showStopStart = snark != null;
    2977         boolean showPriority = snark != null && snark.getStorage() != null && !snark.getStorage().complete() &&
     2978        Storage storage = snark != null ? snark.getStorage() : null;
     2979        boolean showPriority = storage != null && !storage.complete() &&
    29782980                               r.isDirectory();
    29792981
     
    30373039               .append(DataHelper.escapeHTML(fullPath))
    30383040               .append("</a></td></tr>\n");
    3039             if (snark.getStorage() != null) {
     3041            if (storage != null) {
    30403042                buf.append("<tr><td>");
    30413043                toThemeImg(buf, "file");
     
    30433045                   .append(_t("Data location"))
    30443046                   .append(":</b> ")
    3045                    .append(DataHelper.escapeHTML(snark.getStorage().getBase().getPath()))
     3047                   .append(DataHelper.escapeHTML(storage.getBase().getPath()))
    30463048                   .append("</td></tr>\n");
    30473049            }
     
    32863288                buf.append("</td></tr>\n");
    32873289            }
     3290
     3291            boolean showInOrder = storage != null && !storage.complete() &&
     3292                                  meta != null && meta.getFiles() != null && meta.getFiles().size() > 1;
     3293            if (showInOrder) {
     3294                buf.append("<tr id=\"torrentOrderControl\"><td colspan=\"2\">");
     3295                buf.append(_t("Download files in order"));
     3296                buf.append(":<label><input type=\"checkbox\" class=\"optbox\" name=\"enableInOrder\" id=\"enableInOrder\" ");
     3297                if (storage.getInOrder())
     3298                    buf.append("checked=\"checked\"");
     3299                buf.append(">&nbsp;");
     3300                buf.append(_t("Enable for this torrent"));
     3301                buf.append("</label>" +
     3302                           "<input type=\"submit\" name=\"setInOrderEnabled\" value=\"");
     3303                buf.append(_t("Save Preference"));
     3304                buf.append("\" class=\"accept\">" +
     3305                           "</td></tr>\n");
     3306            }
    32883307        } else {
    32893308            // snark == null
     
    33243343        }
    33253344
    3326         Storage storage = snark != null ? snark.getStorage() : null;
    33273345        List<Sorters.FileAndIndex> fileList = new ArrayList<Sorters.FileAndIndex>(ls.length);
    33283346        // precompute remaining for all files for efficiency
     
    34253443        boolean showSaveButton = false;
    34263444        boolean rowEven = true;
     3445        boolean inOrder = storage != null && storage.getInOrder();
    34273446        for (Sorters.FileAndIndex fai : fileList)
    34283447        {
     
    34483467                //status = toImg("tick") + ' ' + _t("Directory");
    34493468            } else {
    3450                 if (snark == null || snark.getStorage() == null) {
     3469                if (storage == null) {
    34513470                    // Assume complete, perhaps he removed a completed torrent but kept a bookmark
    34523471                    complete = true;
     
    35283547                buf.append("<td class=\"priority\">");
    35293548                if ((!complete) && (!item.isDirectory())) {
    3530                     buf.append("<label class=\"priorityHigh\" title=\"").append(_t("Download file at high priority")).append("\">" +
    3531                                "\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prihigh\" value=\"5\" name=\"pri.").append(fileIndex).append("\" ");
    3532                     if (priority > 0)
    3533                         buf.append("checked=\"checked\"");
    3534                     buf.append('>')
    3535                        .append(_t("High")).append("</label>");
     3549                    if (!inOrder) {
     3550                        buf.append("<label class=\"priorityHigh\" title=\"").append(_t("Download file at high priority")).append("\">" +
     3551                                   "\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prihigh\" value=\"5\" name=\"pri.").append(fileIndex).append("\" ");
     3552                        if (priority > 0)
     3553                            buf.append("checked=\"checked\"");
     3554                        buf.append('>')
     3555                           .append(_t("High")).append("</label>");
     3556                    }
    35363557
    35373558                    buf.append("<label class=\"priorityNormal\" title=\"").append(_t("Download file at normal priority")).append("\">" +
    35383559                               "\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prinorm\" value=\"0\" name=\"pri.").append(fileIndex).append("\" ");
    3539                     if (priority == 0)
     3560                    if (priority == 0 || (inOrder && priority >= 0))
    35403561                        buf.append("checked=\"checked\"");
    35413562                    buf.append('>')
     
    35563577        if (showSaveButton) {
    35573578            buf.append("<thead><tr id=\"setPriority\"><th class=\"headerpriority\" colspan=\"5\">" +
    3558                        "<span class=\"script\"><a class=\"control\" id=\"setallhigh\" href=\"javascript:void(null);\" onclick=\"setallhigh();\">")
    3559                .append(toImg("clock_red")).append(_t("Set all high")).append("</a>\n" +
    3560                        "<a class=\"control\" id=\"setallnorm\" href=\"javascript:void(null);\" onclick=\"setallnorm();\">")
     3579                       "<span class=\"script\">");
     3580            if (!inOrder) {
     3581                buf.append("<a class=\"control\" id=\"setallhigh\" href=\"javascript:void(null);\" onclick=\"setallhigh();\">")
     3582                   .append(toImg("clock_red")).append(_t("Set all high")).append("</a>\n");
     3583            }
     3584            buf.append("<a class=\"control\" id=\"setallnorm\" href=\"javascript:void(null);\" onclick=\"setallnorm();\">")
    35613585               .append(toImg("clock")).append(_t("Set all normal")).append("</a>\n" +
    35623586                       "<a class=\"control\" id=\"setallskip\" href=\"javascript:void(null);\" onclick=\"setallskip();\">")
     
    39273951            }
    39283952        }
     3953        if (postParams.get("setInOrderEnabled") != null)
     3954            storage.setInOrder(postParams.get("enableInOrder") != null);
    39293955        snark.updatePiecePriorities();
    39303956        _manager.saveTorrentStatus(snark);
  • apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionManager.java

    rc8490a3 r2daeb6d  
    9898        _tcbShare = new TCBShare(_context, _timer);
    9999        // PROTO_ANY is for backward compatibility (pre-0.7.1)
    100         // TODO change proto to PROTO_STREAMING someday.
    101         // Right now we get everything, and rely on Datagram to specify PROTO_UDP.
    102100        // PacketQueue has sent PROTO_STREAMING since the beginning of mux support (0.7.1)
    103101        // As of 0.9.1, new option to enforce streaming protocol, off by default
    104102        // As of 0.9.1, listen on configured port (default 0 = all)
     103        // enforce protocol default changed to true in 0.9.36
    105104        int protocol = defaultOptions.getEnforceProtocol() ? I2PSession.PROTO_STREAMING : I2PSession.PROTO_ANY;
    106105        _session.addMuxedSessionListener(_messageHandler, protocol, defaultOptions.getLocalPort());
  • apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionOptions.java

    rc8490a3 r2daeb6d  
    156156    /**
    157157     *  If PROTO is enforced, we cannot communicate with destinations earlier than version 0.7.1.
     158     *  Default true as of 0.9.36.
    158159     *  @since 0.9.1
    159160     */
    160     private static final boolean DEFAULT_ENFORCE_PROTO = false;
     161    private static final boolean DEFAULT_ENFORCE_PROTO = true;
    161162
    162163    private final int _trend[] = new int[TREND_COUNT];
     
    524525    /**
    525526     * Do we receive all traffic, or only traffic marked with I2PSession.PROTO_STREAMING (6) ?
    526      * Default false.
     527     * Default true.
    527528     * If PROTO is enforced, we cannot communicate with destinations earlier than version 0.7.1
    528529     * (released March 2009), which is when streaming started sending the PROTO_STREAMING indication.
  • build.properties

    rc8490a3 r2daeb6d  
    3131# Building EXEs in x64 Linux requires that 32bit libraries are installed. In Debian,
    3232# for example, installing the libc6-i386 package will satisfy this requirement.
    33 
    3433# Uncomment the next line to prevent building EXEs (changing it to false will have no impact)
    3534#noExe=true
     35
     36# IzPack 5.1.x install dir
     37#izpack5.home=/PATH/TO/IzPack
    3638
    3739# Change this to false if you don't have gettext or you want to prevent it from running during the build
  • build.xml

    rc8490a3 r2daeb6d  
    2525        <echo message="  installer-windows: build the GUI installer (Windows only)" />
    2626        <echo message="  installer-nowindows: build the GUI installer (all but Windows)" />
     27        <echo message="  installer5, installer5-linux, installer5-nowindows, installer5-windows: use IzPack 5" />
    2728        <echo message="  osxLauncher: build the Mac OS X router/GUI launcher (OSX only)" />
    2829        <echo message="  bbLauncher: build the Browser Bundle router launcher" />
     
    8081            <echo message=" " />
    8182            <echo message="The following command will install the additional runtime dependencies:" />
    82             <echo message="sudo apt-get install libecj-java geoip-database" />
     83            <echo message="sudo apt-get install geoip-database famfamfam-flag-png" />
    8384            <echo message=" " />
    8485            <echo message="Once the dependencies are installed, run &quot;ant debian&quot;"/>
     
    17631764    </target>
    17641765
     1766    <!-- IzPack 4 -->
    17651767    <target name="installer" depends="preppkg, buildProperties, util-list-changes, izpack-patches, buildUtilityJar" >
    1766         <!--
    1767           Force 1.5 pack200 output
    1768           Doesnt work!
    1769           http://jira.codehaus.org/browse/IZPACK-404
    1770           http://forums.sun.com/thread.jspa?threadID=773439
    1771           http://bfo.co.uk/blog/2010/05/13/combining_ant_jar_signatures_and_pack200.html
    1772         <property name="com.sun.java.util.jar.pack.package.majver" value="150" />
    1773         <property name="com.sun.java.util.jar.pack.package.minver" value="7" />
    1774         -->
    17751768        <izpack input="${basedir}/installer/install.xml" output="${basedir}/install.jar" installerType="standard" basedir="${basedir}" />
    1776 
     1769        <ant target="installerexe" />
     1770    </target>
     1771
     1772    <!-- IzPack 5 -->
     1773    <target name="ensureIzpack5" >
     1774        <!-- set if unset -->
     1775        <property name="izpack5.home" value="${user.home}/IzPack" />
     1776        <condition property="izpack5.available" >
     1777            <available file="${izpack5.home}" type="dir" />
     1778        </condition>
     1779        <fail message="Error - IzPack 5.1.x must be installed at ${izpack5.home}, or set izpack5.home=/PATH/TO/IzPack in override.properties, or download from http://izpack.org/downloads/ and install" >
     1780            <condition>
     1781                <not>
     1782                    <isset property="izpack5.available" />
     1783                </not>
     1784            </condition>
     1785        </fail>
     1786        <path id="izpack5.lib.path">
     1787            <fileset dir="${izpack5.home}/lib" includes="*.jar"/>
     1788        </path>
     1789        <taskdef name="izpack5"
     1790                 classpathref="izpack5.lib.path"
     1791                 classname="com.izforge.izpack.ant.IzPackTask" />
     1792    </target>
     1793
     1794    <target name="installer5" depends="ensureIzpack5, preppkg, buildProperties, util-list-changes, buildUtilityJar" >
     1795        <izpack5 input="${basedir}/installer/install5.xml" output="${basedir}/install.jar" installerType="standard" basedir="${basedir}" />
    17771796        <ant target="installerexe" />
    17781797    </target>
     
    17871806
    17881807    <!-- Custom installers -->
     1808    <!-- IzPack 4 -->
    17891809    <target name="installer-nowindows" depends="clean, preppkg-nowindows, izpack-patches" >
    17901810        <fixcrlf srcdir="pkg-temp" includes="*.config **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="lf" />
     
    17921812    </target>
    17931813
     1814    <!-- IzPack 5 -->
     1815    <target name="installer5-nowindows" depends="ensureIzpack5, clean, preppkg-nowindows" >
     1816        <fixcrlf srcdir="pkg-temp" includes="*.config **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="lf" />
     1817        <izpack5 input="${basedir}/installer/install5.xml" output="${basedir}/i2pinstall_${full.version}.jar" installerType="standard" basedir="${basedir}" />
     1818    </target>
     1819
    17941820
    17951821    <target name="installer-freebsd" depends="clean, preppkg-freebsd-only, izpack-patches" >
     
    17981824    </target>
    17991825
     1826    <!-- IzPack 4 -->
    18001827    <target name="installer-linux" depends="clean, preppkg-linux-only, izpack-patches" >
    18011828        <fixcrlf srcdir="pkg-temp" includes="*.config **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="lf" />
    18021829        <izpack input="${basedir}/installer/install.xml" output="${basedir}/i2pinstall_${full.version}_linux-only.jar" installerType="standard" basedir="${basedir}" />
     1830    </target>
     1831
     1832    <!-- IzPack 5 -->
     1833    <target name="installer5-linux" depends="ensureIzpack5, clean, preppkg-linux-only" >
     1834        <fixcrlf srcdir="pkg-temp" includes="*.config **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="lf" />
     1835        <izpack5 input="${basedir}/installer/install5.xml" output="${basedir}/i2pinstall_${full.version}_linux-only.jar" installerType="standard" basedir="${basedir}" />
    18031836    </target>
    18041837
     
    18461879    </target>
    18471880
     1881    <!-- IzPack 4 -->
    18481882    <target name="installer-windows" depends="clean, preppkg-windows-only, util-list-changes, izpack-patches, buildUtilityJar" >
    18491883        <fixcrlf srcdir="pkg-temp" includes="*.config *.bat *.cmd **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="crlf"/>
    18501884        <izpack input="${basedir}/installer/install.xml" output="${basedir}/install.jar" installerType="standard" basedir="${basedir}" />
     1885        <ant target="installerexe" />
     1886        <delete file="${basedir}/install.jar" />
     1887        <move file="${basedir}/i2pinstall.exe" tofile="${basedir}/i2pinstall_${full.version}_windows.exe" />
     1888    </target>
     1889
     1890    <!-- IzPack 5 -->
     1891    <target name="installer5-windows" depends="ensureIzpack5, clean, preppkg-windows-only, util-list-changes, buildUtilityJar" >
     1892        <fixcrlf srcdir="pkg-temp" includes="*.config *.bat *.cmd **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="crlf"/>
     1893        <izpack5 input="${basedir}/installer/install5.xml" output="${basedir}/install.jar" installerType="standard" basedir="${basedir}" />
    18511894        <ant target="installerexe" />
    18521895        <delete file="${basedir}/install.jar" />
  • core/java/src/freenet/support/CPUInformation/AMDInfoImpl.java

    rc8490a3 r2daeb6d  
    478478          }
    479479          break;
     480
     481        // http://lkml.iu.edu/hypermail/linux/kernel/1806.1/00730.html
     482        // untested
     483          case 24: {
     484            isK6Compatible = true;
     485            isK6_2_Compatible = true;
     486            isK6_3_Compatible = true;
     487            isAthlonCompatible = true;
     488            isAthlon64Compatible = true;
     489            // Pending testing of the bulldozer jbigi
     490            //isPiledriverCompatible = true;
     491            //isSteamrollerCompatible = true;
     492            //isExcavatorCompatible = true;
     493            //isBulldozerCompatible = true;
     494            modelString = "Hygon Dhyana model " + model;
     495          }
     496          break;
    480497        }
    481498        return modelString;
  • core/java/src/freenet/support/CPUInformation/CPUID.java

    rc8490a3 r2daeb6d  
    311311        if(!isX86)
    312312            throw new UnknownCPUException("Failed to read CPU information from the system. The CPUID instruction exists on x86 CPUs only.");
    313         if(id.equals("AuthenticAMD"))
     313        // http://lkml.iu.edu/hypermail/linux/kernel/1806.1/00730.html
     314        if(id.equals("AuthenticAMD") || id.equals("HygonGenuine"))
    314315            return new AMDInfoImpl();
    315316        if(id.equals("GenuineIntel"))
  • core/java/src/net/i2p/util/ByteCache.java

    rc8490a3 r2daeb6d  
    33import java.util.Arrays;
    44import java.util.Map;
    5 import java.util.Queue;
    65import java.util.concurrent.ConcurrentHashMap;
    7 import java.util.concurrent.LinkedBlockingQueue;
    86
    97import net.i2p.I2PAppContext;
     
    2321
    2422        1K      32      32K     tunnel TrivialPreprocessor
     23                *changed to 512 since we disabled resize()
    2524        1K      512     512K    tunnel FragmentHandler
    2625        1K      512     512K    I2NP TunnelDataMessage
    2726        1K      512     512K    tunnel FragmentedMessage
    2827
     28        1572    64      100K    UDP InboundMessageState
     29
    2930        1730    128     216K    streaming MessageOutputStream
    30 
    31         2K      64      128K    UDP IMS
    3231
    3332        4K      32      128K    I2PTunnelRunner
     
    5049 *
    5150 */
    52 public final class ByteCache {
     51public final class ByteCache extends TryCache<ByteArray> {
    5352
    5453    //private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(ByteCache.class);
     
    8483            cacheSize = MAX_CACHE / size;
    8584        Integer sz = Integer.valueOf(size);
    86         ByteCache cache = _caches.get(sz);
    87         if (cache == null) {
    88             cache = new ByteCache(cacheSize, size);
    89             _caches.put(sz, cache);
     85        ByteCache cache;
     86        synchronized(_caches) {
     87            cache = _caches.get(sz);
     88            if (cache == null) {
     89                cache = new ByteCache(cacheSize, size);
     90                _caches.put(sz, cache);
     91            }
    9092        }
    9193        cache.resize(cacheSize);
     
    104106    }
    105107
    106     /** list of available and available entries */
    107     private volatile Queue<ByteArray> _available;
    108     private int _maxCached;
    109108    private final int _entrySize;
    110     private volatile long _lastOverflow;
    111    
    112     /** do we actually want to cache? Warning - setting to false may NPE, this should be fixed or removed */
    113     private static final boolean _cache = true;
    114109   
    115110    /** how often do we cleanup the cache */
     
    118113    private static final long EXPIRE_PERIOD = 2*60*1000;
    119114   
     115    /** @since 0.9.36 */
     116    private static class ByteArrayFactory implements TryCache.ObjectFactory<ByteArray> {
     117        private final int sz;
     118
     119        ByteArrayFactory(int entrySize) {
     120            sz = entrySize;
     121        }
     122
     123        public ByteArray newInstance() {
     124            byte data[] = new byte[sz];
     125            ByteArray rv = new ByteArray(data);
     126            rv.setValid(0);
     127            return rv;
     128        }
     129    }
     130
    120131    private ByteCache(int maxCachedEntries, int entrySize) {
    121         if (_cache)
    122             _available = new LinkedBlockingQueue<ByteArray>(maxCachedEntries);
    123         _maxCached = maxCachedEntries;
     132        super(new ByteArrayFactory(entrySize), maxCachedEntries);
    124133        _entrySize = entrySize;
    125         _lastOverflow = -1;
    126         SimpleTimer2.getInstance().addPeriodicEvent(new Cleanup(), CLEANUP_FREQUENCY + (entrySize % 777));   //stagger
     134        int stagger = SystemVersion.isAndroid() ? 0 : (entrySize % 777);
     135        SimpleTimer2.getInstance().addPeriodicEvent(new Cleanup(), CLEANUP_FREQUENCY + stagger);
    127136        I2PAppContext.getGlobalContext().statManager().createRateStat("byteCache.memory." + entrySize, "Memory usage (B)", "Router", new long[] { 10*60*1000 });
    128137    }
    129138   
    130139    private void resize(int maxCachedEntries) {
    131         if (_maxCached >= maxCachedEntries) return;
    132         _maxCached = maxCachedEntries;
    133         // make a bigger one, move the cached items over
    134         Queue<ByteArray> newLBQ = new LinkedBlockingQueue<ByteArray>(maxCachedEntries);
    135         ByteArray ba;
    136         while ((ba = _available.poll()) != null)
    137             newLBQ.offer(ba);
    138         _available = newLBQ;
    139     }
    140    
    141     /**
    142      * Get the next available structure, either from the cache or a brand new one.
    143      * Returned ByteArray will have valid = 0 and offset = 0.
    144      * Returned ByteArray may or may not be zero, depends on whether
    145      * release(ba) or release(ba, false) was called.
    146      * Which is a problem, you should really specify shouldZero on acquire, not release.
    147      */
    148     public final ByteArray acquire() {
    149         if (_cache) {
    150             ByteArray rv = _available.poll();
    151             if (rv != null)
    152                 return rv;
    153         }
    154         _lastOverflow = System.currentTimeMillis();
    155         byte data[] = new byte[_entrySize];
    156         ByteArray rv = new ByteArray(data);
    157         rv.setValid(0);
    158         //rv.setOffset(0);
    159         return rv;
     140        // disabled since we're now extending TryCache
    160141    }
    161142   
     
    164145     *
    165146     */
     147    @Override
    166148    public final void release(ByteArray entry) {
    167149        release(entry, true);
     
    169151
    170152    public final void release(ByteArray entry, boolean shouldZero) {
    171         if (_cache) {
    172             if (entry == null || entry.getData() == null)
    173                 return;
    174             if (entry.getData().length != _entrySize) {
    175                 Log log = I2PAppContext.getGlobalContext().logManager().getLog(ByteCache.class);
    176                 if (log.shouldLog(Log.WARN))
    177                     log.warn("Bad size", new Exception("I did it"));
    178                 return;
    179             }
    180             entry.setValid(0);
    181             entry.setOffset(0);
    182            
    183             if (shouldZero)
    184                 Arrays.fill(entry.getData(), (byte)0x0);
    185             _available.offer(entry);
     153        if (entry == null || entry.getData() == null)
     154            return;
     155        if (entry.getData().length != _entrySize) {
     156            Log log = I2PAppContext.getGlobalContext().logManager().getLog(ByteCache.class);
     157            if (log.shouldLog(Log.WARN))
     158                log.warn("Bad size", new Exception("I did it"));
     159            return;
    186160        }
    187     }
    188    
    189     /**
    190      *  Clear everything (memory pressure)
    191      *  @since 0.7.14
    192      */
    193     private void clear() {
    194         _available.clear();
     161        entry.setValid(0);
     162        entry.setOffset(0);
     163         
     164        if (shouldZero)
     165            Arrays.fill(entry.getData(), (byte)0x0);
     166        super.release(entry);
    195167    }
    196168
    197169    private class Cleanup implements SimpleTimer.TimedEvent {
    198170        public void timeReached() {
    199             I2PAppContext.getGlobalContext().statManager().addRateData("byteCache.memory." + _entrySize, _entrySize * _available.size(), 0);
    200             if (System.currentTimeMillis() - _lastOverflow > EXPIRE_PERIOD) {
    201                 // we haven't exceeded the cache size in a few minutes, so lets
    202                 // shrink the cache
    203                     int toRemove = _available.size() / 2;
    204                     for (int i = 0; i < toRemove; i++)
    205                         _available.poll();
    206                     //if ( (toRemove > 0) && (_log.shouldLog(Log.DEBUG)) )
    207                     //    _log.debug("Removing " + toRemove + " cached entries of size " + _entrySize);
     171            int origsz;
     172            lock.lock();
     173            try {
     174                origsz = items.size();
     175                if (origsz > 1 && System.currentTimeMillis() - _lastUnderflow > EXPIRE_PERIOD) {
     176                    // we haven't exceeded the cache size in a few minutes, so lets
     177                    // shrink the cache
     178                    int toRemove = origsz / 2;
     179                    for (int i = 0; i < toRemove; i++) {
     180                        items.remove(items.size() - 1);
     181                    }
     182                }
     183            } finally {
     184                lock.unlock();
    208185            }
     186            I2PAppContext.getGlobalContext().statManager().addRateData("byteCache.memory." + _entrySize, _entrySize * origsz);
    209187        }
    210188
  • core/java/src/net/i2p/util/SimpleByteCache.java

    rc8490a3 r2daeb6d  
    11package net.i2p.util;
    22
    3 import java.util.Queue;
    4 import java.util.concurrent.ArrayBlockingQueue;
    53import java.util.concurrent.ConcurrentHashMap;
    6 import java.util.concurrent.LinkedBlockingQueue;
    74
    85/**
     
    1916
    2017    private static final int DEFAULT_SIZE = 64;
    21 
    22     /** up to this, use ABQ to minimize object churn and for performance; above this, use LBQ for two locks */
    23     private static final int MAX_FOR_ABQ = 64;
    2418
    2519    /**
     
    6155    }
    6256
    63     /** list of available and available entries */
    64     private Queue<byte[]> _available;
    65     private int _maxCached;
     57    private final TryCache<byte[]> _available;
    6658    private final int _entrySize;
    6759   
     60    /** @since 0.9.36 */
     61    private static class ByteArrayFactory implements TryCache.ObjectFactory<byte[]> {
     62        private final int sz;
     63
     64        ByteArrayFactory(int entrySize) {
     65            sz = entrySize;
     66        }
     67
     68        public byte[] newInstance() {
     69            return new byte[sz];
     70        }
     71    }
     72
    6873    private SimpleByteCache(int maxCachedEntries, int entrySize) {
    69         _maxCached = maxCachedEntries;
    70         _available = createQueue();
     74        _available = new TryCache(new ByteArrayFactory(entrySize), maxCachedEntries);
    7175        _entrySize = entrySize;
    7276    }
    7377   
    7478    private void resize(int maxCachedEntries) {
    75         if (_maxCached >= maxCachedEntries) return;
    76         _maxCached = maxCachedEntries;
    77         // make a bigger one, move the cached items over
    78         Queue<byte[]> newLBQ = createQueue();
    79         byte[] ba;
    80         while ((ba = _available.poll()) != null)
    81             newLBQ.offer(ba);
    82         _available = newLBQ;
     79        // _available is now final, and getInstance() is not used anywhere,
     80        // all call sites just use static acquire()
    8381    }
    8482   
    85     /**
    86      *  @return LBQ or ABQ
    87      *  @since 0.9.2
    88      */
    89     private Queue<byte[]> createQueue() {
    90         if (_entrySize <= MAX_FOR_ABQ)
    91             return new ArrayBlockingQueue<byte[]>(_maxCached);
    92         return new LinkedBlockingQueue<byte[]>(_maxCached);
    93     }
    94 
    9583    /**
    9684     * Get the next available array, either from the cache or a brand new one
     
    10088    }
    10189
    102     /**
     90     /**
    10391     * Get the next available array, either from the cache or a brand new one
    10492     */
    10593    private byte[] acquire() {
    106         byte[] rv = _available.poll();
    107         if (rv == null)
    108             rv = new byte[_entrySize];
    109         return rv;
     94        return _available.acquire();
    11095    }
    11196   
     
    127112        // should be safe without this
    128113        //Arrays.fill(entry, (byte) 0);
    129         _available.offer(entry);
     114        _available.release(entry);
    130115    }
    131116   
  • core/java/src/net/i2p/util/TryCache.java

    rc8490a3 r2daeb6d  
    1212 *
    1313 * @param <T>
     14 * @since 0.9.36
    1415 */
    1516public class TryCache<T> {
     
    2526   
    2627    private final ObjectFactory<T> factory;
    27     private final int capacity;
    28     private final List<T> items;
    29     private final Lock lock = new ReentrantLock();
     28    protected final int capacity;
     29    protected final List<T> items;
     30    protected final Lock lock = new ReentrantLock();
     31    protected long _lastUnderflow;
    3032   
    3133    /**
     
    4850                if (!items.isEmpty()) {
    4951                    rv = items.remove(items.size() - 1);
     52                } else {
     53                    _lastUnderflow = System.currentTimeMillis();
    5054                }
    5155            } finally {
  • history.txt

    rc8490a3 r2daeb6d  
     12018-07-10 zzz
     2 * Installer (ticket #1864):
     3   - Fix wrapper selection on Windows 10
     4   - Add support for IzPack 5
     5 * SSU: Sync/notify improvements (ticket #2260)
     6 * Util: Convert more caches to TryCache (ticket #2263)
     7
    182018-07-08 zzz
    29 * i2psnark: Add comment icon (ticket #2278)
  • installer/install.xml

    rc8490a3 r2daeb6d  
    103103    </resources>
    104104
     105    <dynamicvariables>
     106        <variable name="datamodel" value="${SYSTEM_sun_arch_data_model}"/>
     107    </dynamicvariables>
     108
     109    <conditions>
     110        <condition type="variable" id="is64bit">
     111            <name>datamodel</name>
     112            <value>64</value>
     113        </condition>
     114    </conditions>
     115
    105116    <panels>
    106117        <panel classname="HelloPanel"/>
     
    116127         Using the condition this way, the panel is shown on everything *but* Windows.
    117128         -->
    118     <panel classname="XInfoPanel" condition="!izpack.windowsinstall" />
    119     <panel classname="SimpleFinishPanel"/>
    120 </panels>
     129        <panel classname="XInfoPanel" condition="!izpack.windowsinstall" />
     130        <panel classname="SimpleFinishPanel"/>
     131    </panels>
    121132
    122133    <packs>
     
    136147            <parsable targetfile="$INSTALL_PATH/runplain.sh" type="shell"> <os family="unix" /> </parsable>
    137148            <parsable targetfile="$INSTALL_PATH/Start I2P Router.app/Contents/MacOS/i2prouter" type="shell" os="mac" />
    138 
    139             <conditions>
    140                 <condition type="variable" id="is64bit">
    141                     <name>SYSTEM_sun_arch_data_model</name>
    142                     <value>64</value>
    143                 </condition>
    144             </conditions>
    145149
    146150            <!-- postinstall stuff for windows -->
  • installer/resources/checklist.md

    rc8490a3 r2daeb6d  
    107107  - `history.txt`
    108108  - `installer/install.xml`
     109  - `installer/install5.xml`
    109110  - `core/java/src/net/i2p/CoreVersion.java`
    110111  - `router/java/src/net/i2p/router/RouterVersion.java`
  • installer/resources/postinstall.sh

    rc8490a3 r2daeb6d  
    105105chmod 755 ./eepget
    106106rm -rf ./icons ./lib/wrapper
    107 rm -f ./lib/*.dll /*.bat ./*.cmd ./*.exe ./utility.jar
     107rm -f ./lib/*.dll ./*.bat ./*.cmd ./*.exe ./utility.jar
    108108
    109109if [ ! `echo $HOST_OS  |grep osx` ]; then
  • router/java/src/com/southernstorm/noise/protocol/HandshakeState.java

    rc8490a3 r2daeb6d  
    884884
    885885        /**
    886          *  I2P for getting current hash for siphash calculation
    887          *  @return NOT a copy, do not modify
    888          */
    889         public byte[] getHash() {
    890                 return symmetric.getHandshakeHash();
    891         }
    892 
    893         /**
    894886         *  I2P debug
    895887         */
  • router/java/src/net/i2p/router/RouterVersion.java

    rc8490a3 r2daeb6d  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 7;
     21    public final static long BUILD = 10;
    2222
    2323    /** for example "-test" */
  • router/java/src/net/i2p/router/transport/ntcp/NTCP2Payload.java

    rc8490a3 r2daeb6d  
    344344     * Same as DataHelper.fromLong(src, offset, 8) but allows negative result
    345345     *
    346      * Package private for NTCP2Payload.
    347      *
    348346     * @throws ArrayIndexOutOfBoundsException
    349347     * @since 0.9.36
  • router/java/src/net/i2p/router/transport/ntcp/OutboundNTCP2State.java

    rc8490a3 r2daeb6d  
    443443        byte[] ask_master = doHMAC(ctx, tk, ASK);
    444444        byte[] tmp = new byte[32 + SIPHASH.length];
    445         byte[] hash = state.getHash();
     445        byte[] hash = state.getHandshakeHash();
    446446        System.arraycopy(hash, 0, tmp, 0, 32);
    447447        System.arraycopy(SIPHASH, 0, tmp, 32, SIPHASH.length);
  • router/java/src/net/i2p/router/transport/udp/InboundMessageFragments.java

    rc8490a3 r2daeb6d  
    261261        // races in OutboundMessageFragments.
    262262        if (newAck && from.getOutboundMessageCount() > 0)
    263             _outbound.add(from);
     263            _outbound.add(from, 0);
    264264
    265265        return rv;
  • router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java

    rc8490a3 r2daeb6d  
    5151     */
    5252    private Iterator<PeerState> _iterator;
    53 
    54     /**
    55      *  Avoid sync in add() if possible (not 100% reliable)
    56      */
    57     private volatile boolean _isWaiting;
    5853
    5954    private volatile boolean _alive;
     
    105100        _activePeers.clear();
    106101        synchronized (_activePeers) {
    107             _activePeers.notifyAll();
     102            _activePeers.notify();
    108103        }
    109104    }
     
    166161            OutboundMessageState state = new OutboundMessageState(_context, msg, peer);
    167162            peer.add(state);
    168             add(peer);
     163            add(peer, state.fragmentSize(0));
    169164        } catch (IllegalArgumentException iae) {
    170165            _transport.failed(msg, "Peer disconnected quickly");
     
    183178            throw new RuntimeException("null peer for " + state);
    184179        peer.add(state);
    185         add(peer);
     180        add(peer, state.fragmentSize(0));
    186181        //_context.statManager().addRateData("udp.outboundActiveCount", active, 0);
    187182    }
     
    196191            throw new RuntimeException("null peer");
    197192        int sz = states.size();
     193        int min = peer.fragmentSize();
    198194        for (int i = 0; i < sz; i++) {
    199             peer.add(states.get(i));
    200         }
    201         add(peer);
     195            OutboundMessageState state = states.get(i);
     196            peer.add(state);
     197            int fsz = state.fragmentSize(0);
     198            if (fsz < min)
     199                min = fsz;
     200        }
     201        add(peer, min);
    202202        //_context.statManager().addRateData("udp.outboundActiveCount", active, 0);
    203203    }
     
    212212     * the iterator is now... but these issues are the same as before concurrentification.
    213213     *
     214     * @param the minimum size we can send, or 0 to always notify
    214215     * @since 0.8.9
    215216     */
    216     public void add(PeerState peer) {
    217         boolean wasEmpty = _activePeers.isEmpty();
     217    public void add(PeerState peer, int size) {
    218218        boolean added = _activePeers.add(peer);
    219219        if (added) {
     
    230230        // Also note that the iterator in getNextVolley may have alreay passed us,
    231231        // or not reflect the addition.
    232         if (_isWaiting || wasEmpty) {
     232        if (added || size <= 0 || peer.getSendWindowBytesRemaining() >= size) {
    233233            synchronized (_activePeers) {
    234                 _activePeers.notifyAll();
     234                _activePeers.notify();
    235235            }
    236236        }
     
    322322                    // ... unless nextSendDelay says we have more ready now
    323323                    if (states == null && peersProcessed >= _activePeers.size() && nextSendDelay > 0) {
    324                         _isWaiting = true;
    325324                        peersProcessed = 0;
    326325                        // why? we do this in the loop one at a time
     
    342341                            }
    343342                        }
    344                         _isWaiting = false;
    345343                    //} else {
    346344                    //    if (_log.shouldLog(Log.DEBUG))
  • router/java/src/net/i2p/router/tunnel/TrivialPreprocessor.java

    rc8490a3 r2daeb6d  
    3535     * Used in BatchedPreprocessor; see add'l comments there
    3636     */
    37     protected static final ByteCache _dataCache = ByteCache.getInstance(32, PREPROCESSED_SIZE);
     37    protected static final ByteCache _dataCache = ByteCache.getInstance(512, PREPROCESSED_SIZE);
    3838
    3939    public TrivialPreprocessor(RouterContext ctx) {
Note: See TracChangeset for help on using the changeset viewer.