FileSort

/*************************************************************************
    > File Name: FileSort.h
    > Author: wangzhicheng
    > Mail: 2363702560@qq.com 
    > Created Time: Sat 31 Dec 2016 09:30:39 AM AWST
	> Brief:sort strings in the file
 ************************************************************************/
#ifndef FILE_SORT_H
#define FILE_SORT_H
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <omp.h>
#include <iostream>
#include <fstream>
#include <thread>
#include <algorithm>
#include <functional>  
namespace filesort
{
#define ASC 0
#define DESC 1
using namespace std;
class FileSort 
{
	public:
	/*
	 * @brief sort a file 
	 * @input_path the input file full path
	 * @sortype sort type 
	 * @return true if sort is ok
	 * */
	static bool sort(const char *input_path, const char *output_path, int sortype = ASC, int threadnum = 2);
	private:
	/*
	 * @brief use the stl sort
	 * */
	inline static void threadsort(vector<string>&input, int sortype)
	{
		switch(sortype)
		{
			case ASC:	// ASC
				std::sort(input.begin(), input.end());
				break;
			case DESC:	// DESC
				std::sort(input.rbegin(), input.rend());
				// lamba
				/*
				std::sort(input.begin(), input.end(), [](const string &str0, const string &str1)
						{
							return str0 > str1;
						});
						*/
				break;
		}
	}
};
}
#endif

/*************************************************************************
    > File Name: FileSort.cpp
    > Author: wangzhicheng
    > Mail: 2363702560@qq.com 
    > Created Time: Sat 31 Dec 2016 09:30:39 AM AWST
	> Brief: sort strings in a file
 ************************************************************************/
#include "FileSort.h"
namespace filesort
{
bool FileSort::sort(const char *input_path, const char *output_path, int sortype, int threadnum)
{
	// safe check entry arguments
	int MaxThreadNum = omp_get_num_procs() << 1;
	if(threadnum <= 0) threadnum = 1;
	if(threadnum >= MaxThreadNum) threadnum = MaxThreadNum;
	// open the input file
	ifstream is(input_path);
	if(!is)
	{
		cerr << input_path << " open failed...!" << endl;
		return false;
	}
	// import the string in the input file to various segments
	typedef vector<string> stringset;
	vector<stringset>segments;
	segments.resize(threadnum);		// every thead is responsible for every segment
	int index = 0;
	string line;
	while(getline(is, line))
	{
		segments[index].emplace_back(line);
		index = (index + 1) % threadnum;
	}
	is.close();
	// start theads to sort
	vector<thread>sortthreads;
	int i;
	for(i = 0;i < threadnum;i++)
	{
		stringset &strings = segments[i];
		sortthreads.push_back(thread(FileSort::threadsort, ref(strings), sortype));
	}
	for(auto &th:sortthreads)
	{
		th.join();
	}
	// open the output file
	ofstream os(output_path, ios::trunc);
	if(!os)
	{
		cerr << input_path << " open failed...!" << endl;
		return false;
	}
	// merge the vector to sort
	// init the heap
	vector<pair<string, int> >outstrings;	// first -- key second -- position
	for(i = 0;i < threadnum;i++)
	{
		stringset &strings = segments[i];
		if(!strings.empty())
		{
			outstrings.emplace_back(pair<string, int>(strings.front(), i));
			strings.erase(strings.begin());
		}
	}
	index = 0;
	switch(sortype)
	{
	case ASC:
		make_heap(outstrings.begin(), outstrings.end(), [](const pair<string, int>&p0, const pair<string, int>&p1)
				{
					return p0.first > p1.first;
				});
		break;
	case DESC:
		make_heap(outstrings.begin(), outstrings.end(), [](const pair<string, int>&p0, const pair<string, int>&p1)
				{
					return p0.first < p1.first;
				});
		break;
	}
	while(!outstrings.empty())
	{
		pop_heap(outstrings.begin(), outstrings.end());
		string &key = outstrings.back().first;
		int pos = outstrings.back().second;
		os << key << endl;
		outstrings.pop_back();
		stringset &strings = segments[pos];
		if(!strings.empty())
		{
			outstrings.emplace_back(pair<string, int>(strings.front(), pos));
			strings.erase(strings.begin());
		}
		switch(sortype)
		{
		case ASC:
			make_heap(outstrings.begin(), outstrings.end(), [](const pair<string, int>&p0, const pair<string, int>&p1)
					{
						return p0.first > p1.first;
					});
			break;
		case DESC:
			make_heap(outstrings.begin(), outstrings.end(), [](const pair<string, int>&p0, const pair<string, int>&p1)
					{
						return p0.first < p1.first;
					});
			break;
		}
	}
	os.close();
}
}

