View Issue Details

IDProjectCategoryView StatusLast Update
1529RackTablesIPv4/IPv6/SLBpublic2015-10-13 12:25
ReporterVeratil Assigned Toandriyanov  
PrioritynoneSeveritytrivialReproducibilityalways
Status closedResolutionfixed 
Product Version0.20.10 
Fixed in Version0.20.11 
Summary1529: IPv4 pagination long load times and not user friendly
DescriptionWhen browsing a large address space (say a /8) it can take 5-10 seconds to load completely. Also, when viewing an IP space with multiple pages, it's hard to know which page will be the one you want at quick glance.
Steps To ReproduceCreate an IP space which spans multiple pages (such as /8, /12, or /16).
Additional InformationAn instance where this is seen: we have servers connected to a 10.0.0.0/8 private network with no need to subnet it out (sparse IPs). Their private address is their public with the first octet changed to 10 (e.g. 1.2.3.4 -> 10.2.3.4). With 65536 pages it takes around 5-10 seconds to load and the pagination takes up the vast majority of the page.
TagsNo tags attached.

Activities

Veratil

Veratil

2015-10-10 22:48

reporter   ~0002995

I wrote a simple pagination function that will only show up if you view a /19 or larger capacity subnet (with default IPV4_ADDRS_PER_PAGE). When pagination happens is customizable by the $paginationat variable (compared to $numpages), along with how many pages to show before/after with the $prepostpagecount variable.

This has drastically improved my page load times when there are numerous pages.

Another addition is I've added a title to the link to show the start IP of the page when hovering over the link.
Veratil

Veratil

2015-10-10 22:49

reporter  

interface.php.diff (3,473 bytes)   
--- interface.php.orig	2015-10-09 20:01:10.243356231 -0500
+++ interface.php	2015-10-10 15:36:28.102922378 -0500
@@ -2853,6 +2853,69 @@ function renderIPNetworkAddresses ($rang
 	}
 }
 
