Go 外部排序-网络版
目录结果

main.go
package main import (
"NetworkSort/pipeline"
"fmt"
"os"
"bufio"
) func main() {
const filename = "large.in"
const n = 100000000
file, err := os.Create(filename)
if err != nil {
panic(err)
}
defer file.Close()
p := pipeline.RandomSource(n)
writer := bufio.NewWriter(file)
pipeline.WriterSink(writer, p)
writer.Flush() file, err = os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
p = pipeline.ReaderSource(bufio.NewReader(file), -1)
count := 0
for v := range p {
fmt.Println(v)
count ++
if count >= 100 {
break
}
}
}
sort.go
package main import (
"os"
"NetworkSort/pipeline"
"bufio"
"fmt"
"strconv"
) func main() {
p := createNetworkPipeline("small.in", 512, 4)
writeToFile(p, "small.out")
printFile("small.out")
} func printFile(filename string) {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
p := pipeline.ReaderSource(file, -1)
count := 0
for v:= range p {
fmt.Println(v)
count ++
if count >= 100 {
break
}
}
} func writeToFile(p <-chan int, filename string) {
file, err := os.Create(filename)
if err != nil {
panic(err)
}
defer file.Close()
writer := bufio.NewWriter(file)
defer writer.Flush()
pipeline.WriterSink(writer, p) } func createNetworkPipeline(filename string, fileSize, chunkCount int) <-chan int {
chunkSize := fileSize / chunkCount
pipeline.Init()
var sortAddr []string
for i := 0; i < chunkCount; i ++ {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
file.Seek(int64(i * chunkSize), 0)
source := pipeline.ReaderSource(bufio.NewReader(file), chunkSize)
addr := "127.0.0.1:" + strconv.Itoa(7000 + i)
fmt.Println("addr:", addr)
pipeline.NetworkSink(addr, pipeline.InMemorySort(source))
sortAddr = append(sortAddr, addr)
}
return nil
var sortResults []<-chan int
for _, addr := range sortAddr {
sortResults = append(sortResults, pipeline.NetworkSource(addr))
}
return pipeline.MergeN(sortResults ...)
}
nodes.go
package pipeline import (
"sort"
"io"
"encoding/binary"
"math/rand"
"time"
"fmt"
) var startTime time.Time func Init() {
startTime = time.Now()
} func ArraySource(a ...int) <-chan int {
out := make(chan int, 1024)
go func() {
for _, v := range a{
out <- v
}
close(out)
}()
return out
} func InMemorySort(in <-chan int) <-chan int {
out := make(chan int, 1024)
go func() {
// Read into memory
var a []int
for v := range in {
a = append(a, v)
}
fmt.Println("Read done:", time.Now().Sub(startTime))
// Sort
sort.Ints(a)
fmt.Println("InMemSort done:", time.Now().Sub(startTime)) // Output
for _, v := range a {
out <- v
}
close(out)
}()
return out
} func Merge(in1, in2 <-chan int) <-chan int {
out := make(chan int, 1024)
go func() {
v1, ok1 := <- in1
v2, ok2 := <- in2
for ok1 || ok2 {
if !ok2 || (ok1 && v1 <= v2) {
out <- v1
v1, ok1 = <-in1
} else {
out <- v2
v2, ok2 = <-in2
}
}
close(out)
fmt.Println("Merge done:", time.Now().Sub(startTime)) }()
return out
} func ReaderSource(reader io.Reader, chunkSize int) <-chan int {
out := make(chan int, 1024)
go func() {
buffer := make([]byte, 8)
bytesRead := 0
for {
n, err := reader.Read(buffer)
bytesRead += n
if n > 0 {
v := int(binary.BigEndian.Uint64(buffer))
out <- v
}
if err != nil || (chunkSize != -1 && bytesRead >= chunkSize){
break
}
}
close(out)
}()
return out
} func WriterSink(writer io.Writer, in <-chan int) {
for v := range in {
buffer := make([]byte, 8)
binary.BigEndian.PutUint64(buffer, uint64(v))
writer.Write(buffer)
}
} func RandomSource(count int) <-chan int {
out := make(chan int)
go func() {
for i:=0; i<count; i++ {
out <- rand.Int()
}
close(out)
}()
return out
} func MergeN(inputs ...<-chan int) <-chan int{
if len(inputs) == 1{
return inputs[0]
}
m := len(inputs) / 2 // merge inputs[0...m] and inputs[m...end]
return Merge(MergeN(inputs[:m] ...), MergeN(inputs[m:] ...))
}
network_nodes.go
package pipeline import (
"net"
"bufio"
) func NetworkSink(addr string, in <-chan int){
listener, err :=net.Listen("tcp", addr)
if err != nil {
panic(err)
}
go func() {
defer listener.Close()
conn, err := listener.Accept()
if err != nil {
panic(err)
}
defer conn.Close()
writer := bufio.NewWriter(conn)
defer writer.Flush()
WriterSink(writer, in)
}()
} func NetworkSource(addr string) <-chan int {
out := make(chan int)
go func() {
conn, err := net.Dial("tcp", addr)
if err != nil {
panic(err)
}
r := ReaderSource(bufio.NewReader(conn), -1)
for v := range r {
out <- v
}
close(out)
}()
return out
}
Go 外部排序-网络版的更多相关文章
- sphinx 源码阅读之分词,压缩索引,倒排——单词对应的文档ID列表本质和lucene无异 也是外部排序再压缩 解压的时候需要全部扫描doc_ids列表偏移量相加获得最终的文档ID
转自:http://github.tiankonguse.com/blog/2014/12/03/sphinx-token-inverted-sort.html 外部排序 现在我们的背景是有16个已经 ...
- 外部排序&多路归并排序
外部排序: 一.定义问题 外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序 整个文件的目的.外部排序最常 ...
- 大数据排序算法:外部排序,bitmap算法;大数据去重算法:hash算法,bitmap算法
外部排序算法相关:主要用到归并排序,堆排序,桶排序,重点是先分成不同的块,然后从每个块中找到最小值写入磁盘,分析过程可以看看http://blog.csdn.net/jeason29/article/ ...
- Go实现分布式外部排序
Go实现分布式外部排序 项目路径: https://github.com/Draymonders/go_external_sort 默认读入文件: small.in 默认输出文件:small.out ...
- Multithreading C++ Out of Core Sotring for Massive Data|多线程C++的大规模数据外部排序
先说一下,这个其实是我为实现PantaRay或者是类似Dreamworks的Out of Core点云GI的技术储备,为大规模点云光线跟踪所准备的第一步.在实际的应用中,int类型会被64bit的ui ...
- 常用算法——排序(一)
排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困难.同样,存储在计算机中的数据的次序,对于处理这些数据的算法的 ...
- 八大排序算法Java
目录(?)[-] 概述 插入排序直接插入排序Straight Insertion Sort 插入排序希尔排序Shells Sort 选择排序简单选择排序Simple Selection Sort 选择 ...
- 面试题目——《CC150》排序与查找
面试题11.1:给定两个排序后的数组A和B,其中A的末端有足够的缓冲空间容纳B.编写一个方法,将B合并入A并排序. package cc150.sort_search; public class Me ...
- [Data Structure & Algorithm] 八大排序算法
排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序 ...
随机推荐
- SSH框架解析
当也许能够说是与你的初恋.妙龄的少女開始有些羞涩.是时候说说SHH的故事了.SHH是指Spring+Struts+Hibernate.还记研究生复试那天的面试,老师说了一句话Spring的核心是控制反 ...
- 框架应用:Mybatis - 开发详述
ORM框架 在实际开发中,工程中本质的任务是从数据库中获取数据,然后对数据进行操作,又或者写入数据.开发时语言是大多是面向对象的工程语言,这个时候就必须进行工程语言和数据库连接语言的转换,也就是所谓的 ...
- ASP.NET:把ashx写到类库里并在页面上调用的具体方法
在类库中建Http Handler的操作很简单,就是添加一个普通的类,然后把之前ashx里的代码几乎一模一样贴到这个类中.但要注意命名空间和类名,因为之后我们会用 到.样例Handler: names ...
- Nginx模块系列之auth_basic模块
1.1 介绍 ngx_http_auth_basic_module模块实现让访问着,只有输入正确的用户密码才允许访问web内容.web上的一些内容不想被其他人知道,但是又想让部分人看到.nginx的h ...
- iOS学习笔记(一)——ios搭建开发环境
好久就想试水IOS开发了,由于开发环境限制,一直局限于理论和虚拟机,近来入手了MacBook Pro,也来尝尝鲜,笔者也是现学现总结,如果有不足,请指正. IOS开发必备MAC OS X 另加一部iP ...
- Android UI开发第二十八篇——Fragment中使用左右滑动菜单
Fragment实现了Android UI的分片管理,尤其在平板开发中,好处多多.这一篇将借助Android UI开发第二十六篇——Fragment间的通信. Android UI开发第二十七篇——实 ...
- CSU-1632 Repeated Substrings[后缀数组求重复出现的子串数目]
评测地址:https://cn.vjudge.net/problem/CSU-1632 Description 求字符串中所有出现至少2次的子串个数 Input 第一行为一整数T(T<=10)表 ...
- 《从零开始学Swift》学习笔记(Day 39)——构造函数重载
原创文章,欢迎转载.转载请注明:关东升的博客 构造函数作为一种特殊方法,也可以重载. Swift中构造函数可以多个,他们参数列表和返回值可以不同,这些构造函数构成重载. 示例代码如下: class ...
- 前台传递给后台的JSON字符串中的引号 “” 在JAVA后台被转义为 "
前台传递给后台的JSON字符串中的引号 "" 在JAVA后台被转义为 " 1.问题: 前台数据,JSON字符串带有引号 "" ,数据被传递到后台 ...
- maven实现项目热部署
1.Tomcat的配置 我们需要实现热部署,自然就需要通过maven操作tomcat,所以就需要maven取得操作tomcat的权限,现在这一步就是配置tomcat的可操作权限. 在tomcat的安装 ...