Monday, November 08, 2010 at 12:05 AM.

system.verbs.builtins.radio.weblog.getNextPostAfterDate

on getNextPostAfterDate (adrBlog=radio.weblog.init (), d, adrAdrPost, catname=nil) {
	<<Get the post after the specified date.
		<<Changes:
			<<11/29/01; 5:28:29 PM by JES
				<<Only include category posts in the binary search, if the post exsts.
			<<11/28/01; 10:54:20 AM by JES
				<<Fixed two errors, one when the category has no posts, and one when the category has only a single post.
			<<11/28/01; 12:20:09 AM by JES
				<<Do a binary search on posts for categories. There was already a catname parameter for this, but it was never referenced.
			<<11/16/01; 5:55:28 PM by JES
				<<New optional parameter, catname.
			<<2/23/01; 9:51:32 PM by JES
				<<Fixed an error if there were no posts in the weblog.
			<<2/22/01; 3:52:15 PM by PBS
				<<Created.
	local (adrPosts = @adrBlog^.posts);
	local (sizeTable = sizeOf (adrPosts^));
	
	local (flFound = false, adrPost);
	if catname == nil {
		if sizeOf (adrPosts^) != 0 { //02/23/2001 JES: don't cause an error if there are no posts
			if adrPosts^ [1].when >= d { //optimization: check first post
				adrPost = @adrPosts^ [1];
				flFound = true};
			if adrPosts^ [sizeTable].when < d { //optimization: check last post
				return (false)};
			local (ix = sizeTable / 2, lastIx = 0);
			local (currentLess = 0, currentGreater = 0);
			if ix > 0 {
				loop {
					if ix == sizeTable { //no posts after the date
						return (false)};
					if ix == 1 and adrPosts^ [ix].when >= d { //the first post is after the date
						adrPost = @adrPosts^ [ix];
						flFound = true;
						break};
					if adrPosts^ [ix].when < d and adrPosts^ [ix + 1].when >= d { //found it?
						adrPost = @adrPosts^ [ix + 1];
						flFound = true;
						break};
					if adrPosts^ [ix + 1].when < d {
						currentLess = ix + 1;
						ix = ix + ((sizeTable - ix) / 2);
						if ix == lastIx {
							ix++};
						if (currentGreater != 0) and (ix > currentGreater) {
							ix = currentGreater}}
					else {
						if adrPosts^ [ix + 1].when > d {
							currentGreater = ix + 1;
							ix = ix / 2;
							if ix == lastIx {
								ix--};
							if (currentLess != 0) and (ix < currentLess) {
								ix = currentLess}}};
					lastIx = ix}}}}
	else { //categories have a different search algorithm
		local (adrcat = @adrBlog^.categories.[catname]);
		local (catPostsTable);
		bundle { //build a sorted catPostsTable
			new (tableType, @catPostsTable);
			local (postnum);
			for postnum in adrcat^.storyList {
				local (postname = string.padWithZeros (postnum, 8));
				if defined (adrblog^.posts.[postname]) {
					catPostsTable.[postname] = postname}}};
		local (ctPosts = sizeOf (catPostsTable));
		if ctPosts > 0 {
			on getPost (n) {
				return (@adrPosts^.[string.padWithZeros (n, 8)])};
			if getPost (catPostsTable [1])^.when >= d { //optimization: check first post
				adrPost = getPost (catPostsTable [1]);
				flFound = true};
			if getPost (catPostsTable [ctPosts])^.when < d { //optimization: check last post
				return (false)};
			local (ix = ctPosts / 2, lastIx = 0);
			if ix > 0 {
				local (currentLess = 0, currentGreater = 0);
				loop {
					if ix == ctPosts { //no posts after the date
						return (false)};
					if ix == 1 and getPost (catPostsTable [ix])^.when >= d { //the first post is after the date
						adrPost = getPost (catPostsTable [ix]);
						flFound = true;
						break};
					if getPost (catPostsTable [ix])^.when < d and getPost (catPostsTable [ix + 1])^.when >= d { //found it?
						adrPost = getPost (catPostsTable [ix + 1]);
						flFound = true;
						break};
					if getPost (catPostsTable [ix + 1])^.when < d {
						currentLess = ix + 1;
						ix = ix + ((ctPosts - ix) / 2);
						if ix == lastIx {
							ix++};
						if (currentGreater != 0) and (ix > currentGreater) {
							ix = currentGreater}}
					else {
						if getPost (catPostsTable [ix + 1])^.when > d {
							currentGreater = ix + 1;
							ix = ix / 2;
							if ix == lastIx {
								ix--};
							if (currentLess != 0) and (ix < currentLess) {
								ix = currentLess}}};
					lastIx = ix}}}};
	if flFound {
		adrAdrPost^ = adrPost};
	return (flFound)}
<<bundle //test code
	<<local (adrPost)
	<<if getNextPostAfterDate (d:date ("1/26/2001"), adrAdrPost:@adrPost)
		<<edit (adrPost)
<<bundle //more test code
	<<local (adrPost, d = date ("11/01/2001"))
	<<if getNextPostAfterDate (d:d, adrAdrPost:@adrPost, catname:"Jake's other test channel")
		<<edit (adrPost)
	<<else {dialog.notify ("No post after " + d)}



This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.