+function renderIPv4NetworkPageLink ($rangeid, $page, $title)
+{
+	global $pageno, $tabno;
+	return "<a href='".makeHref (array ('page' => $pageno, 'tab' => $tabno, 'id' => $rangeid, 'pg' => $page)) . "' title='".$title."'>".$page."</a> ";
+}
+
+function renderIPv4NetworkPagination ($range, $page, $numpages)
+{
+	$rendered_pager = '';
+	$startip = ip4_bin2int ($range['ip_bin']);
+	$endip = ip4_bin2int (ip_last ($range));
+	$rangeid = $range['id'];
+	// Should make this configurable perhaps
+	// How many pages before/after current page to show
+	$prepostpagecount = 8;
+	// Minimum pages where pagination does not happen
+	$paginationat = 16; // 16 pages is a /20, 32 is a /19
+	$maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
+	if ($numpages <= $paginationat)
+	{
+		// create original pagination
+		for ($i = 0; $i < $numpages; $i++)
+			if ($i == $page)
+				$rendered_pager .= "<b>".$i."</b> ";
+			else
+				$rendered_pager .= renderIPv4NetworkPageLink($rangeid, $i, ip4_format(ip4_int2bin($startip + $i * $maxperpage)));
+	}
+	else // number of pages > page range, create ranged pagination
+	{
+		// page is within first subset
+		if ($page - $prepostpagecount <= 1)
+		{
+			for ($i = 0; $i < $page; $i++)
+				$rendered_pager .= renderIPv4NetworkPageLink($rangeid, $i, ip4_format(ip4_int2bin($startip + $i * $maxperpage)));
+		}
+		// render 0 ... [page - prepostpagecount] [page - prepostpagecount + 1] ... [page - 1]
+		else
+		{
+			$rendered_pager .= renderIPv4NetworkPageLink($rangeid, 0, ip4_format(ip4_int2bin($startip)));
+			$rendered_pager .= "... ";
+			for ($i = $page - $prepostpagecount; $i < $page; $i++)
+				$rendered_pager .= renderIPv4NetworkPageLink($rangeid, $i, ip4_format(ip4_int2bin($startip + $i * $maxperpage)));
+		}
+		// render current page
+		$rendered_pager .= "<b>".$page."</b> ";
+		// page is within last subset
+		if ($page + $prepostpagecount >= $numpages-2)
+		{
+			for ($i = $page+1; $i < $numpages; $i++)
+				$rendered_pager .= renderIPv4NetworkPageLink($rangeid, $i, ip4_format(ip4_int2bin($startip + $i * $maxperpage)));
+		}
+		// render [page + 1] [page + 2] ... [page + postpagecount] ... [end page]
+		else
+		{
+			for ($i = $page+1; $i <= $page+$prepostpagecount; $i++)
+				$rendered_pager .= renderIPv4NetworkPageLink($rangeid, $i, ip4_format(ip4_int2bin($startip + $i * $maxperpage)));
+			$rendered_pager .= "... ";
+			$rendered_pager .= renderIPv4NetworkPageLink($rangeid, ($numpages-1), ip4_format(ip4_int2bin($endip)));
+		}
+	}
+	return $rendered_pager;
+}
+
 function renderIPv4NetworkAddresses ($range)
 {
 	global $pageno, $tabno, $aac_left;
@@ -2876,11 +2939,7 @@ function renderIPv4NetworkAddresses ($ra
 		if ($numpages = ceil ($address_count / $maxperpage))
 		{
 			echo '<h3>' . ip4_format (ip4_int2bin ($startip)) . ' ~ ' . ip4_format (ip4_int2bin ($endip)) . '</h3>';
-			for ($i = 0; $i < $numpages; $i++)
-				if ($i == $page)
-					$rendered_pager .= "<b>$i</b> ";
-				else
-					$rendered_pager .= "<a href='".makeHref (array ('page' => $pageno, 'tab' => $tabno, 'id' => $range['id'], 'pg' => $i)) . "'>$i</a> ";
+			$rendered_pager = renderIPv4NetworkPagination ($range, $page, $numpages);
 		}
 		$startip = $startip + $page * $maxperpage;
 		$endip = min ($startip + $maxperpage - 1, $endip);
interface.php.diff (3,473 bytes)   
andriyanov

andriyanov

2015-10-12 13:55

reporter   ~0002997

Thank you for this work, it looks OK to me.
Could you please create a pull request on github?
Veratil

Veratil

2015-10-12 17:08

reporter   ~0002999

I actually didn't clone from github. I just edited manually.
andriyanov

andriyanov

2015-10-12 18:01

reporter   ~0003001

It would be much better if I commit your change using your Author string and timestamps. If github is not convenient, please send a patch using git format-patch tool.
Veratil

Veratil

2015-10-12 18:47

reporter   ~0003003

Created pull request https://github.com/RackTables/racktables/pull/138
andriyanov

andriyanov

2015-10-13 12:25

reporter   ~0003005

Merged, thank you!.

Issue History

Date Modified Username Field Change
2015-10-10 04:10 Veratil New Issue
2015-10-10 04:10 Veratil Status new => assigned
2015-10-10 04:10 Veratil Assigned To => andriyanov
2015-10-10 22:48 Veratil Note Added: 0002995
2015-10-10 22:49 Veratil File Added: interface.php.diff
2015-10-12 13:55 andriyanov Note Added: 0002997
2015-10-12 17:08 Veratil Note Added: 0002999
2015-10-12 18:01 andriyanov Note Added: 0003001
2015-10-12 18:47 Veratil Note Added: 0003003
2015-10-13 12:25 andriyanov Note Added: 0003005
2015-10-13 12:25 andriyanov Status assigned => closed
2015-10-13 12:25 andriyanov Resolution open => fixed
2015-10-13 12:25 andriyanov Fixed in Version => 0.20.11