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] 八大排序算法
排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序 ...
随机推荐
- oracle 启动模式
转载自:http://blog.csdn.net/nsj820/article/details/6573525 <一>.ORACLE数据库启动模式 1.启动SQL*PLUS不与数据库连接 ...
- Oracle 11R2 linux上新建实例
Step1. root用户远程登陆到linux主机上.执行下面的命令切换到oracle用户,使对应的环境变量配置文件生效. # su oracle# source ~/.bash_profile St ...
- 微信小程序 模块化
模块化也就是将一些通用的东西抽出来放到一个文件中,通过module.exports去暴露接口.我们在最初新建项目时就有个util.js文件就是被模块化处理时间的 /** * 处理具体业务逻辑 */ f ...
- Zookeeper权限管理与Quota管理
Zookeeper的ACL机制和Quota机制网上资料较少,这里做一个总结,以供大家参考. 1 Zookeeper ACL ZooKeeper的权限管理亦即ACL控制功能通过Server.Client ...
- iOS --发送手机验证码收不到手机验证码
方法一:使用受信任设备上显示的验证码. 如果您的受信任设备是iOS 9 及以上系统时,则验证码将自动显示在受信任设备上.此时你信任的设备上会弹出你在某地登录ID位置的小地图,有一个选择允许与不允许登录 ...
- Android OpenCV集成摄像头图片动态识别车牌号
最近两天开发一个使用OpenCV集成的一个识别车牌号的项目,困难重重,总结一下相关经验,以及开发注意事项: 一.开发环境: Android Studio 个人版本 3.1.4 NDK下载:14b CM ...
- Android开发:《Gradle Recipes for Android》阅读笔记(翻译)2.1——设置项目参数
问题: 开发的时候经常需要向项目中添加一些额外的参数或者硬编码的值. 解决方案: 使用ext块设置公用的值.如果需要从build文件中移除这些值,可以将参数放到gradle.properties文件中 ...
- jwPlayer读取本地视频及相关配置(Tomcat配置虚拟目录)
最近做项目,发现好多知识点都是以前做过的或用过的,但最后要用到的时候,要么就记不牢了,要么就还是得重新整理一遍,所以以后有用的东东,尽量整理一下或Market下了. 项目要求:读取服务器多个视频到本地 ...
- 练习: 省市联动(Ajax)
// 示例一: china.xml (位于 src 目录下) <?xml version="1.0" encoding="utf-8"?> < ...
- 2014-08-28——PC端几款主流浏览器的内核
Trident(IE浏览器) Mozilla(Gecko)(熟悉的有Firefox,Flock等浏览器) WebKit(熟悉的有Safari.Chrome等浏览器) Opera(presto)(Ope ...