/*************************************************************************
    > File Name: main.cpp
    > Author: wangzhicheng
    > Mail: 2363702560@qq.com 
    > Created Time: Sat 31 Dec 2016 09:44:59 AM AWST
 ************************************************************************/

#include "FileSort.h"
#include <iterator>
#include <time.h>
using namespace filesort;
int main()
{
	// generate testing data
	static const int N = 10;
	static const int MAX = 100;
	int i, j;
	ofstream test_input("./input_data", ios::trunc);
	if(!test_input)
	{
		cerr << "input file generate failed...!" << endl;
		return 1;
	}
	char buf[64];
	srand(time(0));
	for(i = 0;i < MAX;i++)
	{
		for(j = 0;j < N;j++)
		{
			sprintf(buf + j, "%d", rand() % N);
		}
		test_input << buf << endl; 
	}
	test_input.close();
	// sort
	FileSort::sort("./input_data", "./output_data", DESC);

	return 0;
}

CC = g++
DBG = 

ifndef  DEBUG_SET
	DEBUG_SET=  -std=c++11 -g -pthread
endif

IFLAGS =-I .\

INDEX_ROOT=..
LIBS =	-L .\
		-lpthread\
		-lgomp\

LINK = 


TARGET=MergeSort
all:$(TARGET)

OBJS=FileSort.o\
	 main.o\

$(TARGET):$(OBJS)
	$(CC) -fPIC -o ./$(TARGET) $(OBJS) $(LIBS) $(LINK)
	
.cpp.o:
	$(CC) $(DBG) $(DEBUG_SET) $(IFLAGS) -fPIC -c $<
	
clean:
	rm *.o -fr
	rm -f MergeSort

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 的filesort 是一个操作,它在查询中用于处理 ORDER BY 子句或者 GROUP BY 子句。 当MySQL需要按特定字段进行排序或者分组时,它必须按照指定的条件来检索数据,并在内存或磁盘上对结果进行排序。这个过程称为filesort。 在进行filesort时,MySQL会将要排序的数据从磁盘加载到内存中去,并使用一种类似快速排序算法的技术对数据进行排序。如果数据量太大无法完全加载到内存中,MySQL可能会使用临时文件进行排序。 filesort的性能取决于多种因素,包括数据量、可用内存和硬盘性能。如果数据量较小且内存足够,排序操作可以在内存中完成,反之则需要使用临时文件进行辅助排序。 为了优化filesort操作,可以考虑以下几点: 1. 确保查询中的 ORDER BY 或 GROUP BY 子句的字段有适当的索引。索引可以帮助MySQL更快地找到和排序数据。 2. 提高系统的可用内存大小,这样更多的数据可以在内存中进行排序,减少磁盘I/O操作。 3. 根据业务需求,避免不必要的排序操作,比如可以在应用程序中进行排序,而不是完全依赖于数据库。 4. 如果filesort仍然是性能瓶颈,可以考虑分区或者分片等技术来减少排序的数据量。 总之,MySQL中的filesort操作是为了处理排序和分组的需求,通过将数据加载到内存中并排序,以获取更高的查询效率。针对filesort的优化可以提高查询性能,使得排序操作更快、更高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值